diff --git a/.eslintignore b/.eslintignore index e8b8c3f297709a..8ab4750abd1685 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,8 +4,7 @@ test/addons/??_* test/fixtures test/message/esm_display_syntax_error.mjs tools/icu -tools/lint-md.mjs -tools/node-lint-md-cli-rollup/dist +tools/lint-md/lint-md.mjs benchmark/tmp doc/**/*.js !.eslintrc.js diff --git a/.github/label-pr-config.yml b/.github/label-pr-config.yml index 6e1bccd478991f..c7a66707c63fb7 100644 --- a/.github/label-pr-config.yml +++ b/.github/label-pr-config.yml @@ -103,9 +103,9 @@ subSystemLabels: /^lib\/internal\/quic\/*/: quic, dont-land-on-v14.x, dont-land-on-v12.x # All other lib/ files map directly - /^lib\/_(\w+)_\w+\.js?$/: $1 # e.g. _(stream)_wrap - /^lib(\/internal)?\/(\w+)\.js?$/: $2 # other .js files - /^lib\/internal\/(\w+)(?:\/|$)/: $1 # internal subfolders + /^lib\/_(\w+)_\w+\.js?$/: $1 # e.g. _(stream)_wrap + /^lib(\/internal)?\/(\w+)\.js?$/: $2 # Other .js files + /^lib\/internal\/(\w+)(?:\/|$)/: $1 # internal subfolders exlusiveLabels: # more specific tests @@ -125,26 +125,26 @@ exlusiveLabels: /^test\//: test - # specific map for webcrypto.md as it should be labeled 'crypto' + # Specific map for webcrypto.md as it should be labeled 'crypto' /^doc\/api\/webcrypto.md$/: doc, crypto - # specific map for modules.md as it should be labeled 'module' not 'modules' + # Specific map for modules.md as it should be labeled 'module' not 'modules' /^doc\/api\/modules.md$/: doc, module - # node-api is treated separately since it is not a JS core module but is still - # considered a subsystem of sorts + # node-api is treated separately since it is not a JS core module but is still + # considered a subsystem of sorts /^doc\/api\/n-api.md$/: doc, node-api - # quic + # quic /^doc\/api\/quic.md$/: doc, quic, dont-land-on-v14.x, dont-land-on-v12.x - # add worker label to PRs that affect doc/api/worker_threads.md + # Add worker label to PRs that affect doc/api/worker_threads.md /^doc\/api\/worker_threads.md$/: doc, worker - # automatically tag JS subsystem-specific API doc changes + # Automatically tag JS subsystem-specific API doc changes /^doc\/api\/(\w+)\.md$/: doc, $1 - # add deprecations label to PRs that affect doc/api/deprecations.md + # Add deprecations label to PRs that affect doc/api/deprecations.md /^doc\/api\/deprecations.md$/: doc, deprecations /^doc\/changelogs\//: release /^doc\//: doc - # more specific benchmarks + # More specific benchmarks /^benchmark\/buffers\//: benchmark, buffer /^benchmark\/(?:arrays|es)\//: benchmark, v8 engine /^benchmark\/_http/: benchmark, http diff --git a/.github/workflows/authors.yml b/.github/workflows/authors.yml index 8171df166ab353..04ca2772c0cf11 100644 --- a/.github/workflows/authors.yml +++ b/.github/workflows/authors.yml @@ -8,19 +8,20 @@ on: jobs: authors_update: + if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 with: - fetch-depth: '0' # this is required to actually get all the authors - - run: "tools/update-authors.js" # run the AUTHORS tool - - uses: gr2m/create-or-update-pull-request-action@v1 # create a PR or update the Action's existing PR + fetch-depth: '0' # This is required to actually get all the authors + - run: "tools/update-authors.js" # Run the AUTHORS tool + - uses: gr2m/create-or-update-pull-request-action@v1 # Create a PR or update the Action's existing PR env: GITHUB_TOKEN: ${{ secrets.GH_USER_TOKEN }} with: author: Node.js GitHub Bot body: "If this PR exists, there's presumably new additions to the AUTHORS file. This is an automatically generated PR by the `authors.yml` GitHub Action, which runs `tools/update-authors.js` and submits a new PR or updates an existing PR.\n\nPlease note that there might be duplicate entries. If there are, please remove them and add the duplicate emails to .mailmap directly to this PR." - branch: "actions/authors-update" # custom branch *just* for this Action. + branch: "actions/authors-update" # Custom branch *just* for this Action. commit-message: "meta: update AUTHORS" labels: meta title: "meta: update AUTHORS" diff --git a/.github/workflows/auto-start-ci.yml b/.github/workflows/auto-start-ci.yml index c3527549e16af4..ef7c97d9e502b6 100644 --- a/.github/workflows/auto-start-ci.yml +++ b/.github/workflows/auto-start-ci.yml @@ -1,4 +1,3 @@ ---- name: Auto Start CI on: diff --git a/.github/workflows/close-stalled.yml b/.github/workflows/close-stalled.yml index 916baf0463fa6c..351ddb78c012f8 100644 --- a/.github/workflows/close-stalled.yml +++ b/.github/workflows/close-stalled.yml @@ -1,26 +1,26 @@ name: Close stalled issues and PRs on: schedule: - - cron: "0 0 * * *" + - cron: "0 0 * * *" jobs: stale: if: github.repository == 'nodejs/node' runs-on: ubuntu-latest steps: - - uses: actions/stale@v3 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - days-before-close: 30 - stale-pr-label: stalled - stale-issue-label: stalled - close-issue-message: Closing this because it has stalled. Feel free to reopen if this issue is still relevant, or to ping the collaborator who labelled it stalled if you have any questions. - close-pr-message: Closing this because it has stalled. Feel free to reopen if this PR is still relevant, or to ping the collaborator who labelled it stalled if you have any questions. - # used to filter issues to check whether or not should be closed, avoids hitting maximum operations allowed if needing to paginate through all open issues - only-labels: stalled - # max requests it will send per run to the GitHub API before it deliberately exits to avoid hitting API rate limits - operations-per-run: 500 - # deactivates automatic removal of stalled label if issue gets any activity - remove-stale-when-updated: false - # deactivates automatic stale labelling as we prefer to do that manually - days-before-stale: -1 + - uses: actions/stale@v3 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-close: 30 + stale-pr-label: stalled + stale-issue-label: stalled + close-issue-message: Closing this because it has stalled. Feel free to reopen if this issue is still relevant, or to ping the collaborator who labelled it stalled if you have any questions. + close-pr-message: Closing this because it has stalled. Feel free to reopen if this PR is still relevant, or to ping the collaborator who labelled it stalled if you have any questions. + # used to filter issues to check whether or not should be closed, avoids hitting maximum operations allowed if needing to paginate through all open issues + only-labels: stalled + # max requests it will send per run to the GitHub API before it deliberately exits to avoid hitting API rate limits + operations-per-run: 500 + # deactivates automatic removal of stalled label if issue gets any activity + remove-stale-when-updated: false + # deactivates automatic stale labelling as we prefer to do that manually + days-before-stale: -1 diff --git a/.github/workflows/commit-queue.yml b/.github/workflows/commit-queue.yml index 9b8e99c98e5582..b2d37f80906896 100644 --- a/.github/workflows/commit-queue.yml +++ b/.github/workflows/commit-queue.yml @@ -1,4 +1,3 @@ ---- # This action requires the following secrets to be set on the repository: # GH_USER_NAME: GitHub user whose Jenkins and GitHub token are defined below # GH_USER_TOKEN: GitHub user token, to be used by ncu and to push changes diff --git a/.github/workflows/license-builder.yml b/.github/workflows/license-builder.yml index 115bef9977d9d5..b6453d61ac5199 100644 --- a/.github/workflows/license-builder.yml +++ b/.github/workflows/license-builder.yml @@ -12,8 +12,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - run: "./tools/license-builder.sh" # run the license builder tool - - uses: gr2m/create-or-update-pull-request-action@v1.x # create a PR or update the Action's existing PR + - run: "./tools/license-builder.sh" # Run the license builder tool + - uses: gr2m/create-or-update-pull-request-action@v1.x # Create a PR or update the Action's existing PR env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 04cecbbc516052..2694e07ab3c6fd 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -55,7 +55,7 @@ jobs: - name: Get release version numbers if: ${{ github.event.pull_request && github.event.pull_request.base.ref == github.event.pull_request.base.repo.default_branch }} id: get-released-versions - run: ./tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs + run: ./tools/lint-md/list-released-versions-from-changelogs.mjs - name: Lint docs run: | echo "::add-matcher::.github/workflows/remark-lint-problem-matcher.json" diff --git a/.github/workflows/test-internet.yml b/.github/workflows/test-internet.yml index 4ef4c42c147d47..8d2ba377d3cd0f 100644 --- a/.github/workflows/test-internet.yml +++ b/.github/workflows/test-internet.yml @@ -5,10 +5,10 @@ on: schedule: - cron: 5 0 * * * -pull_request: - types: [opened, synchronize, reopened, ready_for_review] - paths: - - test/internet/** + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths: + - test/internet/** push: branches: - master diff --git a/.mailmap b/.mailmap index 9ee76141ef3af6..8800cfab9a3fc7 100644 --- a/.mailmap +++ b/.mailmap @@ -153,6 +153,7 @@ garygsc Geoffrey Booth Geoffrey Booth Geoffrey Bugaisky +George Adams Gerhard Stöbich Gibson Fahnestock Gil Pedersen @@ -246,8 +247,11 @@ Kiyoshi Nomo Koichi Kobayashi Kostiantyn Wandalen Kris Kowal +Kunal Pathak Kyle Robinson Young +Lakshmi Swetha Gopireddy Lakshmi Swetha Gopireddy +Lars-Magnus Skog Leeseean Chiu Lucas Pardue Luke Bayes diff --git a/.yamllint.yaml b/.yamllint.yaml index d4af06e4156947..97ec306ea3fa0c 100644 --- a/.yamllint.yaml +++ b/.yamllint.yaml @@ -1,8 +1,15 @@ -extends: relaxed +extends: default rules: + document-start: + present: false line-length: disable + truthy: + allowed-values: ['true', 'false', 'on', 'off'] ignore: | /deps/ node_modules/ + /test/fixtures/wpt/ + /tools/gyp/ + /tools/pip/ diff --git a/AUTHORS b/AUTHORS index 602727b0a389e3..a0a0ef6cc1248f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -419,7 +419,7 @@ Arianit Uka Andrei Sedoi Eugene Girshov Evan Oxfeld -Lars-Magnus Skog +Lars-Magnus Skog Raymond Feng Aaron Cannon Xidorn Quan @@ -1328,7 +1328,7 @@ Nate Chris Story Matthew Garrett David Goussev -George Adams +George Adams Benedikt Meurer Kai Cataldo Victor Felder @@ -1600,7 +1600,6 @@ rockcoder23 Anton Paras Pratik Jain Shivanth MP -Kunal Pathak erdun <494251936@qq.com> Jiajie Hu Matt Woicik @@ -2297,7 +2296,6 @@ Yongsheng Zhang Neeraj Laad Scott Van Gilder Yaniv Friedensohn -Lars-Magnus Skog Lucas Woo Troels Liebe Bentsen pranshuchittora @@ -2644,7 +2642,6 @@ James Bunton Kevin Smith H1Gdev Julian Alimin -Lakshmi Swetha Gopireddy Manusaporn Treerungroj Richard Chamberlain Daniel George Holz @@ -3316,5 +3313,8 @@ Christian Boehlke null <60427892+vierofernando@users.noreply.github.com> Dominic Elm treysis +shfshanyue +Nikita Galkin +vipul kumar # Generated by tools/update-authors.js diff --git a/BUILDING.md b/BUILDING.md index 06cfaff6052bb4..520d9b3d521538 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -113,49 +113,45 @@ platforms. This is true regardless of entries in the table below. | Windows | x86 (native) | >= Windows 8.1/2012 R2 | Tier 1 (running) / Experimental (compiling) [6](#fn6) | | | Windows | x64, x86 | Windows Server 2012 (not R2) | Experimental | | | Windows | arm64 | >= Windows 10 | Tier 2 (compiling) / Experimental (running) | | -| macOS | x64 | >= 10.13 | Tier 1 | For notes about compilation see [8](#fn8) | +| macOS | x64 | >= 10.13 | Tier 1 | For notes about compilation see [7](#fn7) | | macOS | arm64 | >= 11 | Tier 1 | | | SmartOS | x64 | >= 18 | Tier 2 | | | AIX | ppc64be >=power7 | >= 7.2 TL04 | Tier 2 | | -| FreeBSD | x64 | >= 11 | Experimental | Downgraded as of Node.js 12 [7](#fn7) | +| FreeBSD | x64 | >= 12.2 | Experimental | | 1: GCC 8 is not provided on the base platform. Users will - need the - [Toolchain test builds PPA](https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test?field.series_filter=xenial) - or similar to source a newer compiler. +need the +[Toolchain test builds PPA](https://launchpad.net/~ubuntu-toolchain-r/+archive/ubuntu/test?field.series_filter=xenial) +or similar to source a newer compiler. 2: GCC 8 is not provided on the base platform. Users will - need the - [devtoolset-8](https://www.softwarecollections.org/en/scls/rhscl/devtoolset-8/) - or later to source a newer compiler. +need the +[devtoolset-8](https://www.softwarecollections.org/en/scls/rhscl/devtoolset-8/) +or later to source a newer compiler. 3: Older kernel versions may work for ARM64. However the - Node.js test infrastructure only tests >= 4.5. +Node.js test infrastructure only tests >= 4.5. 4: On Windows, running Node.js in Windows terminal emulators - like `mintty` requires the usage of [winpty](https://github.com/rprichard/winpty) - for the tty channels to work (e.g. `winpty node.exe script.js`). - In "Git bash" if you call the node shell alias (`node` without the `.exe` - extension), `winpty` is used automatically. +like `mintty` requires the usage of [winpty](https://github.com/rprichard/winpty) +for the tty channels to work (e.g. `winpty node.exe script.js`). +In "Git bash" if you call the node shell alias (`node` without the `.exe` +extension), `winpty` is used automatically. 5: The Windows Subsystem for Linux (WSL) is not - supported, but the GNU/Linux build process and binaries should work. The - community will only address issues that reproduce on native GNU/Linux - systems. Issues that only reproduce on WSL should be reported in the - [WSL issue tracker](https://github.com/Microsoft/WSL/issues). Running the - Windows binary (`node.exe`) in WSL is not recommended. It will not work - without workarounds such as stdio redirection. +supported, but the GNU/Linux build process and binaries should work. The +community will only address issues that reproduce on native GNU/Linux +systems. Issues that only reproduce on WSL should be reported in the +[WSL issue tracker](https://github.com/Microsoft/WSL/issues). Running the +Windows binary (`node.exe`) in WSL is not recommended. It will not work +without workarounds such as stdio redirection. 6: Running Node.js on x86 Windows should work and binaries are provided. However, tests in our infrastructure only run on WoW64. Furthermore, compiling on x86 Windows is Experimental and may not be possible. -7: The default FreeBSD 12.0 compiler is Clang 6.0.1, but -FreeBSD 12.1 upgrades to 8.0.1. Other Clang/LLVM versions are available -via the system's package manager, including Clang 9.0. - -8: Our macOS x64 Binaries are compiled with 10.13 as a target. +7: Our macOS x64 Binaries are compiled with 10.13 as a target. However there is no guarantee compiling on 10.13 will work as Xcode11 is required to compile. @@ -195,7 +191,7 @@ Ubuntu 14.04 and Debian 8. #### OpenSSL asm support OpenSSL-1.1.1 requires the following assembler version for use of asm -support on x86_64 and ia32. +support on x86\_64 and ia32. For use of AVX-512, @@ -212,9 +208,9 @@ For use of AVX2, * nasm version 2.10 or higher in Windows Please refer to - for details. + for details. - If compiling without one of the above, use `configure` with the +If compiling without one of the above, use `configure` with the `--openssl-no-asm` flag. Otherwise, `configure` will fail. ### Previous versions of this document @@ -232,6 +228,7 @@ Consult previous versions of this document for older versions of Node.js: ### Note about Python The Node.js project supports Python >= 3 for building and testing. + ### Unix and macOS #### Unix prerequisites @@ -480,7 +477,7 @@ release version is actually installed when you run `make install`. To use the debug build with all the normal dependencies overwrite the release version in the install directory: -``` console +```console $ make install PREFIX=/opt/node-debug/ $ cp -a -f out/Debug/node /opt/node-debug/node ``` @@ -496,7 +493,7 @@ was captured on (i.e. 64-bit `gdb` for `node` built on a 64-bit system, Linux Example of generating a backtrace from the core dump: -``` console +```console $ gdb /opt/node-debug/node core.node.8.1535359906 $ backtrace ``` @@ -507,12 +504,12 @@ $ backtrace related bugs. ASAN builds are currently only supported on linux. If you want to check it on Windows or macOS or you want a consistent toolchain on Linux, you can try [Docker](https://www.docker.com/products/docker-desktop) - (using an image like `gengjiawen/node-build:2020-02-14`). +(using an image like `gengjiawen/node-build:2020-02-14`). The `--debug` is not necessary and will slow down build and testing, but it can show clear stacktrace if ASAN hits an issue. -``` console +```console $ ./configure --debug --enable-asan && make -j4 $ make test-only ``` @@ -521,6 +518,7 @@ $ make test-only If you plan to frequently rebuild Node.js, especially if using several branches, installing `ccache` can help to greatly reduce build times. Set up with: + ```console $ sudo apt install ccache # for Debian/Ubuntu, included in most Linux distros $ ccache -o cache_dir= @@ -528,13 +526,16 @@ $ ccache -o max_size=5.0G $ export CC="ccache gcc" # add to your .profile $ export CXX="ccache g++" # add to your .profile ``` + This will allow for near-instantaneous rebuilds even when switching branches. When modifying only the JS layer in `lib`, it is possible to externally load it without modifying the executable: + ```console $ ./configure --node-builtin-modules-path $(pwd) ``` + The resulting binary won't include any JS files and will try to load them from the specified directory. The JS debugger of Visual Studio Code supports this configuration since the November 2020 version and allows for setting @@ -678,7 +679,7 @@ $ ./configure --with-intl=full-icu ### Trimmed: `small-icu` (English only) support - In this configuration, only English data is included, but +In this configuration, only English data is included, but the full `Intl` (ECMA-402) APIs. It does not need to download any dependencies to function. You can add full data at runtime. @@ -774,6 +775,7 @@ If you want to build Node.js using openssl-3.0.0+quic, you can follow these steps: **clone OpenSSL source and prepare build** + ```bash git clone git@github.com:quictls/openssl.git @@ -791,6 +793,7 @@ will publish the OpenSSL libraries and such. We will also use this path (and sub-paths) later when compiling Node.js. **compile and install OpenSSL** + ```console make -j8 make install @@ -806,6 +809,7 @@ find the `fipsmodule.cnf` file - let's add the following to the end of the `openssl.cnf` file. **alter openssl.cnf** + ```text .include fipsmodule.cnf @@ -826,6 +830,7 @@ sure that you specify an absolute path for the `.include fipsmodule.cnf` line - using relative paths did not work on my system! **alter openssl.cnf using a script** + ```console cat <> /path/to/install/dir/ssl/openssl.cnf .include /path/to/install/dir/ssl/fipsmodule.cnf @@ -845,12 +850,14 @@ EOT As you might have picked a non-custom path for your OpenSSL install dir, we have to export the following two environment variables in order for Node.js to find our OpenSSL modules we built beforehand: + ```console export OPENSSL_CONF=/path/to/install/dir/ssl/openssl.cnf export OPENSSL_MODULES=/path/to/install/dir/lib/ossl-modules ``` **build Node.js** + ```console ./configure \ --shared-openssl \ @@ -865,6 +872,7 @@ make -j8 ``` **verify the produced executable** + ```console ldd ./node linux-vdso.so.1 (0x00007ffd7917b000) @@ -884,12 +892,14 @@ If the `ldd` command says that `libcrypto` cannot be found one needs to set `--shared-openssl-libpath` (see previous step). **verify the OpenSSL version** + ```console ./node -p process.versions.openssl 3.0.0-alpha16+quic ``` **verify that FIPS is available** + ```console ./node -p 'process.config.variables.openssl_is_fips' true @@ -905,13 +915,16 @@ executable. See sections [Enabling FIPS using OpenSSL config](#enabling-fips-using-openssl-config) below. ### Enabling FIPS using Node.js options + This is done using one of the Node.js options `--enable-fips` or `--force-fips`, for example: + ```console $ node --enable-fips -p 'crypto.getFips()' ``` ### Enabling FIPS using OpenSSL config + This example show that using OpenSSL's configuration file, FIPS can be enabled without specifying the `--enable-fips` or `--force-fips` options by setting `default_properties = fips=yes` in the FIPS configuration file. See @@ -920,6 +933,7 @@ for details. For this to work the OpenSSL configuration file (default openssl.cnf) needs to be updated. The following shows an example: + ```console openssl_conf = openssl_init @@ -939,6 +953,7 @@ activate = 1 [algorithm_sect] default_properties = fips=yes ``` + After this change Node.js can be run without the `--enable-fips` or `--force-fips` options. diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b9d45bae3ae90..0a9a84011b0368 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ Please use the following table to find the changelog for a specific Node.js release. + @@ -32,7 +33,8 @@ release.
16Current
-16.9.1
+16.10.0
+16.9.1
16.9.0
16.8.0
16.7.0
@@ -49,7 +51,8 @@ release. 16.0.0
-14.17.6
+14.18.0
+14.17.6
14.17.5
14.17.4
14.17.3
@@ -138,8 +141,9 @@ release. LTS releases. * Release versions in **bold** text are the most recent supported releases. ----- ----- +*** + +*** ## 2016-05-06, Version 0.12.14 (Maintenance), @rvagg @@ -1355,7 +1359,7 @@ release. ## 2009.08.21, Version 0.1.5 -Moved to doc/changelogs/CHANGELOG_V6.md#6.0.0. ## 2009.08.13, Version 0.1.4 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30db8cf9b12524..d0d3f4f648ef96 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,8 +29,10 @@ See [details on our policy on Code of Conduct](./doc/guides/contributing/code-of * [Notes](./doc/guides/contributing/pull-requests.md#notes) + ## Developer's Certificate of Origin 1.1 +
 By making a contribution to this project, I certify that:
 
  (a) The contribution was created in whole or in part by me and I
@@ -54,3 +56,4 @@ By making a contribution to this project, I certify that:
      personal information I submit with it, including my sign-off) is
      maintained indefinitely and may be redistributed consistent with
      this project or the open source license(s) involved.
+
diff --git a/GOVERNANCE.md b/GOVERNANCE.md index aa73e4b3ee7519..37ce1576cffccf 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -153,8 +153,8 @@ the nomination fails. There are steps a nominator can take in advance to make a nomination as frictionless as possible. To request feedback from other collaborators in - private, use the [collaborators discussion page][] - (which only collaborators may view). A nominator may also work with the +private, use the [collaborators discussion page][] +(which only collaborators may view). A nominator may also work with the nominee to improve their contribution profile. Collaborators might overlook someone with valuable contributions. In that case, diff --git a/Makefile b/Makefile index baae6a3b46bd26..e55bd8d70242ac 100644 --- a/Makefile +++ b/Makefile @@ -827,6 +827,9 @@ else ifeq ($(findstring s390,$(UNAME_M)),s390) DESTCPU ?= s390 else +ifeq ($(findstring arm64,$(UNAME_M)),arm64) +DESTCPU ?= arm64 +else ifeq ($(findstring arm,$(UNAME_M)),arm) DESTCPU ?= arm else @@ -850,6 +853,7 @@ endif endif endif endif +endif ifeq ($(DESTCPU),x64) ARCH=x64 else @@ -1221,12 +1225,11 @@ bench-addons-clean: .PHONY: lint-md-rollup lint-md-rollup: $(RM) tools/.*mdlintstamp - cd tools/node-lint-md-cli-rollup && npm install - cd tools/node-lint-md-cli-rollup && npm run build-node + cd tools/lint-md && npm ci && npm run build .PHONY: lint-md-clean lint-md-clean: - $(RM) -r tools/node-lint-md-cli-rollup/node_modules + $(RM) -r tools/lint-md/node_modules $(RM) tools/.*mdlintstamp .PHONY: lint-md-build @@ -1243,7 +1246,7 @@ LINT_MD_TARGETS = doc src lib benchmark test tools/doc tools/icu $(wildcard *.md LINT_MD_FILES = $(shell $(FIND) $(LINT_MD_TARGETS) -type f \ ! -path '*node_modules*' ! -path 'test/fixtures/*' -name '*.md' \ $(LINT_MD_NEWER)) -run-lint-md = tools/lint-md.mjs -q -f --no-stdout $(LINT_MD_FILES) +run-lint-md = tools/lint-md/lint-md.mjs $(LINT_MD_FILES) # Lint all changed markdown files maintained by us tools/.mdlintstamp: $(LINT_MD_FILES) $(info Running Markdown linter...) @@ -1254,6 +1257,13 @@ tools/.mdlintstamp: $(LINT_MD_FILES) # Lints the markdown documents maintained by us in the codebase. lint-md: lint-js-doc | tools/.mdlintstamp +run-format-md = tools/lint-md/lint-md.mjs --format $(LINT_MD_FILES) +.PHONY: format-md +# Formats the markdown documents maintained by us in the codebase. +format-md: + @$(call available-node,$(run-format-md)) + + LINT_JS_TARGETS = .eslintrc.js benchmark doc lib test tools @@ -1392,8 +1402,8 @@ cpplint: lint-cpp # Try with '--system' if it fails without; the system may have set '--user' lint-py-build: $(info Pip installing flake8 linter on $(shell $(PYTHON) --version)...) - $(PYTHON) -m pip install --upgrade -t tools/pip/site-packages flake8 || \ - $(PYTHON) -m pip install --upgrade --system -t tools/pip/site-packages flake8 + $(PYTHON) -m pip install --no-user --upgrade -t tools/pip/site-packages flake8 || \ + $(PYTHON) -m pip install --no-user --upgrade --system -t tools/pip/site-packages flake8 ifneq ("","$(wildcard tools/pip/site-packages/flake8)") .PHONY: lint-py @@ -1412,8 +1422,8 @@ endif # Try with '--system' if it fails without; the system may have set '--user' lint-yaml-build: $(info Pip installing yamllint on $(shell $(PYTHON) --version)...) - $(PYTHON) -m pip install --upgrade -t tools/pip/site-packages yamllint || \ - $(PYTHON) -m pip install --upgrade --system -t tools/pip/site-packages yamllint + $(PYTHON) -m pip install --no-user --upgrade -t tools/pip/site-packages yamllint || \ + $(PYTHON) -m pip install --no-user --upgrade --system -t tools/pip/site-packages yamllint .PHONY: lint-yaml # Lints the YAML files with yamllint. diff --git a/README.md b/README.md index a0ffe3b2ba6455..f25095b165db1a 100644 --- a/README.md +++ b/README.md @@ -499,7 +499,7 @@ For information about the governance of the Node.js project, see * [firedfox](https://github.com/firedfox) - **Daniel Wang** \ * [gdams](https://github.com/gdams) - - **George Adams** \ (he/him) + **George Adams** \ (he/him) * [geek](https://github.com/geek) - **Wyatt Preul** \ * [gibfahn](https://github.com/gibfahn) - diff --git a/benchmark/README.md b/benchmark/README.md index dc02db4abd8d24..e40972fde08ac9 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -32,7 +32,7 @@ directory, see [the guide on benchmarks](../doc/guides/writing-and-running-bench | module | Benchmarks for the `module` subsystem. | | net | Benchmarks for the `net` subsystem. | | path | Benchmarks for the `path` subsystem. | -| perf_hooks | Benchmarks for the `perf_hooks` subsystem. | +| perf\_hooks | Benchmarks for the `perf_hooks` subsystem. | | process | Benchmarks for the `process` subsystem. | | querystring | Benchmarks for the `querystring` subsystem. | | streams | Benchmarks for the `streams` subsystem. | diff --git a/benchmark/util/to-usv-string.js b/benchmark/util/to-usv-string.js new file mode 100644 index 00000000000000..22d23d3198d124 --- /dev/null +++ b/benchmark/util/to-usv-string.js @@ -0,0 +1,21 @@ +'use strict'; + +const common = require('../common'); + +const BASE = 'string\ud801'; + +const bench = common.createBenchmark(main, { + n: [1e5], + size: [10, 100, 500], +}); + +function main({ n, size }) { + const { toUSVString } = require('util'); + const str = BASE.repeat(size); + + bench.start(); + for (let i = 0; i < n; i++) { + toUSVString(str); + } + bench.end(n); +} diff --git a/configure.py b/configure.py index 9327d6e5f5da06..6efb98c2316f08 100755 --- a/configure.py +++ b/configure.py @@ -1512,7 +1512,7 @@ def glob_to_var(dir_base, dir_sub, patch_dir): for ent in files: (path, dirs, files) = ent for file in files: - if file.endswith('.cpp') or file.endswith('.c') or file.endswith('.h'): + if file.endswith(('.cpp', '.c', '.h')): # srcfile uses "slash" as dir separator as its output is consumed by gyp srcfile = '%s/%s' % (dir_sub, file) if patch_dir: diff --git a/deps/nghttp2/lib/CMakeLists.txt b/deps/nghttp2/lib/CMakeLists.txt index a02a534b1a8436..4dc2fcdbac6a60 100644 --- a/deps/nghttp2/lib/CMakeLists.txt +++ b/deps/nghttp2/lib/CMakeLists.txt @@ -24,7 +24,6 @@ set(NGHTTP2_SOURCES nghttp2_http.c nghttp2_rcbuf.c nghttp2_debug.c - nghttp2_ksl.c ) set(NGHTTP2_RES "") diff --git a/deps/nghttp2/lib/Makefile.am b/deps/nghttp2/lib/Makefile.am index 63fa0fa8324d0a..1e1f24843ac713 100644 --- a/deps/nghttp2/lib/Makefile.am +++ b/deps/nghttp2/lib/Makefile.am @@ -27,6 +27,7 @@ EXTRA_DIST = Makefile.msvc CMakeLists.txt version.rc.in AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG) AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \ @DEFS@ +AM_LDFLAGS = @LIBTOOL_LDFLAGS@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnghttp2.pc @@ -49,8 +50,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \ nghttp2_mem.c \ nghttp2_http.c \ nghttp2_rcbuf.c \ - nghttp2_debug.c \ - nghttp2_ksl.c + nghttp2_debug.c HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \ nghttp2_frame.h \ @@ -66,9 +66,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \ nghttp2_mem.h \ nghttp2_http.h \ nghttp2_rcbuf.h \ - nghttp2_debug.h \ - nghttp2_ksl.h + nghttp2_debug.h libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS) -libnghttp2_la_LDFLAGS = -no-undefined \ +libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) diff --git a/deps/nghttp2/lib/Makefile.in b/deps/nghttp2/lib/Makefile.in index 14ec74591ba3df..78e76e55d9683d 100644 --- a/deps/nghttp2/lib/Makefile.in +++ b/deps/nghttp2/lib/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.16.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -162,7 +162,7 @@ am__objects_2 = nghttp2_pq.lo nghttp2_map.lo nghttp2_queue.lo \ nghttp2_hd_huffman.lo nghttp2_hd_huffman_data.lo \ nghttp2_version.lo nghttp2_priority_spec.lo nghttp2_option.lo \ nghttp2_callbacks.lo nghttp2_mem.lo nghttp2_http.lo \ - nghttp2_rcbuf.lo nghttp2_debug.lo nghttp2_ksl.lo + nghttp2_rcbuf.lo nghttp2_debug.lo am_libnghttp2_la_OBJECTS = $(am__objects_1) $(am__objects_2) libnghttp2_la_OBJECTS = $(am_libnghttp2_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -193,9 +193,8 @@ am__depfiles_remade = ./$(DEPDIR)/nghttp2_buf.Plo \ ./$(DEPDIR)/nghttp2_hd.Plo ./$(DEPDIR)/nghttp2_hd_huffman.Plo \ ./$(DEPDIR)/nghttp2_hd_huffman_data.Plo \ ./$(DEPDIR)/nghttp2_helper.Plo ./$(DEPDIR)/nghttp2_http.Plo \ - ./$(DEPDIR)/nghttp2_ksl.Plo ./$(DEPDIR)/nghttp2_map.Plo \ - ./$(DEPDIR)/nghttp2_mem.Plo ./$(DEPDIR)/nghttp2_npn.Plo \ - ./$(DEPDIR)/nghttp2_option.Plo \ + ./$(DEPDIR)/nghttp2_map.Plo ./$(DEPDIR)/nghttp2_mem.Plo \ + ./$(DEPDIR)/nghttp2_npn.Plo ./$(DEPDIR)/nghttp2_option.Plo \ ./$(DEPDIR)/nghttp2_outbound_item.Plo \ ./$(DEPDIR)/nghttp2_pq.Plo \ ./$(DEPDIR)/nghttp2_priority_spec.Plo \ @@ -262,8 +261,6 @@ am__define_uniq_tagged_files = \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libnghttp2.pc.in \ $(top_srcdir)/depcomp @@ -307,11 +304,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@ BOOST_THREAD_LIB = @BOOST_THREAD_LIB@ +BPFCFLAGS = @BPFCFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CUNIT_CFLAGS = @CUNIT_CFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ @@ -330,8 +330,11 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ +EXTRABPFCFLAGS = @EXTRABPFCFLAGS@ EXTRACFLAG = @EXTRACFLAG@ +EXTRA_DEFS = @EXTRA_DEFS@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX14 = @HAVE_CXX14@ @@ -342,9 +345,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JANSSON_CFLAGS = @JANSSON_CFLAGS@ JANSSON_LIBS = @JANSSON_LIBS@ +JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@ JEMALLOC_LIBS = @JEMALLOC_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBBPF_CFLAGS = @LIBBPF_CFLAGS@ +LIBBPF_LIBS = @LIBBPF_LIBS@ LIBCARES_CFLAGS = @LIBCARES_CFLAGS@ LIBCARES_LIBS = @LIBCARES_LIBS@ LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@ @@ -353,9 +359,16 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@ LIBEV_LIBS = @LIBEV_LIBS@ LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@ LIBMRUBY_LIBS = @LIBMRUBY_LIBS@ +LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@ +LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@ +LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@ +LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@ +LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@ +LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ +LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ @@ -393,7 +406,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ -PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ +PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ @@ -487,6 +500,7 @@ AM_CFLAGS = $(WARNCFLAGS) $(EXTRACFLAG) AM_CPPFLAGS = -I$(srcdir)/includes -I$(builddir)/includes -DBUILDING_NGHTTP2 \ @DEFS@ +AM_LDFLAGS = @LIBTOOL_LDFLAGS@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnghttp2.pc DISTCLEANFILES = $(pkgconfig_DATA) @@ -506,8 +520,7 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \ nghttp2_mem.c \ nghttp2_http.c \ nghttp2_rcbuf.c \ - nghttp2_debug.c \ - nghttp2_ksl.c + nghttp2_debug.c HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \ nghttp2_frame.h \ @@ -523,11 +536,10 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \ nghttp2_mem.h \ nghttp2_http.h \ nghttp2_rcbuf.h \ - nghttp2_debug.h \ - nghttp2_ksl.h + nghttp2_debug.h libnghttp2_la_SOURCES = $(HFILES) $(OBJECTS) -libnghttp2_la_LDFLAGS = -no-undefined \ +libnghttp2_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined \ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) all: all-recursive @@ -619,7 +631,6 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_hd_huffman_data.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_helper.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_http.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_ksl.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_mem.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nghttp2_npn.Plo@am__quote@ # am--include-marker @@ -789,7 +800,6 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am @@ -902,7 +912,6 @@ distclean: distclean-recursive -rm -f ./$(DEPDIR)/nghttp2_hd_huffman_data.Plo -rm -f ./$(DEPDIR)/nghttp2_helper.Plo -rm -f ./$(DEPDIR)/nghttp2_http.Plo - -rm -f ./$(DEPDIR)/nghttp2_ksl.Plo -rm -f ./$(DEPDIR)/nghttp2_map.Plo -rm -f ./$(DEPDIR)/nghttp2_mem.Plo -rm -f ./$(DEPDIR)/nghttp2_npn.Plo @@ -970,7 +979,6 @@ maintainer-clean: maintainer-clean-recursive -rm -f ./$(DEPDIR)/nghttp2_hd_huffman_data.Plo -rm -f ./$(DEPDIR)/nghttp2_helper.Plo -rm -f ./$(DEPDIR)/nghttp2_http.Plo - -rm -f ./$(DEPDIR)/nghttp2_ksl.Plo -rm -f ./$(DEPDIR)/nghttp2_map.Plo -rm -f ./$(DEPDIR)/nghttp2_mem.Plo -rm -f ./$(DEPDIR)/nghttp2_npn.Plo diff --git a/deps/nghttp2/lib/includes/Makefile.in b/deps/nghttp2/lib/includes/Makefile.in index e1948dfeaa3f1c..834eff24ab9c67 100644 --- a/deps/nghttp2/lib/includes/Makefile.in +++ b/deps/nghttp2/lib/includes/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.2 from Makefile.am. +# Makefile.in generated by automake 1.16.4 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2020 Free Software Foundation, Inc. +# Copyright (C) 1994-2021 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -197,8 +197,6 @@ am__define_uniq_tagged_files = \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ @@ -215,11 +213,14 @@ BOOST_CPPFLAGS = @BOOST_CPPFLAGS@ BOOST_LDFLAGS = @BOOST_LDFLAGS@ BOOST_SYSTEM_LIB = @BOOST_SYSTEM_LIB@ BOOST_THREAD_LIB = @BOOST_THREAD_LIB@ +BPFCFLAGS = @BPFCFLAGS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ CUNIT_CFLAGS = @CUNIT_CFLAGS@ CUNIT_LIBS = @CUNIT_LIBS@ CXX = @CXX@ @@ -238,8 +239,11 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +ETAGS = @ETAGS@ EXEEXT = @EXEEXT@ +EXTRABPFCFLAGS = @EXTRABPFCFLAGS@ EXTRACFLAG = @EXTRACFLAG@ +EXTRA_DEFS = @EXTRA_DEFS@ FGREP = @FGREP@ GREP = @GREP@ HAVE_CXX14 = @HAVE_CXX14@ @@ -250,9 +254,12 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ JANSSON_CFLAGS = @JANSSON_CFLAGS@ JANSSON_LIBS = @JANSSON_LIBS@ +JEMALLOC_CFLAGS = @JEMALLOC_CFLAGS@ JEMALLOC_LIBS = @JEMALLOC_LIBS@ LD = @LD@ LDFLAGS = @LDFLAGS@ +LIBBPF_CFLAGS = @LIBBPF_CFLAGS@ +LIBBPF_LIBS = @LIBBPF_LIBS@ LIBCARES_CFLAGS = @LIBCARES_CFLAGS@ LIBCARES_LIBS = @LIBCARES_LIBS@ LIBEVENT_OPENSSL_CFLAGS = @LIBEVENT_OPENSSL_CFLAGS@ @@ -261,9 +268,16 @@ LIBEV_CFLAGS = @LIBEV_CFLAGS@ LIBEV_LIBS = @LIBEV_LIBS@ LIBMRUBY_CFLAGS = @LIBMRUBY_CFLAGS@ LIBMRUBY_LIBS = @LIBMRUBY_LIBS@ +LIBNGHTTP3_CFLAGS = @LIBNGHTTP3_CFLAGS@ +LIBNGHTTP3_LIBS = @LIBNGHTTP3_LIBS@ +LIBNGTCP2_CFLAGS = @LIBNGTCP2_CFLAGS@ +LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS = @LIBNGTCP2_CRYPTO_OPENSSL_CFLAGS@ +LIBNGTCP2_CRYPTO_OPENSSL_LIBS = @LIBNGTCP2_CRYPTO_OPENSSL_LIBS@ +LIBNGTCP2_LIBS = @LIBNGTCP2_LIBS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ +LIBTOOL_LDFLAGS = @LIBTOOL_LDFLAGS@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBXML2_LIBS = @LIBXML2_LIBS@ LIPO = @LIPO@ @@ -301,7 +315,7 @@ PYTHON_CPPFLAGS = @PYTHON_CPPFLAGS@ PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ PYTHON_EXTRA_LDFLAGS = @PYTHON_EXTRA_LDFLAGS@ PYTHON_EXTRA_LIBS = @PYTHON_EXTRA_LIBS@ -PYTHON_LDFLAGS = @PYTHON_LDFLAGS@ +PYTHON_LIBS = @PYTHON_LIBS@ PYTHON_PLATFORM = @PYTHON_PLATFORM@ PYTHON_PREFIX = @PYTHON_PREFIX@ PYTHON_SITE_PKG = @PYTHON_SITE_PKG@ @@ -497,7 +511,6 @@ cscopelist-am: $(am__tagged_files) distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - distdir: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) distdir-am diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h index d9fae5bf0c138e..04321a652f145b 100644 --- a/deps/nghttp2/lib/includes/nghttp2/nghttp2.h +++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2.h @@ -411,12 +411,12 @@ typedef enum { */ NGHTTP2_ERR_TOO_MANY_SETTINGS = -537, /** - * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is - * under unexpected condition and processing was terminated (e.g., - * out of memory). If application receives this error code, it must - * stop using that :type:`nghttp2_session` object and only allowed - * operation for that object is deallocate it using - * `nghttp2_session_del()`. + * The errors < :enum:`nghttp2_error.NGHTTP2_ERR_FATAL` mean that + * the library is under unexpected condition and processing was + * terminated (e.g., out of memory). If application receives this + * error code, it must stop using that :type:`nghttp2_session` + * object and only allowed operation for that object is deallocate + * it using `nghttp2_session_del()`. */ NGHTTP2_ERR_FATAL = -900, /** @@ -545,9 +545,9 @@ typedef struct { * :type:`nghttp2_on_frame_send_callback`, and * :type:`nghttp2_on_frame_not_send_callback`), it may not be * NULL-terminated if header field is passed from application with - * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`). When application - * is constructing this struct, |name| is not required to be - * NULL-terminated. + * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`). + * When application is constructing this struct, |name| is not + * required to be NULL-terminated. */ uint8_t *name; /** @@ -558,9 +558,9 @@ typedef struct { * :type:`nghttp2_on_frame_send_callback`, and * :type:`nghttp2_on_frame_not_send_callback`), it may not be * NULL-terminated if header field is passed from application with - * the flag :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE`). When - * application is constructing this struct, |value| is not required - * to be NULL-terminated. + * the flag :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE`). + * When application is constructing this struct, |value| is not + * required to be NULL-terminated. */ uint8_t *value; /** @@ -717,8 +717,8 @@ typedef enum { * * Default maximum number of incoming concurrent streams. Use * `nghttp2_submit_settings()` with - * :enum:`NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` to change the - * maximum number of incoming concurrent streams. + * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS` + * to change the maximum number of incoming concurrent streams. * * .. note:: * @@ -872,38 +872,41 @@ typedef enum { * The implementation of this function must read at most |length| * bytes of data from |source| (or possibly other places) and store * them in |buf| and return number of data stored in |buf|. If EOF is - * reached, set :enum:`NGHTTP2_DATA_FLAG_EOF` flag in |*data_flags|. + * reached, set :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag + * in |*data_flags|. * * Sometime it is desirable to avoid copying data into |buf| and let * application to send data directly. To achieve this, set - * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` to |*data_flags| (and possibly - * other flags, just like when we do copy), and return the number of - * bytes to send without copying data into |buf|. The library, seeing - * :enum:`NGHTTP2_DATA_FLAG_NO_COPY`, will invoke + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` to + * |*data_flags| (and possibly other flags, just like when we do + * copy), and return the number of bytes to send without copying data + * into |buf|. The library, seeing + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY`, will invoke * :type:`nghttp2_send_data_callback`. The application must send * complete DATA frame in that callback. * * If this callback is set by `nghttp2_submit_request()`, * `nghttp2_submit_response()` or `nghttp2_submit_headers()` and * `nghttp2_submit_data()` with flag parameter - * :enum:`NGHTTP2_FLAG_END_STREAM` set, and - * :enum:`NGHTTP2_DATA_FLAG_EOF` flag is set to |*data_flags|, DATA - * frame will have END_STREAM flag set. Usually, this is expected - * behaviour and all are fine. One exception is send trailer fields. - * You cannot send trailer fields after sending frame with END_STREAM - * set. To avoid this problem, one can set - * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM` along with - * :enum:`NGHTTP2_DATA_FLAG_EOF` to signal the library not to set - * END_STREAM in DATA frame. Then application can use - * `nghttp2_submit_trailer()` to send trailer fields. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` flag is set to + * |*data_flags|, DATA frame will have END_STREAM flag set. Usually, + * this is expected behaviour and all are fine. One exception is send + * trailer fields. You cannot send trailer fields after sending frame + * with END_STREAM set. To avoid this problem, one can set + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM` along + * with :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF` to signal the + * library not to set END_STREAM in DATA frame. Then application can + * use `nghttp2_submit_trailer()` to send trailer fields. * `nghttp2_submit_trailer()` can be called inside this callback. * * If the application wants to postpone DATA frames (e.g., * asynchronous I/O, or reading data blocks for long time), it is - * achieved by returning :enum:`NGHTTP2_ERR_DEFERRED` without reading - * any data in this invocation. The library removes DATA frame from - * the outgoing queue temporarily. To move back deferred DATA frame - * to outgoing queue, call `nghttp2_session_resume_data()`. + * achieved by returning :enum:`nghttp2_error.NGHTTP2_ERR_DEFERRED` + * without reading any data in this invocation. The library removes + * DATA frame from the outgoing queue temporarily. To move back + * deferred DATA frame to outgoing queue, call + * `nghttp2_session_resume_data()`. * * By default, |length| is limited to 16KiB at maximum. If peer * allows larger frames, application can enlarge transmission buffer @@ -912,16 +915,17 @@ typedef enum { * * If the application just wants to return from * `nghttp2_session_send()` or `nghttp2_session_mem_send()` without - * sending anything, return :enum:`NGHTTP2_ERR_PAUSE`. + * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. * * In case of error, there are 2 choices. Returning - * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close the stream - * by issuing RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. If a - * different error code is desirable, use - * `nghttp2_submit_rst_stream()` with a desired error code and then - * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. Returning - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session - * failure. + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will + * close the stream by issuing RST_STREAM with + * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. If a different + * error code is desirable, use `nghttp2_submit_rst_stream()` with a + * desired error code and then return + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. + * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will + * signal the entire session failure. */ typedef ssize_t (*nghttp2_data_source_read_callback)( nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length, @@ -1301,8 +1305,9 @@ typedef union { * |length| bytes of data stored in |data|. The |flags| is currently * not used and always 0. It must return the number of bytes sent if * it succeeds. If it cannot send any single byte without blocking, - * it must return :enum:`NGHTTP2_ERR_WOULDBLOCK`. For other errors, - * it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. The + * it must return :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. For + * other errors, it must return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The * |user_data| pointer is the third argument passed in to the call to * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. * @@ -1330,9 +1335,10 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session, /** * @functypedef * - * Callback function invoked when :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is - * used in :type:`nghttp2_data_source_read_callback` to send complete - * DATA frame. + * Callback function invoked when + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in + * :type:`nghttp2_data_source_read_callback` to send complete DATA + * frame. * * The |frame| is a DATA frame to send. The |framehd| is the * serialized frame header (9 bytes). The |length| is the length of @@ -1350,21 +1356,22 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session, * If all data were written successfully, return 0. * * If it cannot send any data at all, just return - * :enum:`NGHTTP2_ERR_WOULDBLOCK`; the library will call this callback - * with the same parameters later (It is recommended to send complete - * DATA frame at once in this function to deal with error; if partial - * frame data has already sent, it is impossible to send another data - * in that state, and all we can do is tear down connection). When - * data is fully processed, but application wants to make - * `nghttp2_session_mem_send()` or `nghttp2_session_send()` return - * immediately without processing next frames, return - * :enum:`NGHTTP2_ERR_PAUSE`. If application decided to reset this - * stream, return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then + * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`; the library will call + * this callback with the same parameters later (It is recommended to + * send complete DATA frame at once in this function to deal with + * error; if partial frame data has already sent, it is impossible to + * send another data in that state, and all we can do is tear down + * connection). When data is fully processed, but application wants + * to make `nghttp2_session_mem_send()` or `nghttp2_session_send()` + * return immediately without processing next frames, return + * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`. If application decided to + * reset this stream, return + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then * the library will send RST_STREAM with INTERNAL_ERROR as error code. * The application can also return - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, which will result in - * connection closure. Returning any other value is treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned. + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which will + * result in connection closure. Returning any other value is treated + * as :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. */ typedef int (*nghttp2_send_data_callback)(nghttp2_session *session, nghttp2_frame *frame, @@ -1381,11 +1388,13 @@ typedef int (*nghttp2_send_data_callback)(nghttp2_session *session, * currently not used and always 0. It must return the number of * bytes written in |buf| if it succeeds. If it cannot read any * single byte without blocking, it must return - * :enum:`NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF before it reads any - * single byte, it must return :enum:`NGHTTP2_ERR_EOF`. For other - * errors, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. - * Returning 0 is treated as :enum:`NGHTTP2_ERR_WOULDBLOCK`. The - * |user_data| pointer is the third argument passed in to the call to + * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. If it gets EOF + * before it reads any single byte, it must return + * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`. For other errors, it must + * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. + * Returning 0 is treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. The |user_data| + * pointer is the third argument passed in to the call to * `nghttp2_session_client_new()` or `nghttp2_session_server_new()`. * * This callback is required if the application uses @@ -1429,7 +1438,8 @@ typedef ssize_t (*nghttp2_recv_callback)(nghttp2_session *session, uint8_t *buf, * The implementation of this function must return 0 if it succeeds. * If nonzero value is returned, it is treated as fatal error and * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_frame_recv_callback()`. @@ -1457,7 +1467,8 @@ typedef int (*nghttp2_on_frame_recv_callback)(nghttp2_session *session, * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error and * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_invalid_frame_recv_callback()`. @@ -1480,9 +1491,9 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)( * `nghttp2_session_server_new()`. * * If the application uses `nghttp2_session_mem_recv()`, it can return - * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()` - * return without processing further input bytes. The memory by - * pointed by the |data| is retained until + * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make + * `nghttp2_session_mem_recv()` return without processing further + * input bytes. The memory by pointed by the |data| is retained until * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called. * The application must retain the input bytes which was used to * produce the |data| parameter, because it may refer to the memory @@ -1491,7 +1502,8 @@ typedef int (*nghttp2_on_invalid_frame_recv_callback)( * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error, and * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_data_chunk_recv_callback()`. @@ -1511,19 +1523,20 @@ typedef int (*nghttp2_on_data_chunk_recv_callback)(nghttp2_session *session, * `nghttp2_session_server_new()`. * * The implementation of this function must return 0 if it succeeds. - * It can also return :enum:`NGHTTP2_ERR_CANCEL` to cancel the - * transmission of the given frame. + * It can also return :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` to + * cancel the transmission of the given frame. * * If there is a fatal error while executing this callback, the - * implementation should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, - * which makes `nghttp2_session_send()` and - * `nghttp2_session_mem_send()` functions immediately return - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * implementation should return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes + * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * If the other value is returned, it is treated as if - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned. But the - * implementation should not rely on this since the library may define - * new return value to extend its capability. + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. + * But the implementation should not rely on this since the library + * may define new return value to extend its capability. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_before_frame_send_callback()`. @@ -1542,7 +1555,8 @@ typedef int (*nghttp2_before_frame_send_callback)(nghttp2_session *session, * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error and * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_frame_send_callback()`. @@ -1564,7 +1578,8 @@ typedef int (*nghttp2_on_frame_send_callback)(nghttp2_session *session, * The implementation of this function must return 0 if it succeeds. * If nonzero is returned, it is treated as fatal error and * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * `nghttp2_session_get_stream_user_data()` can be used to get * associated data. @@ -1595,7 +1610,8 @@ typedef int (*nghttp2_on_frame_not_send_callback)(nghttp2_session *session, * If nonzero is returned, it is treated as fatal error and * `nghttp2_session_recv()`, `nghttp2_session_mem_recv()`, * `nghttp2_session_send()`, and `nghttp2_session_mem_send()` - * functions immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * functions immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_stream_close_callback()`. @@ -1613,10 +1629,11 @@ typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session, * will be emitted by :type:`nghttp2_on_header_callback`. * * The ``frame->hd.flags`` may not have - * :enum:`NGHTTP2_FLAG_END_HEADERS` flag set, which indicates that one - * or more CONTINUATION frames are involved. But the application does - * not need to care about that because the header name/value pairs are - * emitted transparently regardless of CONTINUATION frames. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_HEADERS` flag set, which + * indicates that one or more CONTINUATION frames are involved. But + * the application does not need to care about that because the header + * name/value pairs are emitted transparently regardless of + * CONTINUATION frames. * * The server applications probably create an object to store * information about new stream if ``frame->hd.type == @@ -1639,26 +1656,31 @@ typedef int (*nghttp2_on_stream_close_callback)(nghttp2_session *session, * trailer fields also has ``frame->headers.cat == * NGHTTP2_HCAT_HEADERS`` which does not contain any status code. * - * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close - * the stream (promised stream if frame is PUSH_PROMISE) by issuing - * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. In this case, + * Returning + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will + * close the stream (promised stream if frame is PUSH_PROMISE) by + * issuing RST_STREAM with + * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. In this case, * :type:`nghttp2_on_header_callback` and * :type:`nghttp2_on_frame_recv_callback` will not be invoked. If a * different error code is desirable, use * `nghttp2_submit_rst_stream()` with a desired error code and then - * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. Again, use - * ``frame->push_promise.promised_stream_id`` as stream_id parameter - * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE. + * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. + * Again, use ``frame->push_promise.promised_stream_id`` as stream_id + * parameter in `nghttp2_submit_rst_stream()` if frame is + * PUSH_PROMISE. * * The implementation of this function must return 0 if it succeeds. - * It can return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to + * It can return + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` to * reset the stream (promised stream if frame is PUSH_PROMISE). For * critical errors, it must return - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the other value is - * returned, it is treated as if :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` - * is returned. If :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned, + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other + * value is returned, it is treated as if + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned. If + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned, * `nghttp2_session_mem_recv()` function will immediately return - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_begin_headers_callback()`. @@ -1675,16 +1697,17 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session, * The |value| of length |valuelen| is header value. The |flags| is * bitwise OR of one or more of :type:`nghttp2_nv_flag`. * - * If :enum:`NGHTTP2_NV_FLAG_NO_INDEX` is set in |flags|, the receiver - * must not index this name/value pair when forwarding it to the next - * hop. More specifically, "Literal Header Field never Indexed" - * representation must be used in HPACK encoding. + * If :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_INDEX` is set in + * |flags|, the receiver must not index this name/value pair when + * forwarding it to the next hop. More specifically, "Literal Header + * Field never Indexed" representation must be used in HPACK encoding. * * When this callback is invoked, ``frame->hd.type`` is either - * :enum:`NGHTTP2_HEADERS` or :enum:`NGHTTP2_PUSH_PROMISE`. After all - * header name/value pairs are processed with this callback, and no - * error has been detected, :type:`nghttp2_on_frame_recv_callback` - * will be invoked. If there is an error in decompression, + * :enum:`nghttp2_frame_type.NGHTTP2_HEADERS` or + * :enum:`nghttp2_frame_type.NGHTTP2_PUSH_PROMISE`. After all header + * name/value pairs are processed with this callback, and no error has + * been detected, :type:`nghttp2_on_frame_recv_callback` will be + * invoked. If there is an error in decompression, * :type:`nghttp2_on_frame_recv_callback` for the |frame| will not be * invoked. * @@ -1702,34 +1725,39 @@ typedef int (*nghttp2_on_begin_headers_callback)(nghttp2_session *session, * explained in :ref:`http-messaging` section. * * If the application uses `nghttp2_session_mem_recv()`, it can return - * :enum:`NGHTTP2_ERR_PAUSE` to make `nghttp2_session_mem_recv()` - * return without processing further input bytes. The memory pointed - * by |frame|, |name| and |value| parameters are retained until - * `nghttp2_session_mem_recv()` or `nghttp2_session_recv()` is called. - * The application must retain the input bytes which was used to - * produce these parameters, because it may refer to the memory region - * included in the input bytes. - * - * Returning :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will close - * the stream (promised stream if frame is PUSH_PROMISE) by issuing - * RST_STREAM with :enum:`NGHTTP2_INTERNAL_ERROR`. In this case, + * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make + * `nghttp2_session_mem_recv()` return without processing further + * input bytes. The memory pointed by |frame|, |name| and |value| + * parameters are retained until `nghttp2_session_mem_recv()` or + * `nghttp2_session_recv()` is called. The application must retain + * the input bytes which was used to produce these parameters, because + * it may refer to the memory region included in the input bytes. + * + * Returning + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will + * close the stream (promised stream if frame is PUSH_PROMISE) by + * issuing RST_STREAM with + * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. In this case, * :type:`nghttp2_on_header_callback` and * :type:`nghttp2_on_frame_recv_callback` will not be invoked. If a * different error code is desirable, use * `nghttp2_submit_rst_stream()` with a desired error code and then - * return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. Again, use - * ``frame->push_promise.promised_stream_id`` as stream_id parameter - * in `nghttp2_submit_rst_stream()` if frame is PUSH_PROMISE. + * return :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. + * Again, use ``frame->push_promise.promised_stream_id`` as stream_id + * parameter in `nghttp2_submit_rst_stream()` if frame is + * PUSH_PROMISE. * * The implementation of this function must return 0 if it succeeds. - * It may return :enum:`NGHTTP2_ERR_PAUSE` or - * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. For other critical - * failures, it must return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If - * the other nonzero value is returned, it is treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned, + * It may return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` or + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. For + * other critical failures, it must return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other + * nonzero value is returned, it is treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned, * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_header_callback()`. @@ -1796,11 +1824,12 @@ typedef int (*nghttp2_on_header_callback2)(nghttp2_session *session, * * With this callback, application inspects the incoming invalid * field, and it also can reset stream from this callback by returning - * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the - * error code is :enum:`NGHTTP2_PROTOCOL_ERROR`. To change the error - * code, call `nghttp2_submit_rst_stream()` with the error code of - * choice in addition to returning - * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By + * default, the error code is + * :enum:`nghttp2_error_code.NGHTTP2_PROTOCOL_ERROR`. To change the + * error code, call `nghttp2_submit_rst_stream()` with the error code + * of choice in addition to returning + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. * * If 0 is returned, the header field is ignored, and the stream is * not reset. @@ -1831,11 +1860,12 @@ typedef int (*nghttp2_on_invalid_header_callback)( * * With this callback, application inspects the incoming invalid * field, and it also can reset stream from this callback by returning - * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By default, the - * error code is :enum:`NGHTTP2_INTERNAL_ERROR`. To change the error - * code, call `nghttp2_submit_rst_stream()` with the error code of - * choice in addition to returning - * :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. By + * default, the error code is + * :enum:`nghttp2_error_code.NGHTTP2_INTERNAL_ERROR`. To change the + * error code, call `nghttp2_submit_rst_stream()` with the error code + * of choice in addition to returning + * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`. */ typedef int (*nghttp2_on_invalid_header_callback2)( nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name, @@ -1849,11 +1879,12 @@ typedef int (*nghttp2_on_invalid_header_callback2)( * |frame|. The application must choose the total length of payload * including padded bytes in range [frame->hd.length, max_payloadlen], * inclusive. Choosing number not in this range will be treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Returning + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Returning * ``frame->hd.length`` means no padding is added. Returning - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will make + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_select_padding_callback()`. @@ -1873,16 +1904,17 @@ typedef ssize_t (*nghttp2_select_padding_callback)(nghttp2_session *session, * |remote_max_frame_size|)]. If a value greater than this range is * returned than the max allow value will be used. Returning a value * smaller than this range is treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. The |frame_type| is provided - * for future extensibility and identifies the type of frame (see - * :type:`nghttp2_frame_type`) for which to get the length for. - * Currently supported frame types are: :enum:`NGHTTP2_DATA`. + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. The + * |frame_type| is provided for future extensibility and identifies + * the type of frame (see :type:`nghttp2_frame_type`) for which to get + * the length for. Currently supported frame types are: + * :enum:`nghttp2_frame_type.NGHTTP2_DATA`. * * This callback can be used to control the length in bytes for which * :type:`nghttp2_data_source_read_callback` is allowed to send to the * remote endpoint. This callback is optional. Returning - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` will signal the entire session - * failure. + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will signal the + * entire session failure. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_data_source_read_length_callback()`. @@ -1909,7 +1941,8 @@ typedef ssize_t (*nghttp2_data_source_read_length_callback)( * The implementation of this function must return 0 if it succeeds. * If nonzero value is returned, it is treated as fatal error and * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. * * To set this callback to :type:`nghttp2_session_callbacks`, use * `nghttp2_session_callbacks_set_on_begin_frame_callback()`. @@ -1928,14 +1961,15 @@ typedef int (*nghttp2_on_begin_frame_callback)(nghttp2_session *session, * The implementation of this function must return 0 if it succeeds. * * To abort processing this extension frame, return - * :enum:`NGHTTP2_ERR_CANCEL`. + * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`. * * If fatal error occurred, application should return - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the - * other values are returned, currently they are treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other + * values are returned, currently they are treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. */ typedef int (*nghttp2_on_extension_chunk_recv_callback)( nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, @@ -1965,14 +1999,15 @@ typedef int (*nghttp2_on_extension_chunk_recv_callback)( * |*payload|, and do its own mechanism to process extension frames. * * To abort processing this extension frame, return - * :enum:`NGHTTP2_ERR_CANCEL`. + * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`. * * If fatal error occurred, application should return - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the - * other values are returned, currently they are treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other + * values are returned, currently they are treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. */ typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session, void **payload, @@ -1994,17 +2029,18 @@ typedef int (*nghttp2_unpack_extension_callback)(nghttp2_session *session, * bytes written into |buf| when it succeeds. * * To abort processing this extension frame, return - * :enum:`NGHTTP2_ERR_CANCEL`, and + * :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL`, and * :type:`nghttp2_on_frame_not_send_callback` will be invoked. * * If fatal error occurred, application should return - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions - * immediately return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the - * other values are returned, currently they are treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. If the return value is - * strictly larger than |len|, it is treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. + * immediately return + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the other + * values are returned, currently they are treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. If the return + * value is strictly larger than |len|, it is treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. */ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session, uint8_t *buf, size_t len, @@ -2029,12 +2065,12 @@ typedef ssize_t (*nghttp2_pack_extension_callback)(nghttp2_session *session, * * Normally, application should return 0 from this callback. If fatal * error occurred while doing something in this callback, application - * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * library will return immediately with return value - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if nonzero value - * is returned from this callback, they are treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not - * rely on this details. + * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. + * In this case, library will return immediately with return value + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if + * nonzero value is returned from this callback, they are treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application + * should not rely on this details. */ typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg, size_t len, void *user_data); @@ -2055,12 +2091,12 @@ typedef int (*nghttp2_error_callback)(nghttp2_session *session, const char *msg, * * Normally, application should return 0 from this callback. If fatal * error occurred while doing something in this callback, application - * should return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. In this case, - * library will return immediately with return value - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if nonzero value - * is returned from this callback, they are treated as - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, but application should not - * rely on this details. + * should return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. + * In this case, library will return immediately with return value + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`. Currently, if + * nonzero value is returned from this callback, they are treated as + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, but application + * should not rely on this details. */ typedef int (*nghttp2_error_callback2)(nghttp2_session *session, int lib_error_code, const char *msg, @@ -2090,7 +2126,7 @@ typedef struct nghttp2_session_callbacks nghttp2_session_callbacks; * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -2287,7 +2323,7 @@ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_begin_frame_callback( * @function * * Sets callback function invoked when - * :enum:`NGHTTP2_DATA_FLAG_NO_COPY` is used in + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in * :type:`nghttp2_data_source_read_callback` to avoid data copy. */ NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_data_callback( @@ -2470,7 +2506,7 @@ typedef struct nghttp2_option nghttp2_option; * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_option_new(nghttp2_option **option_ptr); @@ -2531,7 +2567,8 @@ nghttp2_option_set_peer_max_concurrent_streams(nghttp2_option *option, * If this option is not used or used with zero value, if MAGIC does * not match :macro:`NGHTTP2_CLIENT_MAGIC`, `nghttp2_session_recv()` * and `nghttp2_session_mem_recv()` will return error - * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal error. + * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal + * error. */ NGHTTP2_EXTERN void nghttp2_option_set_no_recv_client_magic(nghttp2_option *option, int val); @@ -2616,8 +2653,8 @@ nghttp2_option_set_builtin_recv_extension_type(nghttp2_option *option, * received. If this option is set to nonzero, the library won't send * PING frame with ACK flag set in the response for incoming PING * frame. The application can send PING frame with ACK flag set using - * `nghttp2_submit_ping()` with :enum:`NGHTTP2_FLAG_ACK` as flags - * parameter. + * `nghttp2_submit_ping()` with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` + * as flags parameter. */ NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, int val); @@ -2631,7 +2668,7 @@ NGHTTP2_EXTERN void nghttp2_option_set_no_auto_ping_ack(nghttp2_option *option, * `nghttp2_hd_deflate_bound()`. The default value is 64KiB. If * application attempts to send header fields larger than this limit, * the transmission of the frame fails with error code - * :enum:`NGHTTP2_ERR_FRAME_SIZE_ERROR`. + * :enum:`nghttp2_error.NGHTTP2_ERR_FRAME_SIZE_ERROR`. */ NGHTTP2_EXTERN void nghttp2_option_set_max_send_header_block_length(nghttp2_option *option, @@ -2700,7 +2737,7 @@ NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -2726,7 +2763,7 @@ nghttp2_session_client_new(nghttp2_session **session_ptr, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -2752,7 +2789,7 @@ nghttp2_session_server_new(nghttp2_session **session_ptr, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -2778,7 +2815,7 @@ nghttp2_session_client_new2(nghttp2_session **session_ptr, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -2804,7 +2841,7 @@ nghttp2_session_server_new2(nghttp2_session **session_ptr, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_client_new3( @@ -2829,7 +2866,7 @@ NGHTTP2_EXTERN int nghttp2_session_client_new3( * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_server_new3( @@ -2853,12 +2890,12 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session); * outbound queue and sends it to the remote peer. It does this as * many times as possible until the user callback * :type:`nghttp2_send_callback` returns - * :enum:`NGHTTP2_ERR_WOULDBLOCK`, the outbound queue becomes empty - * or flow control is triggered (remote window size becomes depleted - * or maximum number of concurrent streams is reached). - * This function calls several callback functions which are passed - * when initializing the |session|. Here is the simple time chart - * which tells when each callback is invoked: + * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue + * becomes empty or flow control is triggered (remote window size + * becomes depleted or maximum number of concurrent streams is + * reached). This function calls several callback functions which are + * passed when initializing the |session|. Here is the simple time + * chart which tells when each callback is invoked: * * 1. Get the next frame to send from outbound queue. * @@ -2876,7 +2913,7 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session); * * 6. :type:`nghttp2_before_frame_send_callback` is invoked. * - * 7. If :enum:`NGHTTP2_ERR_CANCEL` is returned from + * 7. If :enum:`nghttp2_error.NGHTTP2_ERR_CANCEL` is returned from * :type:`nghttp2_before_frame_send_callback`, the current frame * transmission is canceled, and * :type:`nghttp2_on_frame_not_send_callback` is invoked. Abort @@ -2894,9 +2931,9 @@ NGHTTP2_EXTERN void nghttp2_session_del(nghttp2_session *session); * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` * The callback function failed. */ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session); @@ -2928,7 +2965,7 @@ NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session); * |*data_ptr| if it succeeds, or one of the following negative error * codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. * * .. note:: @@ -2950,8 +2987,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session, * * This function receives as many frames as possible until the user * callback :type:`nghttp2_recv_callback` returns - * :enum:`NGHTTP2_ERR_WOULDBLOCK`. This function calls several - * callback functions which are passed when initializing the + * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`. This function calls + * several callback functions which are passed when initializing the * |session|. Here is the simple time chart which tells when each * callback is invoked: * @@ -2996,18 +3033,18 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_EOF` + * :enum:`nghttp2_error.NGHTTP2_ERR_EOF` * The remote peer did shutdown on the connection. - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` * The callback function failed. - * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC` + * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC` * Invalid client magic was detected. This error only returns * when |session| was configured as server and * `nghttp2_option_set_no_recv_client_magic()` is not used with * nonzero value. - * :enum:`NGHTTP2_ERR_FLOODED` + * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED` * Flooding was detected in this HTTP/2 session, and it must be * closed. This is most likely caused by misbehaviour of peer. */ @@ -3017,7 +3054,7 @@ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session); * @function * * Processes data |in| as an input from the remote endpoint. The - * |inlen| indicates the number of bytes in the |in|. + * |inlen| indicates the number of bytes to receive in the |in|. * * This function behaves like `nghttp2_session_recv()` except that it * does not use :type:`nghttp2_recv_callback` to receive data; the @@ -3026,27 +3063,27 @@ NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session); * are called in the same way as they are in `nghttp2_session_recv()`. * * In the current implementation, this function always tries to - * processes all input data unless either an error occurs or - * :enum:`NGHTTP2_ERR_PAUSE` is returned from + * processes |inlen| bytes of input data unless either an error occurs or + * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from * :type:`nghttp2_on_header_callback` or * :type:`nghttp2_on_data_chunk_recv_callback`. If - * :enum:`NGHTTP2_ERR_PAUSE` is used, the return value includes the - * number of bytes which was used to produce the data or frame for the - * callback. + * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is used, the return value + * includes the number of bytes which was used to produce the data or + * frame for the callback. * * This function returns the number of processed bytes, or one of the * following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` + * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` * The callback function failed. - * :enum:`NGHTTP2_ERR_BAD_CLIENT_MAGIC` + * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC` * Invalid client magic was detected. This error only returns * when |session| was configured as server and * `nghttp2_option_set_no_recv_client_magic()` is not used with * nonzero value. - * :enum:`NGHTTP2_ERR_FLOODED` + * :enum:`nghttp2_error.NGHTTP2_ERR_FLOODED` * Flooding was detected in this HTTP/2 session, and it must be * closed. This is most likely caused by misbehaviour of peer. */ @@ -3063,9 +3100,9 @@ NGHTTP2_EXTERN ssize_t nghttp2_session_mem_recv(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The stream does not exist; or no deferred data exist. - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_resume_data(nghttp2_session *session, @@ -3126,7 +3163,7 @@ nghttp2_session_get_stream_user_data(nghttp2_session *session, * This function returns 0 if it succeeds, or one of following * negative error codes: * - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The stream does not exist */ NGHTTP2_EXTERN int @@ -3343,7 +3380,7 @@ nghttp2_session_get_hd_deflate_dynamic_table_size(nghttp2_session *session); * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session, @@ -3370,9 +3407,9 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |last_stream_id| is invalid. */ NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session, @@ -3387,7 +3424,7 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session, * * This function is only usable for server. If this function is * called with client side session, this function returns - * :enum:`NGHTTP2_ERR_INVALID_STATE`. + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. * * To gracefully shutdown HTTP/2 session, server should call this * function to send GOAWAY with last_stream_id (1u << 31) - 1. And @@ -3409,9 +3446,9 @@ NGHTTP2_EXTERN int nghttp2_session_terminate_session2(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * The |session| is initialized as client. */ NGHTTP2_EXTERN int nghttp2_submit_shutdown_notice(nghttp2_session *session); @@ -3446,7 +3483,7 @@ NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings( * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |next_stream_id| is strictly less than the value * `nghttp2_session_get_next_stream_id()` returns; or * |next_stream_id| is invalid (e.g., even integer for client, or @@ -3481,11 +3518,11 @@ nghttp2_session_get_next_stream_id(nghttp2_session *session); * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0. - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * Automatic WINDOW_UPDATE is not disabled. */ NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session, @@ -3502,9 +3539,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * Automatic WINDOW_UPDATE is not disabled. */ NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session, @@ -3521,11 +3558,11 @@ NGHTTP2_EXTERN int nghttp2_session_consume_connection(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0. - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * Automatic WINDOW_UPDATE is not disabled. */ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session, @@ -3555,9 +3592,9 @@ NGHTTP2_EXTERN int nghttp2_session_consume_stream(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * Attempted to depend on itself; or no stream exist for the given * |stream_id|; or |stream_id| is 0 */ @@ -3598,9 +3635,9 @@ nghttp2_session_change_stream_priority(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * Attempted to depend on itself; or stream denoted by |stream_id| * already exists; or |stream_id| cannot be used to create idle * stream (in other words, local endpoint has already opened @@ -3651,11 +3688,11 @@ nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |settings_payload| is badly formed. - * :enum:`NGHTTP2_ERR_PROTO` + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` * The stream ID 1 is already used or closed; or is not available. */ NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session, @@ -3695,11 +3732,11 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |settings_payload| is badly formed. - * :enum:`NGHTTP2_ERR_PROTO` + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` * The stream ID 1 is already used or closed; or is not available. */ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session, @@ -3723,10 +3760,10 @@ NGHTTP2_EXTERN int nghttp2_session_upgrade2(nghttp2_session *session, * This function returns the number of bytes written in |buf|, or one * of the following negative error codes: * - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |iv| contains duplicate settings ID or invalid value. * - * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` * The provided |buflen| size is too small to hold the output. */ NGHTTP2_EXTERN ssize_t nghttp2_pack_settings_payload( @@ -3757,8 +3794,8 @@ NGHTTP2_EXTERN const char *nghttp2_http2_strerror(uint32_t error_code); * on with |weight| and its exclusive flag. If |exclusive| is * nonzero, exclusive flag is set. * - * The |weight| must be in [:enum:`NGHTTP2_MIN_WEIGHT`, - * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. + * The |weight| must be in [:macro:`NGHTTP2_MIN_WEIGHT`, + * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. */ NGHTTP2_EXTERN void nghttp2_priority_spec_init(nghttp2_priority_spec *pri_spec, int32_t stream_id, @@ -3793,11 +3830,12 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``, * this function will copy its data members. * - * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`, - * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` is - * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes - * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than - * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`. + * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, + * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` + * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes + * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than + * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes + * :macro:`NGHTTP2_MAX_WEIGHT`. * * The |nva| is an array of name/value pair :type:`nghttp2_nv` with * |nvlen| elements. The application is responsible to include @@ -3808,12 +3846,12 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); * This function creates copies of all name/value pairs in |nva|. It * also lower-cases all names in |nva|. The order of elements in * |nva| is preserved. For header fields with - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name - * and value are not copied respectively. With - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to - * pass header field name in lowercase. The application should - * maintain the references to them until + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, + * header field name and value are not copied respectively. With + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application + * is responsible to pass header field name in lowercase. The + * application should maintain the references to them until * :type:`nghttp2_on_frame_send_callback` or * :type:`nghttp2_on_frame_not_send_callback` is called. * @@ -3835,15 +3873,15 @@ nghttp2_priority_spec_check_default(const nghttp2_priority_spec *pri_spec); * This function returns assigned stream ID if it succeeds, or one of * the following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` * No stream ID is available because maximum stream ID was * reached. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * Trying to depend on itself (new stream ID equals * ``pri_spec->stream_id``). - * :enum:`NGHTTP2_ERR_PROTO` + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` * The |session| is server session. * * .. warning:: @@ -3878,12 +3916,12 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request( * This function creates copies of all name/value pairs in |nva|. It * also lower-cases all names in |nva|. The order of elements in * |nva| is preserved. For header fields with - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name - * and value are not copied respectively. With - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to - * pass header field name in lowercase. The application should - * maintain the references to them until + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, + * header field name and value are not copied respectively. With + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application + * is responsible to pass header field name in lowercase. The + * application should maintain the references to them until * :type:`nghttp2_on_frame_send_callback` or * :type:`nghttp2_on_frame_not_send_callback` is called. * @@ -3909,16 +3947,16 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_request( * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0. - * :enum:`NGHTTP2_ERR_DATA_EXIST` + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` * DATA or HEADERS has been already submitted and not fully * processed yet. Normally, this does not happen, but when * application wrongly calls `nghttp2_submit_response()` twice, * this may happen. - * :enum:`NGHTTP2_ERR_PROTO` + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` * The |session| is client session. * * .. warning:: @@ -3944,12 +3982,12 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, * This function creates copies of all name/value pairs in |nva|. It * also lower-cases all names in |nva|. The order of elements in * |nva| is preserved. For header fields with - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name - * and value are not copied respectively. With - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to - * pass header field name in lowercase. The application should - * maintain the references to them until + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, + * header field name and value are not copied respectively. With + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application + * is responsible to pass header field name in lowercase. The + * application should maintain the references to them until * :type:`nghttp2_on_frame_send_callback` or * :type:`nghttp2_on_frame_not_send_callback` is called. * @@ -3961,16 +3999,16 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, * |nva| will be sent as response headers, which will result in error. * * This function has the same effect with `nghttp2_submit_headers()`, - * with flags = :enum:`NGHTTP2_FLAG_END_STREAM` and both pri_spec and - * stream_user_data to NULL. + * with flags = :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` and both + * pri_spec and stream_user_data to NULL. * * To submit trailer fields after `nghttp2_submit_response()` is * called, the application has to specify * :type:`nghttp2_data_provider` to `nghttp2_submit_response()`. * Inside of :type:`nghttp2_data_source_read_callback`, when setting - * :enum:`NGHTTP2_DATA_FLAG_EOF`, also set - * :enum:`NGHTTP2_DATA_FLAG_NO_END_STREAM`. After that, the - * application can send trailer fields using + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set + * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_END_STREAM`. After + * that, the application can send trailer fields using * `nghttp2_submit_trailer()`. `nghttp2_submit_trailer()` can be used * inside :type:`nghttp2_data_source_read_callback`. * @@ -3978,9 +4016,9 @@ nghttp2_submit_response(nghttp2_session *session, int32_t stream_id, * Otherwise, this function returns 0 if it succeeds, or one of the * following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0. */ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, @@ -3993,10 +4031,10 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, * Submits HEADERS frame. The |flags| is bitwise OR of the * following values: * - * * :enum:`NGHTTP2_FLAG_END_STREAM` + * * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` * - * If |flags| includes :enum:`NGHTTP2_FLAG_END_STREAM`, this frame has - * END_STREAM flag set. + * If |flags| includes :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, + * this frame has END_STREAM flag set. * * The library handles the CONTINUATION frame internally and it * correctly sets END_HEADERS to the last sequence of the PUSH_PROMISE @@ -4013,11 +4051,11 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, * use `nghttp2_priority_spec_init()`. If |pri_spec| is not ``NULL``, * this function will copy its data members. * - * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`, - * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` is - * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes - * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than - * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`. + * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, + * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` + * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes + * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than + * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`. * * The |nva| is an array of name/value pair :type:`nghttp2_nv` with * |nvlen| elements. The application is responsible to include @@ -4028,12 +4066,12 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, * This function creates copies of all name/value pairs in |nva|. It * also lower-cases all names in |nva|. The order of elements in * |nva| is preserved. For header fields with - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name - * and value are not copied respectively. With - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to - * pass header field name in lowercase. The application should - * maintain the references to them until + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, + * header field name and value are not copied respectively. With + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application + * is responsible to pass header field name in lowercase. The + * application should maintain the references to them until * :type:`nghttp2_on_frame_send_callback` or * :type:`nghttp2_on_frame_not_send_callback` is called. * @@ -4051,19 +4089,19 @@ NGHTTP2_EXTERN int nghttp2_submit_trailer(nghttp2_session *session, * |stream_id| is -1. Otherwise, this function returns 0 if it * succeeds, or one of the following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` * No stream ID is available because maximum stream ID was * reached. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0; or trying to depend on itself (stream ID * equals ``pri_spec->stream_id``). - * :enum:`NGHTTP2_ERR_DATA_EXIST` + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` * DATA or HEADERS has been already submitted and not fully * processed yet. This happens if stream denoted by |stream_id| * is in reserved state. - * :enum:`NGHTTP2_ERR_PROTO` + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` * The |stream_id| is -1, and |session| is server session. * * .. warning:: @@ -4085,8 +4123,8 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_headers( * * Submits one or more DATA frames to the stream |stream_id|. The * data to be sent are provided by |data_prd|. If |flags| contains - * :enum:`NGHTTP2_FLAG_END_STREAM`, the last DATA frame has END_STREAM - * flag set. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM`, the last DATA frame + * has END_STREAM flag set. * * This function does not take ownership of the |data_prd|. The * function copies the members of the |data_prd|. @@ -4094,27 +4132,28 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_headers( * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_DATA_EXIST` + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` * DATA or HEADERS has been already submitted and not fully * processed yet. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0. - * :enum:`NGHTTP2_ERR_STREAM_CLOSED` + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED` * The stream was already closed; or the |stream_id| is invalid. * * .. note:: * * Currently, only one DATA or HEADERS is allowed for a stream at a * time. Submitting these frames more than once before first DATA - * or HEADERS is finished results in :enum:`NGHTTP2_ERR_DATA_EXIST` - * error code. The earliest callback which tells that previous - * frame is done is :type:`nghttp2_on_frame_send_callback`. In side - * that callback, new data can be submitted using - * `nghttp2_submit_data()`. Of course, all data except for last one - * must not have :enum:`NGHTTP2_FLAG_END_STREAM` flag set in - * |flags|. This sounds a bit complicated, and we recommend to use + * or HEADERS is finished results in + * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST` error code. The + * earliest callback which tells that previous frame is done is + * :type:`nghttp2_on_frame_send_callback`. In side that callback, + * new data can be submitted using `nghttp2_submit_data()`. Of + * course, all data except for last one must not have + * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|. + * This sounds a bit complicated, and we recommend to use * `nghttp2_submit_request()` and `nghttp2_submit_response()` to * avoid this cascading issue. The experience shows that for HTTP * use, these two functions are enough to implement both client and @@ -4131,25 +4170,26 @@ NGHTTP2_EXTERN int nghttp2_submit_data(nghttp2_session *session, uint8_t flags, * to the priority specification |pri_spec|. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * The |pri_spec| is priority specification of this request. ``NULL`` * is not allowed for this function. To specify the priority, use * `nghttp2_priority_spec_init()`. This function will copy its data * members. * - * The ``pri_spec->weight`` must be in [:enum:`NGHTTP2_MIN_WEIGHT`, - * :enum:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` is - * strictly less than :enum:`NGHTTP2_MIN_WEIGHT`, it becomes - * :enum:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than - * :enum:`NGHTTP2_MAX_WEIGHT`, it becomes :enum:`NGHTTP2_MAX_WEIGHT`. + * The ``pri_spec->weight`` must be in [:macro:`NGHTTP2_MIN_WEIGHT`, + * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive. If ``pri_spec->weight`` + * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes + * :macro:`NGHTTP2_MIN_WEIGHT`. If it is strictly greater than + * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes + * :macro:`NGHTTP2_MAX_WEIGHT`. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0; or the |pri_spec| is NULL; or trying to * depend on itself. */ @@ -4167,14 +4207,14 @@ nghttp2_submit_priority(nghttp2_session *session, uint8_t flags, * The pre-defined error code is one of :enum:`nghttp2_error_code`. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0. */ NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session, @@ -4189,7 +4229,7 @@ NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session, * indicates the number of :type:`nghttp2_settings_entry`. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * This function does not take ownership of the |iv|. This function * copies all the elements in the |iv|. @@ -4198,16 +4238,17 @@ NGHTTP2_EXTERN int nghttp2_submit_rst_stream(nghttp2_session *session, * size becomes strictly larger than NGHTTP2_MAX_WINDOW_SIZE, * RST_STREAM is issued against such a stream. * - * SETTINGS with :enum:`NGHTTP2_FLAG_ACK` is automatically submitted - * by the library and application could not send it at its will. + * SETTINGS with :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` is + * automatically submitted by the library and application could not + * send it at its will. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |iv| contains invalid value (e.g., initial window size * strictly greater than (1 << 31) - 1. - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session, @@ -4235,12 +4276,12 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session, * This function creates copies of all name/value pairs in |nva|. It * also lower-cases all names in |nva|. The order of elements in * |nva| is preserved. For header fields with - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME` and - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, header field name - * and value are not copied respectively. With - * :enum:`NGHTTP2_NV_FLAG_NO_COPY_NAME`, application is responsible to - * pass header field name in lowercase. The application should - * maintain the references to them until + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME` and + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set, + * header field name and value are not copied respectively. With + * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_NAME`, application + * is responsible to pass header field name in lowercase. The + * application should maintain the references to them until * :type:`nghttp2_on_frame_send_callback` or * :type:`nghttp2_on_frame_not_send_callback` is called. * @@ -4259,18 +4300,18 @@ NGHTTP2_EXTERN int nghttp2_submit_settings(nghttp2_session *session, * This function returns assigned promised stream ID if it succeeds, * or one of the following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_PROTO` + * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO` * This function was invoked when |session| is initialized as * client. - * :enum:`NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE` * No stream ID is available because maximum stream ID was * reached. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is 0; The |stream_id| does not designate stream * that peer initiated. - * :enum:`NGHTTP2_ERR_STREAM_CLOSED` + * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_CLOSED` * The stream was already closed; or the |stream_id| is invalid. * * .. warning:: @@ -4299,10 +4340,10 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise( * * The |flags| is bitwise OR of 0 or more of the following value. * - * * :enum:`NGHTTP2_FLAG_ACK` + * * :enum:`nghttp2_flag.NGHTTP2_FLAG_ACK` * * Unless `nghttp2_option_set_no_auto_ping_ack()` is used, the |flags| - * should be :enum:`NGHTTP2_FLAG_NONE`. + * should be :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * If the |opaque_data| is non ``NULL``, then it should point to the 8 * bytes array of memory to specify opaque data to send with PING @@ -4312,7 +4353,7 @@ NGHTTP2_EXTERN int32_t nghttp2_submit_push_promise( * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, @@ -4327,7 +4368,7 @@ NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, * The pre-defined error code is one of :enum:`nghttp2_error_code`. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * The |last_stream_id| is peer's stream ID or 0. So if |session| is * initialized as client, |last_stream_id| must be even or 0. If @@ -4357,9 +4398,9 @@ NGHTTP2_EXTERN int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |opaque_data_len| is too large; the |last_stream_id| is * invalid. */ @@ -4415,7 +4456,7 @@ nghttp2_session_check_server_session(nghttp2_session *session); * Submits WINDOW_UPDATE frame. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * The |stream_id| is the stream ID to send this WINDOW_UPDATE. To * send connection level WINDOW_UPDATE, specify 0 to |stream_id|. @@ -4442,9 +4483,9 @@ nghttp2_session_check_server_session(nghttp2_session *session); * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_FLOW_CONTROL` + * :enum:`nghttp2_error.NGHTTP2_ERR_FLOW_CONTROL` * The local window size overflow or gets negative. - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session, @@ -4462,7 +4503,7 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session, * to transmission queue. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * This sounds similar to `nghttp2_submit_window_update()`, but there * are 2 differences. The first difference is that this function @@ -4481,9 +4522,9 @@ NGHTTP2_EXTERN int nghttp2_submit_window_update(nghttp2_session *session, * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The |stream_id| is negative. - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -4514,18 +4555,19 @@ nghttp2_session_set_local_window_size(nghttp2_session *session, uint8_t flags, * * The standard HTTP/2 frame cannot be sent with this function, so * |type| must be strictly grater than 0x9. Otherwise, this function - * will fail with error code :enum:`NGHTTP2_ERR_INVALID_ARGUMENT`. + * will fail with error code + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * If :type:`nghttp2_pack_extension_callback` is not set. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * If |type| specifies standard HTTP/2 frame type. The frame * types in the rage [0x0, 0x9], both inclusive, are standard * HTTP/2 frame type, and cannot be sent using this function. - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory */ NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session, @@ -4539,8 +4581,8 @@ NGHTTP2_EXTERN int nghttp2_submit_extension(nghttp2_session *session, * extension to HTTP/2. If this frame is received, and * `nghttp2_option_set_user_recv_extension_type()` is not set, and * `nghttp2_option_set_builtin_recv_extension_type()` is set for - * :enum:`NGHTTP2_ALTSVC`, ``nghttp2_extension.payload`` will point to - * this struct. + * :enum:`nghttp2_frame_type.NGHTTP2_ALTSVC`, + * ``nghttp2_extension.payload`` will point to this struct. * * It has the following members: */ @@ -4574,7 +4616,7 @@ typedef struct { * `RFC 7383 `_. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * The |origin| points to the origin this alternative service is * associated with. The |origin_len| is the length of the origin. If @@ -4584,16 +4626,16 @@ typedef struct { * * The ALTSVC frame is only usable from server side. If this function * is invoked with client side session, this function returns - * :enum:`NGHTTP2_ERR_INVALID_STATE`. + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * The function is called from client side session - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * The sum of |origin_len| and |field_value_len| is larger than * 16382; or |origin_len| is 0 while |stream_id| is 0; or * |origin_len| is not 0 while |stream_id| is not 0. @@ -4632,8 +4674,8 @@ typedef struct { * If this frame is received, and * `nghttp2_option_set_user_recv_extension_type()` is not set, and * `nghttp2_option_set_builtin_recv_extension_type()` is set for - * :enum:`NGHTTP2_ORIGIN`, ``nghttp2_extension.payload`` will point to - * this struct. + * :enum:`nghttp2_frame_type.NGHTTP2_ORIGIN`, + * ``nghttp2_extension.payload`` will point to this struct. * * It has the following members: */ @@ -4657,7 +4699,7 @@ typedef struct { * `RFC 8336 `_. * * The |flags| is currently ignored and should be - * :enum:`NGHTTP2_FLAG_NONE`. + * :enum:`nghttp2_flag.NGHTTP2_FLAG_NONE`. * * The |ov| points to the array of origins. The |nov| specifies the * number of origins included in |ov|. This function creates copies @@ -4665,13 +4707,13 @@ typedef struct { * * The ORIGIN frame is only usable by a server. If this function is * invoked with client side session, this function returns - * :enum:`NGHTTP2_ERR_INVALID_STATE`. + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`. * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * The function is called from client side session. - * :enum:`NGHTTP2_ERR_INVALID_ARGUMENT` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT` * There are too many origins, or an origin is too large to fit * into a default frame payload. */ @@ -4797,7 +4839,31 @@ NGHTTP2_EXTERN int nghttp2_check_header_value(const uint8_t *value, size_t len); /** * @function * - * Returns nonzero if the |value| which is supposed to the value of + * Returns nonzero if the |value| which is supposed to be the value of + * the :method header field is valid according to + * https://datatracker.ietf.org/doc/html/rfc7231#section-4 and + * https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6 + */ +NGHTTP2_EXTERN int nghttp2_check_method(const uint8_t *value, size_t len); + +/** + * @function + * + * Returns nonzero if the |value| which is supposed to be the value of + * the :path header field is valid according to + * https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.3 + * + * |value| is valid if it merely consists of the allowed characters. + * In particular, it does not check whether |value| follows the syntax + * of path. The allowed characters are all characters valid by + * `nghttp2_check_header_value` minus SPC and HT. + */ +NGHTTP2_EXTERN int nghttp2_check_path(const uint8_t *value, size_t len); + +/** + * @function + * + * Returns nonzero if the |value| which is supposed to be the value of the * :authority or host header field is valid according to * https://tools.ietf.org/html/rfc3986#section-3.2 * @@ -4831,7 +4897,7 @@ typedef struct nghttp2_hd_deflater nghttp2_hd_deflater; * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -4885,7 +4951,7 @@ NGHTTP2_EXTERN void nghttp2_hd_deflate_del(nghttp2_hd_deflater *deflater); * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int @@ -4899,24 +4965,24 @@ nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater, * the |buf| of length |buflen|. * * If |buf| is not large enough to store the deflated header block, - * this function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The - * caller should use `nghttp2_hd_deflate_bound()` to know the upper - * bound of buffer size required to deflate given header name/value - * pairs. + * this function fails with + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller + * should use `nghttp2_hd_deflate_bound()` to know the upper bound of + * buffer size required to deflate given header name/value pairs. * * Once this function fails, subsequent call of this function always - * returns :enum:`NGHTTP2_ERR_HEADER_COMP`. + * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. * * After this function returns, it is safe to delete the |nva|. * * This function returns the number of bytes written to |buf| if it * succeeds, or one of the following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_HEADER_COMP` + * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` * Deflation process has failed. - * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` * The provided |buflen| size is too small to hold the output. */ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, @@ -4932,23 +4998,24 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, * must be set in len field of :type:`nghttp2_vec`. If and only if * one chunk is filled up completely, next chunk will be used. If * |vec| is not large enough to store the deflated header block, this - * function fails with :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller + * function fails with + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`. The caller * should use `nghttp2_hd_deflate_bound()` to know the upper bound of * buffer size required to deflate given header name/value pairs. * * Once this function fails, subsequent call of this function always - * returns :enum:`NGHTTP2_ERR_HEADER_COMP`. + * returns :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`. * * After this function returns, it is safe to delete the |nva|. * * This function returns the number of bytes written to |vec| if it * succeeds, or one of the following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_HEADER_COMP` + * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` * Deflation process has failed. - * :enum:`NGHTTP2_ERR_INSUFF_BUFSIZE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE` * The provided |buflen| size is too small to hold the output. */ NGHTTP2_EXTERN ssize_t nghttp2_hd_deflate_hd_vec(nghttp2_hd_deflater *deflater, @@ -5028,7 +5095,7 @@ typedef struct nghttp2_hd_inflater nghttp2_hd_inflater; * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. */ NGHTTP2_EXTERN int nghttp2_hd_inflate_new(nghttp2_hd_inflater **inflater_ptr); @@ -5077,9 +5144,9 @@ NGHTTP2_EXTERN void nghttp2_hd_inflate_del(nghttp2_hd_inflater *inflater); * This function returns 0 if it succeeds, or one of the following * negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_INVALID_STATE` + * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE` * The function is called while header block is being inflated. * Probably, application missed to call * `nghttp2_hd_inflate_end_headers()`. @@ -5117,7 +5184,8 @@ typedef enum { * * Inflates name/value block stored in |in| with length |inlen|. This * function performs decompression. For each successful emission of - * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in + * header name/value pair, + * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in * |*inflate_flags| and name/value pair is assigned to the |nv_out| * and the function returns. The caller must not free the members of * |nv_out|. @@ -5140,11 +5208,11 @@ typedef enum { * This function returns the number of bytes processed if it succeeds, * or one of the following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_HEADER_COMP` + * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` * Inflation process has failed. - * :enum:`NGHTTP2_ERR_BUFFER_ERROR` + * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR` * The header field name or value is too large. * * Example follows:: @@ -5199,7 +5267,8 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, * * Inflates name/value block stored in |in| with length |inlen|. This * function performs decompression. For each successful emission of - * header name/value pair, :enum:`NGHTTP2_HD_INFLATE_EMIT` is set in + * header name/value pair, + * :enum:`nghttp2_hd_inflate_flag.NGHTTP2_HD_INFLATE_EMIT` is set in * |*inflate_flags| and name/value pair is assigned to the |nv_out| * and the function returns. The caller must not free the members of * |nv_out|. @@ -5215,8 +5284,9 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, * for the next header block input. * * In other words, if |in_final| is nonzero, and this function returns - * |inlen|, you can assert that :enum:`NGHTTP2_HD_INFLATE_FINAL` is - * set in |*inflate_flags|. + * |inlen|, you can assert that + * :enum:`nghttp2_hd_inflate_final.NGHTTP2_HD_INFLATE_FINAL` is set in + * |*inflate_flags|. * * The caller can feed complete compressed header block. It also can * feed it in several chunks. The caller must set |in_final| to @@ -5226,11 +5296,11 @@ NGHTTP2_EXTERN ssize_t nghttp2_hd_inflate_hd(nghttp2_hd_inflater *inflater, * This function returns the number of bytes processed if it succeeds, * or one of the following negative error codes: * - * :enum:`NGHTTP2_ERR_NOMEM` + * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM` * Out of memory. - * :enum:`NGHTTP2_ERR_HEADER_COMP` + * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP` * Inflation process has failed. - * :enum:`NGHTTP2_ERR_BUFFER_ERROR` + * :enum:`nghttp2_error.NGHTTP2_ERR_BUFFER_ERROR` * The header field name or value is too large. * * Example follows:: @@ -5401,7 +5471,7 @@ typedef enum { * * Returns state of |stream|. The root stream retrieved by * `nghttp2_session_get_root_stream()` will have stream state - * :enum:`NGHTTP2_STREAM_STATE_IDLE`. + * :enum:`nghttp2_stream_proto_state.NGHTTP2_STREAM_STATE_IDLE`. */ NGHTTP2_EXTERN nghttp2_stream_proto_state nghttp2_stream_get_state(nghttp2_stream *stream); diff --git a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h index ff6bf3d3b22e4f..5f2454cfd7cbbb 100644 --- a/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h +++ b/deps/nghttp2/lib/includes/nghttp2/nghttp2ver.h @@ -29,7 +29,7 @@ * @macro * Version number of the nghttp2 library release */ -#define NGHTTP2_VERSION "1.42.0" +#define NGHTTP2_VERSION "1.45.1" /** * @macro @@ -37,6 +37,6 @@ * release. This is a 24 bit number with 8 bits for major number, 8 bits * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203. */ -#define NGHTTP2_VERSION_NUM 0x012a00 +#define NGHTTP2_VERSION_NUM 0x012d01 #endif /* NGHTTP2VER_H */ diff --git a/deps/nghttp2/lib/nghttp2_frame.h b/deps/nghttp2/lib/nghttp2_frame.h index 615bbf31f5d60d..4b9222ac6dd685 100644 --- a/deps/nghttp2/lib/nghttp2_frame.h +++ b/deps/nghttp2/lib/nghttp2_frame.h @@ -57,7 +57,7 @@ /* Maximum headers block size to send, calculated using nghttp2_hd_deflate_bound(). This is the default value, and can be - overridden by nghttp2_option_set_max_send_header_block_size(). */ + overridden by nghttp2_option_set_max_send_header_block_length(). */ #define NGHTTP2_MAX_HEADERSLEN 65536 /* The number of bytes for each SETTINGS entry */ diff --git a/deps/nghttp2/lib/nghttp2_helper.c b/deps/nghttp2/lib/nghttp2_helper.c index 0bd5414723d736..588e269c3449fd 100644 --- a/deps/nghttp2/lib/nghttp2_helper.c +++ b/deps/nghttp2/lib/nghttp2_helper.c @@ -507,7 +507,166 @@ int nghttp2_check_header_value(const uint8_t *value, size_t len) { return 1; } -/* Generated by genauthroitychartbl.py */ +/* Generated by genmethodchartbl.py */ +static char VALID_METHOD_CHARS[] = { + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 0 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 0 /* ( */, 0 /* ) */, 1 /* * */, 1 /* + */, + 0 /* , */, 1 /* - */, 1 /* . */, 0 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 0 /* : */, 0 /* ; */, + 0 /* < */, 0 /* = */, 0 /* > */, 0 /* ? */, + 0 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 0 /* [ */, + 0 /* \ */, 0 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 0 /* { */, + 1 /* | */, 0 /* } */, 1 /* ~ */, 0 /* DEL */, + 0 /* 0x80 */, 0 /* 0x81 */, 0 /* 0x82 */, 0 /* 0x83 */, + 0 /* 0x84 */, 0 /* 0x85 */, 0 /* 0x86 */, 0 /* 0x87 */, + 0 /* 0x88 */, 0 /* 0x89 */, 0 /* 0x8a */, 0 /* 0x8b */, + 0 /* 0x8c */, 0 /* 0x8d */, 0 /* 0x8e */, 0 /* 0x8f */, + 0 /* 0x90 */, 0 /* 0x91 */, 0 /* 0x92 */, 0 /* 0x93 */, + 0 /* 0x94 */, 0 /* 0x95 */, 0 /* 0x96 */, 0 /* 0x97 */, + 0 /* 0x98 */, 0 /* 0x99 */, 0 /* 0x9a */, 0 /* 0x9b */, + 0 /* 0x9c */, 0 /* 0x9d */, 0 /* 0x9e */, 0 /* 0x9f */, + 0 /* 0xa0 */, 0 /* 0xa1 */, 0 /* 0xa2 */, 0 /* 0xa3 */, + 0 /* 0xa4 */, 0 /* 0xa5 */, 0 /* 0xa6 */, 0 /* 0xa7 */, + 0 /* 0xa8 */, 0 /* 0xa9 */, 0 /* 0xaa */, 0 /* 0xab */, + 0 /* 0xac */, 0 /* 0xad */, 0 /* 0xae */, 0 /* 0xaf */, + 0 /* 0xb0 */, 0 /* 0xb1 */, 0 /* 0xb2 */, 0 /* 0xb3 */, + 0 /* 0xb4 */, 0 /* 0xb5 */, 0 /* 0xb6 */, 0 /* 0xb7 */, + 0 /* 0xb8 */, 0 /* 0xb9 */, 0 /* 0xba */, 0 /* 0xbb */, + 0 /* 0xbc */, 0 /* 0xbd */, 0 /* 0xbe */, 0 /* 0xbf */, + 0 /* 0xc0 */, 0 /* 0xc1 */, 0 /* 0xc2 */, 0 /* 0xc3 */, + 0 /* 0xc4 */, 0 /* 0xc5 */, 0 /* 0xc6 */, 0 /* 0xc7 */, + 0 /* 0xc8 */, 0 /* 0xc9 */, 0 /* 0xca */, 0 /* 0xcb */, + 0 /* 0xcc */, 0 /* 0xcd */, 0 /* 0xce */, 0 /* 0xcf */, + 0 /* 0xd0 */, 0 /* 0xd1 */, 0 /* 0xd2 */, 0 /* 0xd3 */, + 0 /* 0xd4 */, 0 /* 0xd5 */, 0 /* 0xd6 */, 0 /* 0xd7 */, + 0 /* 0xd8 */, 0 /* 0xd9 */, 0 /* 0xda */, 0 /* 0xdb */, + 0 /* 0xdc */, 0 /* 0xdd */, 0 /* 0xde */, 0 /* 0xdf */, + 0 /* 0xe0 */, 0 /* 0xe1 */, 0 /* 0xe2 */, 0 /* 0xe3 */, + 0 /* 0xe4 */, 0 /* 0xe5 */, 0 /* 0xe6 */, 0 /* 0xe7 */, + 0 /* 0xe8 */, 0 /* 0xe9 */, 0 /* 0xea */, 0 /* 0xeb */, + 0 /* 0xec */, 0 /* 0xed */, 0 /* 0xee */, 0 /* 0xef */, + 0 /* 0xf0 */, 0 /* 0xf1 */, 0 /* 0xf2 */, 0 /* 0xf3 */, + 0 /* 0xf4 */, 0 /* 0xf5 */, 0 /* 0xf6 */, 0 /* 0xf7 */, + 0 /* 0xf8 */, 0 /* 0xf9 */, 0 /* 0xfa */, 0 /* 0xfb */, + 0 /* 0xfc */, 0 /* 0xfd */, 0 /* 0xfe */, 0 /* 0xff */ +}; + +int nghttp2_check_method(const uint8_t *value, size_t len) { + const uint8_t *last; + if (len == 0) { + return 0; + } + for (last = value + len; value != last; ++value) { + if (!VALID_METHOD_CHARS[*value]) { + return 0; + } + } + return 1; +} + +/* Generated by genpathchartbl.py */ +static char VALID_PATH_CHARS[] = { + 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, + 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, + 0 /* BS */, 0 /* HT */, 0 /* LF */, 0 /* VT */, + 0 /* FF */, 0 /* CR */, 0 /* SO */, 0 /* SI */, + 0 /* DLE */, 0 /* DC1 */, 0 /* DC2 */, 0 /* DC3 */, + 0 /* DC4 */, 0 /* NAK */, 0 /* SYN */, 0 /* ETB */, + 0 /* CAN */, 0 /* EM */, 0 /* SUB */, 0 /* ESC */, + 0 /* FS */, 0 /* GS */, 0 /* RS */, 0 /* US */, + 0 /* SPC */, 1 /* ! */, 1 /* " */, 1 /* # */, + 1 /* $ */, 1 /* % */, 1 /* & */, 1 /* ' */, + 1 /* ( */, 1 /* ) */, 1 /* * */, 1 /* + */, + 1 /* , */, 1 /* - */, 1 /* . */, 1 /* / */, + 1 /* 0 */, 1 /* 1 */, 1 /* 2 */, 1 /* 3 */, + 1 /* 4 */, 1 /* 5 */, 1 /* 6 */, 1 /* 7 */, + 1 /* 8 */, 1 /* 9 */, 1 /* : */, 1 /* ; */, + 1 /* < */, 1 /* = */, 1 /* > */, 1 /* ? */, + 1 /* @ */, 1 /* A */, 1 /* B */, 1 /* C */, + 1 /* D */, 1 /* E */, 1 /* F */, 1 /* G */, + 1 /* H */, 1 /* I */, 1 /* J */, 1 /* K */, + 1 /* L */, 1 /* M */, 1 /* N */, 1 /* O */, + 1 /* P */, 1 /* Q */, 1 /* R */, 1 /* S */, + 1 /* T */, 1 /* U */, 1 /* V */, 1 /* W */, + 1 /* X */, 1 /* Y */, 1 /* Z */, 1 /* [ */, + 1 /* \ */, 1 /* ] */, 1 /* ^ */, 1 /* _ */, + 1 /* ` */, 1 /* a */, 1 /* b */, 1 /* c */, + 1 /* d */, 1 /* e */, 1 /* f */, 1 /* g */, + 1 /* h */, 1 /* i */, 1 /* j */, 1 /* k */, + 1 /* l */, 1 /* m */, 1 /* n */, 1 /* o */, + 1 /* p */, 1 /* q */, 1 /* r */, 1 /* s */, + 1 /* t */, 1 /* u */, 1 /* v */, 1 /* w */, + 1 /* x */, 1 /* y */, 1 /* z */, 1 /* { */, + 1 /* | */, 1 /* } */, 1 /* ~ */, 0 /* DEL */, + 1 /* 0x80 */, 1 /* 0x81 */, 1 /* 0x82 */, 1 /* 0x83 */, + 1 /* 0x84 */, 1 /* 0x85 */, 1 /* 0x86 */, 1 /* 0x87 */, + 1 /* 0x88 */, 1 /* 0x89 */, 1 /* 0x8a */, 1 /* 0x8b */, + 1 /* 0x8c */, 1 /* 0x8d */, 1 /* 0x8e */, 1 /* 0x8f */, + 1 /* 0x90 */, 1 /* 0x91 */, 1 /* 0x92 */, 1 /* 0x93 */, + 1 /* 0x94 */, 1 /* 0x95 */, 1 /* 0x96 */, 1 /* 0x97 */, + 1 /* 0x98 */, 1 /* 0x99 */, 1 /* 0x9a */, 1 /* 0x9b */, + 1 /* 0x9c */, 1 /* 0x9d */, 1 /* 0x9e */, 1 /* 0x9f */, + 1 /* 0xa0 */, 1 /* 0xa1 */, 1 /* 0xa2 */, 1 /* 0xa3 */, + 1 /* 0xa4 */, 1 /* 0xa5 */, 1 /* 0xa6 */, 1 /* 0xa7 */, + 1 /* 0xa8 */, 1 /* 0xa9 */, 1 /* 0xaa */, 1 /* 0xab */, + 1 /* 0xac */, 1 /* 0xad */, 1 /* 0xae */, 1 /* 0xaf */, + 1 /* 0xb0 */, 1 /* 0xb1 */, 1 /* 0xb2 */, 1 /* 0xb3 */, + 1 /* 0xb4 */, 1 /* 0xb5 */, 1 /* 0xb6 */, 1 /* 0xb7 */, + 1 /* 0xb8 */, 1 /* 0xb9 */, 1 /* 0xba */, 1 /* 0xbb */, + 1 /* 0xbc */, 1 /* 0xbd */, 1 /* 0xbe */, 1 /* 0xbf */, + 1 /* 0xc0 */, 1 /* 0xc1 */, 1 /* 0xc2 */, 1 /* 0xc3 */, + 1 /* 0xc4 */, 1 /* 0xc5 */, 1 /* 0xc6 */, 1 /* 0xc7 */, + 1 /* 0xc8 */, 1 /* 0xc9 */, 1 /* 0xca */, 1 /* 0xcb */, + 1 /* 0xcc */, 1 /* 0xcd */, 1 /* 0xce */, 1 /* 0xcf */, + 1 /* 0xd0 */, 1 /* 0xd1 */, 1 /* 0xd2 */, 1 /* 0xd3 */, + 1 /* 0xd4 */, 1 /* 0xd5 */, 1 /* 0xd6 */, 1 /* 0xd7 */, + 1 /* 0xd8 */, 1 /* 0xd9 */, 1 /* 0xda */, 1 /* 0xdb */, + 1 /* 0xdc */, 1 /* 0xdd */, 1 /* 0xde */, 1 /* 0xdf */, + 1 /* 0xe0 */, 1 /* 0xe1 */, 1 /* 0xe2 */, 1 /* 0xe3 */, + 1 /* 0xe4 */, 1 /* 0xe5 */, 1 /* 0xe6 */, 1 /* 0xe7 */, + 1 /* 0xe8 */, 1 /* 0xe9 */, 1 /* 0xea */, 1 /* 0xeb */, + 1 /* 0xec */, 1 /* 0xed */, 1 /* 0xee */, 1 /* 0xef */, + 1 /* 0xf0 */, 1 /* 0xf1 */, 1 /* 0xf2 */, 1 /* 0xf3 */, + 1 /* 0xf4 */, 1 /* 0xf5 */, 1 /* 0xf6 */, 1 /* 0xf7 */, + 1 /* 0xf8 */, 1 /* 0xf9 */, 1 /* 0xfa */, 1 /* 0xfb */, + 1 /* 0xfc */, 1 /* 0xfd */, 1 /* 0xfe */, 1 /* 0xff */ +}; + +int nghttp2_check_path(const uint8_t *value, size_t len) { + const uint8_t *last; + for (last = value + len; value != last; ++value) { + if (!VALID_PATH_CHARS[*value]) { + return 0; + } + } + return 1; +} + +/* Generated by genauthoritychartbl.py */ static char VALID_AUTHORITY_CHARS[] = { 0 /* NUL */, 0 /* SOH */, 0 /* STX */, 0 /* ETX */, 0 /* EOT */, 0 /* ENQ */, 0 /* ACK */, 0 /* BEL */, diff --git a/deps/nghttp2/lib/nghttp2_http.c b/deps/nghttp2/lib/nghttp2_http.c index 62f57b6aec779c..a2bcd2c0a19333 100644 --- a/deps/nghttp2/lib/nghttp2_http.c +++ b/deps/nghttp2/lib/nghttp2_http.c @@ -360,12 +360,21 @@ int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream, return NGHTTP2_ERR_IGN_HTTP_HEADER; } - if (nv->token == NGHTTP2_TOKEN__AUTHORITY || - nv->token == NGHTTP2_TOKEN_HOST) { + switch (nv->token) { + case NGHTTP2_TOKEN__METHOD: + rv = nghttp2_check_method(nv->value->base, nv->value->len); + break; + case NGHTTP2_TOKEN__PATH: + rv = nghttp2_check_path(nv->value->base, nv->value->len); + break; + case NGHTTP2_TOKEN__AUTHORITY: + case NGHTTP2_TOKEN_HOST: rv = nghttp2_check_authority(nv->value->base, nv->value->len); - } else if (nv->token == NGHTTP2_TOKEN__SCHEME) { + break; + case NGHTTP2_TOKEN__SCHEME: rv = check_scheme(nv->value->base, nv->value->len); - } else { + break; + default: rv = nghttp2_check_header_value(nv->value->base, nv->value->len); } diff --git a/deps/nghttp2/lib/nghttp2_ksl.c b/deps/nghttp2/lib/nghttp2_ksl.c deleted file mode 100644 index dffd1cbcffc484..00000000000000 --- a/deps/nghttp2/lib/nghttp2_ksl.c +++ /dev/null @@ -1,707 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2020 nghttp2 contributors - * Copyright (c) 2018 ngtcp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#include "nghttp2_ksl.h" - -#include -#include -#include -#include - -#include "nghttp2_mem.h" - -static size_t ksl_nodelen(size_t keylen) { - return (sizeof(nghttp2_ksl_node) + keylen - sizeof(uint64_t) + 0xf) & - (size_t)~0xf; -} - -static size_t ksl_blklen(size_t nodelen) { - return sizeof(nghttp2_ksl_blk) + nodelen * NGHTTP2_KSL_MAX_NBLK - - sizeof(uint64_t); -} - -/* - * ksl_node_set_key sets |key| to |node|. - */ -static void ksl_node_set_key(nghttp2_ksl *ksl, nghttp2_ksl_node *node, - const void *key) { - memcpy(node->key, key, ksl->keylen); -} - -int nghttp2_ksl_init(nghttp2_ksl *ksl, nghttp2_ksl_compar compar, size_t keylen, - nghttp2_mem *mem) { - size_t nodelen = ksl_nodelen(keylen); - size_t blklen = ksl_blklen(nodelen); - nghttp2_ksl_blk *head; - - ksl->head = nghttp2_mem_malloc(mem, blklen); - if (!ksl->head) { - return NGHTTP2_ERR_NOMEM; - } - ksl->front = ksl->back = ksl->head; - ksl->compar = compar; - ksl->keylen = keylen; - ksl->nodelen = nodelen; - ksl->n = 0; - ksl->mem = mem; - - head = ksl->head; - head->next = head->prev = NULL; - head->n = 0; - head->leaf = 1; - - return 0; -} - -/* - * ksl_free_blk frees |blk| recursively. - */ -static void ksl_free_blk(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk) { - size_t i; - - if (!blk->leaf) { - for (i = 0; i < blk->n; ++i) { - ksl_free_blk(ksl, nghttp2_ksl_nth_node(ksl, blk, i)->blk); - } - } - - nghttp2_mem_free(ksl->mem, blk); -} - -void nghttp2_ksl_free(nghttp2_ksl *ksl) { - if (!ksl) { - return; - } - - ksl_free_blk(ksl, ksl->head); -} - -/* - * ksl_split_blk splits |blk| into 2 nghttp2_ksl_blk objects. The new - * nghttp2_ksl_blk is always the "right" block. - * - * It returns the pointer to the nghttp2_ksl_blk created which is the - * located at the right of |blk|, or NULL which indicates out of - * memory error. - */ -static nghttp2_ksl_blk *ksl_split_blk(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk) { - nghttp2_ksl_blk *rblk; - - rblk = nghttp2_mem_malloc(ksl->mem, ksl_blklen(ksl->nodelen)); - if (rblk == NULL) { - return NULL; - } - - rblk->next = blk->next; - blk->next = rblk; - if (rblk->next) { - rblk->next->prev = rblk; - } else if (ksl->back == blk) { - ksl->back = rblk; - } - rblk->prev = blk; - rblk->leaf = blk->leaf; - - rblk->n = blk->n / 2; - - memcpy(rblk->nodes, blk->nodes + ksl->nodelen * (blk->n - rblk->n), - ksl->nodelen * rblk->n); - - blk->n -= rblk->n; - - assert(blk->n >= NGHTTP2_KSL_MIN_NBLK); - assert(rblk->n >= NGHTTP2_KSL_MIN_NBLK); - - return rblk; -} - -/* - * ksl_split_node splits a node included in |blk| at the position |i| - * into 2 adjacent nodes. The new node is always inserted at the - * position |i+1|. - * - * It returns 0 if it succeeds, or one of the following negative error - * codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -static int ksl_split_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) { - nghttp2_ksl_node *node; - nghttp2_ksl_blk *lblk = nghttp2_ksl_nth_node(ksl, blk, i)->blk, *rblk; - - rblk = ksl_split_blk(ksl, lblk); - if (rblk == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - memmove(blk->nodes + (i + 2) * ksl->nodelen, - blk->nodes + (i + 1) * ksl->nodelen, - ksl->nodelen * (blk->n - (i + 1))); - - node = nghttp2_ksl_nth_node(ksl, blk, i + 1); - node->blk = rblk; - ++blk->n; - ksl_node_set_key(ksl, node, - nghttp2_ksl_nth_node(ksl, rblk, rblk->n - 1)->key); - - node = nghttp2_ksl_nth_node(ksl, blk, i); - ksl_node_set_key(ksl, node, - nghttp2_ksl_nth_node(ksl, lblk, lblk->n - 1)->key); - - return 0; -} - -/* - * ksl_split_head splits a head (root) block. It increases the height - * of skip list by 1. - * - * It returns 0 if it succeeds, or one of the following negative error - * codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -static int ksl_split_head(nghttp2_ksl *ksl) { - nghttp2_ksl_blk *rblk = NULL, *lblk, *nhead = NULL; - nghttp2_ksl_node *node; - - rblk = ksl_split_blk(ksl, ksl->head); - if (rblk == NULL) { - return NGHTTP2_ERR_NOMEM; - } - - lblk = ksl->head; - - nhead = nghttp2_mem_malloc(ksl->mem, ksl_blklen(ksl->nodelen)); - if (nhead == NULL) { - nghttp2_mem_free(ksl->mem, rblk); - return NGHTTP2_ERR_NOMEM; - } - nhead->next = nhead->prev = NULL; - nhead->n = 2; - nhead->leaf = 0; - - node = nghttp2_ksl_nth_node(ksl, nhead, 0); - ksl_node_set_key(ksl, node, - nghttp2_ksl_nth_node(ksl, lblk, lblk->n - 1)->key); - node->blk = lblk; - - node = nghttp2_ksl_nth_node(ksl, nhead, 1); - ksl_node_set_key(ksl, node, - nghttp2_ksl_nth_node(ksl, rblk, rblk->n - 1)->key); - node->blk = rblk; - - ksl->head = nhead; - - return 0; -} - -/* - * insert_node inserts a node whose key is |key| with the associated - * |data| at the index of |i|. This function assumes that the number - * of nodes contained by |blk| is strictly less than - * NGHTTP2_KSL_MAX_NBLK. - */ -static void ksl_insert_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i, - const nghttp2_ksl_key *key, void *data) { - nghttp2_ksl_node *node; - - assert(blk->n < NGHTTP2_KSL_MAX_NBLK); - - memmove(blk->nodes + (i + 1) * ksl->nodelen, blk->nodes + i * ksl->nodelen, - ksl->nodelen * (blk->n - i)); - - node = nghttp2_ksl_nth_node(ksl, blk, i); - ksl_node_set_key(ksl, node, key); - node->data = data; - - ++blk->n; -} - -static size_t ksl_bsearch(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, - const nghttp2_ksl_key *key, - nghttp2_ksl_compar compar) { - ssize_t left = -1, right = (ssize_t)blk->n, mid; - nghttp2_ksl_node *node; - - while (right - left > 1) { - mid = (left + right) / 2; - node = nghttp2_ksl_nth_node(ksl, blk, (size_t)mid); - if (compar((nghttp2_ksl_key *)node->key, key)) { - left = mid; - } else { - right = mid; - } - } - - return (size_t)right; -} - -int nghttp2_ksl_insert(nghttp2_ksl *ksl, nghttp2_ksl_it *it, - const nghttp2_ksl_key *key, void *data) { - nghttp2_ksl_blk *blk = ksl->head; - nghttp2_ksl_node *node; - size_t i; - int rv; - - if (blk->n == NGHTTP2_KSL_MAX_NBLK) { - rv = ksl_split_head(ksl); - if (rv != 0) { - return rv; - } - blk = ksl->head; - } - - for (;;) { - i = ksl_bsearch(ksl, blk, key, ksl->compar); - - if (blk->leaf) { - if (i < blk->n && - !ksl->compar(key, nghttp2_ksl_nth_node(ksl, blk, i)->key)) { - if (it) { - *it = nghttp2_ksl_end(ksl); - } - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - ksl_insert_node(ksl, blk, i, key, data); - ++ksl->n; - if (it) { - nghttp2_ksl_it_init(it, ksl, blk, i); - } - return 0; - } - - if (i == blk->n) { - /* This insertion extends the largest key in this subtree. */ - for (; !blk->leaf;) { - node = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1); - if (node->blk->n == NGHTTP2_KSL_MAX_NBLK) { - rv = ksl_split_node(ksl, blk, blk->n - 1); - if (rv != 0) { - return rv; - } - node = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1); - } - ksl_node_set_key(ksl, node, key); - blk = node->blk; - } - ksl_insert_node(ksl, blk, blk->n, key, data); - ++ksl->n; - if (it) { - nghttp2_ksl_it_init(it, ksl, blk, blk->n - 1); - } - return 0; - } - - node = nghttp2_ksl_nth_node(ksl, blk, i); - - if (node->blk->n == NGHTTP2_KSL_MAX_NBLK) { - rv = ksl_split_node(ksl, blk, i); - if (rv != 0) { - return rv; - } - if (ksl->compar((nghttp2_ksl_key *)node->key, key)) { - node = nghttp2_ksl_nth_node(ksl, blk, i + 1); - if (ksl->compar((nghttp2_ksl_key *)node->key, key)) { - ksl_node_set_key(ksl, node, key); - } - } - } - - blk = node->blk; - } -} - -/* - * ksl_remove_node removes the node included in |blk| at the index of - * |i|. - */ -static void ksl_remove_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) { - memmove(blk->nodes + i * ksl->nodelen, blk->nodes + (i + 1) * ksl->nodelen, - ksl->nodelen * (blk->n - (i + 1))); - - --blk->n; -} - -/* - * ksl_merge_node merges 2 nodes which are the nodes at the index of - * |i| and |i + 1|. - * - * If |blk| is the direct descendant of head (root) block and the head - * block contains just 2 nodes, the merged block becomes head block, - * which decreases the height of |ksl| by 1. - * - * This function returns the pointer to the merged block. - */ -static nghttp2_ksl_blk *ksl_merge_node(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, - size_t i) { - nghttp2_ksl_blk *lblk, *rblk; - - assert(i + 1 < blk->n); - - lblk = nghttp2_ksl_nth_node(ksl, blk, i)->blk; - rblk = nghttp2_ksl_nth_node(ksl, blk, i + 1)->blk; - - assert(lblk->n + rblk->n < NGHTTP2_KSL_MAX_NBLK); - - memcpy(lblk->nodes + ksl->nodelen * lblk->n, rblk->nodes, - ksl->nodelen * rblk->n); - - lblk->n += rblk->n; - lblk->next = rblk->next; - if (lblk->next) { - lblk->next->prev = lblk; - } else if (ksl->back == rblk) { - ksl->back = lblk; - } - - nghttp2_mem_free(ksl->mem, rblk); - - if (ksl->head == blk && blk->n == 2) { - nghttp2_mem_free(ksl->mem, ksl->head); - ksl->head = lblk; - } else { - ksl_remove_node(ksl, blk, i + 1); - ksl_node_set_key(ksl, nghttp2_ksl_nth_node(ksl, blk, i), - nghttp2_ksl_nth_node(ksl, lblk, lblk->n - 1)->key); - } - - return lblk; -} - -/* - * ksl_shift_left moves the first node in blk->nodes[i]->blk->nodes to - * blk->nodes[i - 1]->blk->nodes. - */ -static void ksl_shift_left(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) { - nghttp2_ksl_node *lnode, *rnode, *dest, *src; - - assert(i > 0); - - lnode = nghttp2_ksl_nth_node(ksl, blk, i - 1); - rnode = nghttp2_ksl_nth_node(ksl, blk, i); - - assert(lnode->blk->n < NGHTTP2_KSL_MAX_NBLK); - assert(rnode->blk->n > NGHTTP2_KSL_MIN_NBLK); - - dest = nghttp2_ksl_nth_node(ksl, lnode->blk, lnode->blk->n); - src = nghttp2_ksl_nth_node(ksl, rnode->blk, 0); - - memcpy(dest, src, ksl->nodelen); - ksl_node_set_key(ksl, lnode, dest->key); - ++lnode->blk->n; - - --rnode->blk->n; - memmove(rnode->blk->nodes, rnode->blk->nodes + ksl->nodelen, - ksl->nodelen * rnode->blk->n); -} - -/* - * ksl_shift_right moves the last node in blk->nodes[i]->blk->nodes to - * blk->nodes[i + 1]->blk->nodes. - */ -static void ksl_shift_right(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t i) { - nghttp2_ksl_node *lnode, *rnode, *dest, *src; - - assert(i < blk->n - 1); - - lnode = nghttp2_ksl_nth_node(ksl, blk, i); - rnode = nghttp2_ksl_nth_node(ksl, blk, i + 1); - - assert(lnode->blk->n > NGHTTP2_KSL_MIN_NBLK); - assert(rnode->blk->n < NGHTTP2_KSL_MAX_NBLK); - - memmove(rnode->blk->nodes + ksl->nodelen, rnode->blk->nodes, - ksl->nodelen * rnode->blk->n); - ++rnode->blk->n; - - dest = nghttp2_ksl_nth_node(ksl, rnode->blk, 0); - src = nghttp2_ksl_nth_node(ksl, lnode->blk, lnode->blk->n - 1); - - memcpy(dest, src, ksl->nodelen); - - --lnode->blk->n; - ksl_node_set_key( - ksl, lnode, - nghttp2_ksl_nth_node(ksl, lnode->blk, lnode->blk->n - 1)->key); -} - -/* - * key_equal returns nonzero if |lhs| and |rhs| are equal using the - * function |compar|. - */ -static int key_equal(nghttp2_ksl_compar compar, const nghttp2_ksl_key *lhs, - const nghttp2_ksl_key *rhs) { - return !compar(lhs, rhs) && !compar(rhs, lhs); -} - -int nghttp2_ksl_remove(nghttp2_ksl *ksl, nghttp2_ksl_it *it, - const nghttp2_ksl_key *key) { - nghttp2_ksl_blk *blk = ksl->head; - nghttp2_ksl_node *node; - size_t i; - - if (!blk->leaf && blk->n == 2 && - nghttp2_ksl_nth_node(ksl, blk, 0)->blk->n == NGHTTP2_KSL_MIN_NBLK && - nghttp2_ksl_nth_node(ksl, blk, 1)->blk->n == NGHTTP2_KSL_MIN_NBLK) { - blk = ksl_merge_node(ksl, ksl->head, 0); - } - - for (;;) { - i = ksl_bsearch(ksl, blk, key, ksl->compar); - - if (i == blk->n) { - if (it) { - *it = nghttp2_ksl_end(ksl); - } - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - - if (blk->leaf) { - if (ksl->compar(key, nghttp2_ksl_nth_node(ksl, blk, i)->key)) { - if (it) { - *it = nghttp2_ksl_end(ksl); - } - return NGHTTP2_ERR_INVALID_ARGUMENT; - } - ksl_remove_node(ksl, blk, i); - --ksl->n; - if (it) { - if (blk->n == i && blk->next) { - nghttp2_ksl_it_init(it, ksl, blk->next, 0); - } else { - nghttp2_ksl_it_init(it, ksl, blk, i); - } - } - return 0; - } - - node = nghttp2_ksl_nth_node(ksl, blk, i); - - if (node->blk->n == NGHTTP2_KSL_MIN_NBLK) { - if (i > 0 && nghttp2_ksl_nth_node(ksl, blk, i - 1)->blk->n > - NGHTTP2_KSL_MIN_NBLK) { - ksl_shift_right(ksl, blk, i - 1); - blk = node->blk; - } else if (i + 1 < blk->n && - nghttp2_ksl_nth_node(ksl, blk, i + 1)->blk->n > - NGHTTP2_KSL_MIN_NBLK) { - ksl_shift_left(ksl, blk, i + 1); - blk = node->blk; - } else if (i > 0) { - blk = ksl_merge_node(ksl, blk, i - 1); - } else { - assert(i + 1 < blk->n); - blk = ksl_merge_node(ksl, blk, i); - } - } else { - blk = node->blk; - } - } -} - -nghttp2_ksl_it nghttp2_ksl_lower_bound(nghttp2_ksl *ksl, - const nghttp2_ksl_key *key) { - nghttp2_ksl_blk *blk = ksl->head; - nghttp2_ksl_it it; - size_t i; - - for (;;) { - i = ksl_bsearch(ksl, blk, key, ksl->compar); - - if (blk->leaf) { - if (i == blk->n && blk->next) { - blk = blk->next; - i = 0; - } - nghttp2_ksl_it_init(&it, ksl, blk, i); - return it; - } - - if (i == blk->n) { - /* This happens if descendant has smaller key. Fast forward to - find last node in this subtree. */ - for (; !blk->leaf; blk = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1)->blk) - ; - if (blk->next) { - blk = blk->next; - i = 0; - } else { - i = blk->n; - } - nghttp2_ksl_it_init(&it, ksl, blk, i); - return it; - } - blk = nghttp2_ksl_nth_node(ksl, blk, i)->blk; - } -} - -nghttp2_ksl_it nghttp2_ksl_lower_bound_compar(nghttp2_ksl *ksl, - const nghttp2_ksl_key *key, - nghttp2_ksl_compar compar) { - nghttp2_ksl_blk *blk = ksl->head; - nghttp2_ksl_it it; - size_t i; - - for (;;) { - i = ksl_bsearch(ksl, blk, key, compar); - - if (blk->leaf) { - if (i == blk->n && blk->next) { - blk = blk->next; - i = 0; - } - nghttp2_ksl_it_init(&it, ksl, blk, i); - return it; - } - - if (i == blk->n) { - /* This happens if descendant has smaller key. Fast forward to - find last node in this subtree. */ - for (; !blk->leaf; blk = nghttp2_ksl_nth_node(ksl, blk, blk->n - 1)->blk) - ; - if (blk->next) { - blk = blk->next; - i = 0; - } else { - i = blk->n; - } - nghttp2_ksl_it_init(&it, ksl, blk, i); - return it; - } - blk = nghttp2_ksl_nth_node(ksl, blk, i)->blk; - } -} - -void nghttp2_ksl_update_key(nghttp2_ksl *ksl, const nghttp2_ksl_key *old_key, - const nghttp2_ksl_key *new_key) { - nghttp2_ksl_blk *blk = ksl->head; - nghttp2_ksl_node *node; - size_t i; - - for (;;) { - i = ksl_bsearch(ksl, blk, old_key, ksl->compar); - - assert(i < blk->n); - node = nghttp2_ksl_nth_node(ksl, blk, i); - - if (blk->leaf) { - assert(key_equal(ksl->compar, (nghttp2_ksl_key *)node->key, old_key)); - ksl_node_set_key(ksl, node, new_key); - return; - } - - if (key_equal(ksl->compar, (nghttp2_ksl_key *)node->key, old_key) || - ksl->compar((nghttp2_ksl_key *)node->key, new_key)) { - ksl_node_set_key(ksl, node, new_key); - } - - blk = node->blk; - } -} - -static void ksl_print(nghttp2_ksl *ksl, nghttp2_ksl_blk *blk, size_t level) { - size_t i; - nghttp2_ksl_node *node; - - fprintf(stderr, "LV=%zu n=%zu\n", level, blk->n); - - if (blk->leaf) { - for (i = 0; i < blk->n; ++i) { - node = nghttp2_ksl_nth_node(ksl, blk, i); - fprintf(stderr, " %" PRId64, *(int64_t *)(void *)node->key); - } - fprintf(stderr, "\n"); - return; - } - - for (i = 0; i < blk->n; ++i) { - ksl_print(ksl, nghttp2_ksl_nth_node(ksl, blk, i)->blk, level + 1); - } -} - -size_t nghttp2_ksl_len(nghttp2_ksl *ksl) { return ksl->n; } - -void nghttp2_ksl_clear(nghttp2_ksl *ksl) { - size_t i; - nghttp2_ksl_blk *head; - - if (!ksl->head->leaf) { - for (i = 0; i < ksl->head->n; ++i) { - ksl_free_blk(ksl, nghttp2_ksl_nth_node(ksl, ksl->head, i)->blk); - } - } - - ksl->front = ksl->back = ksl->head; - ksl->n = 0; - - head = ksl->head; - - head->next = head->prev = NULL; - head->n = 0; - head->leaf = 1; -} - -void nghttp2_ksl_print(nghttp2_ksl *ksl) { ksl_print(ksl, ksl->head, 0); } - -nghttp2_ksl_it nghttp2_ksl_begin(const nghttp2_ksl *ksl) { - nghttp2_ksl_it it; - nghttp2_ksl_it_init(&it, ksl, ksl->front, 0); - return it; -} - -nghttp2_ksl_it nghttp2_ksl_end(const nghttp2_ksl *ksl) { - nghttp2_ksl_it it; - nghttp2_ksl_it_init(&it, ksl, ksl->back, ksl->back->n); - return it; -} - -void nghttp2_ksl_it_init(nghttp2_ksl_it *it, const nghttp2_ksl *ksl, - nghttp2_ksl_blk *blk, size_t i) { - it->ksl = ksl; - it->blk = blk; - it->i = i; -} - -void *nghttp2_ksl_it_get(const nghttp2_ksl_it *it) { - assert(it->i < it->blk->n); - return nghttp2_ksl_nth_node(it->ksl, it->blk, it->i)->data; -} - -void nghttp2_ksl_it_prev(nghttp2_ksl_it *it) { - assert(!nghttp2_ksl_it_begin(it)); - - if (it->i == 0) { - it->blk = it->blk->prev; - it->i = it->blk->n - 1; - } else { - --it->i; - } -} - -int nghttp2_ksl_it_begin(const nghttp2_ksl_it *it) { - return it->i == 0 && it->blk->prev == NULL; -} diff --git a/deps/nghttp2/lib/nghttp2_ksl.h b/deps/nghttp2/lib/nghttp2_ksl.h deleted file mode 100644 index 39d900ffbf5bd6..00000000000000 --- a/deps/nghttp2/lib/nghttp2_ksl.h +++ /dev/null @@ -1,315 +0,0 @@ -/* - * nghttp2 - HTTP/2 C Library - * - * Copyright (c) 2020 nghttp2 contributors - * Copyright (c) 2018 ngtcp2 contributors - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef NGHTTP2_KSL_H -#define NGHTTP2_KSL_H - -#ifdef HAVE_CONFIG_H -# include -#endif /* HAVE_CONFIG_H */ - -#include - -#include - -/* - * Skip List using single key instead of range. - */ - -#define NGHTTP2_KSL_DEGR 16 -/* NGHTTP2_KSL_MAX_NBLK is the maximum number of nodes which a single - block can contain. */ -#define NGHTTP2_KSL_MAX_NBLK (2 * NGHTTP2_KSL_DEGR - 1) -/* NGHTTP2_KSL_MIN_NBLK is the minimum number of nodes which a single - block other than root must contains. */ -#define NGHTTP2_KSL_MIN_NBLK (NGHTTP2_KSL_DEGR - 1) - -/* - * nghttp2_ksl_key represents key in nghttp2_ksl. - */ -typedef void nghttp2_ksl_key; - -struct nghttp2_ksl_node; -typedef struct nghttp2_ksl_node nghttp2_ksl_node; - -struct nghttp2_ksl_blk; -typedef struct nghttp2_ksl_blk nghttp2_ksl_blk; - -/* - * nghttp2_ksl_node is a node which contains either nghttp2_ksl_blk or - * opaque data. If a node is an internal node, it contains - * nghttp2_ksl_blk. Otherwise, it has data. The key is stored at the - * location starting at key. - */ -struct nghttp2_ksl_node { - union { - nghttp2_ksl_blk *blk; - void *data; - }; - union { - uint64_t align; - /* key is a buffer to include key associated to this node. - Because the length of key is unknown until nghttp2_ksl_init is - called, the actual buffer will be allocated after this - field. */ - uint8_t key[1]; - }; -}; - -/* - * nghttp2_ksl_blk contains nghttp2_ksl_node objects. - */ -struct nghttp2_ksl_blk { - /* next points to the next block if leaf field is nonzero. */ - nghttp2_ksl_blk *next; - /* prev points to the previous block if leaf field is nonzero. */ - nghttp2_ksl_blk *prev; - /* n is the number of nodes this object contains in nodes. */ - size_t n; - /* leaf is nonzero if this block contains leaf nodes. */ - int leaf; - union { - uint64_t align; - /* nodes is a buffer to contain NGHTTP2_KSL_MAX_NBLK - nghttp2_ksl_node objects. Because nghttp2_ksl_node object is - allocated along with the additional variable length key - storage, the size of buffer is unknown until nghttp2_ksl_init is - called. */ - uint8_t nodes[1]; - }; -}; - -/* - * nghttp2_ksl_compar is a function type which returns nonzero if key - * |lhs| should be placed before |rhs|. It returns 0 otherwise. - */ -typedef int (*nghttp2_ksl_compar)(const nghttp2_ksl_key *lhs, - const nghttp2_ksl_key *rhs); - -struct nghttp2_ksl; -typedef struct nghttp2_ksl nghttp2_ksl; - -struct nghttp2_ksl_it; -typedef struct nghttp2_ksl_it nghttp2_ksl_it; - -/* - * nghttp2_ksl_it is a forward iterator to iterate nodes. - */ -struct nghttp2_ksl_it { - const nghttp2_ksl *ksl; - nghttp2_ksl_blk *blk; - size_t i; -}; - -/* - * nghttp2_ksl is a deterministic paged skip list. - */ -struct nghttp2_ksl { - /* head points to the root block. */ - nghttp2_ksl_blk *head; - /* front points to the first leaf block. */ - nghttp2_ksl_blk *front; - /* back points to the last leaf block. */ - nghttp2_ksl_blk *back; - nghttp2_ksl_compar compar; - size_t n; - /* keylen is the size of key */ - size_t keylen; - /* nodelen is the actual size of nghttp2_ksl_node including key - storage. */ - size_t nodelen; - nghttp2_mem *mem; -}; - -/* - * nghttp2_ksl_init initializes |ksl|. |compar| specifies compare - * function. |keylen| is the length of key. - * - * It returns 0 if it succeeds, or one of the following negative error - * codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - */ -int nghttp2_ksl_init(nghttp2_ksl *ksl, nghttp2_ksl_compar compar, size_t keylen, - nghttp2_mem *mem); - -/* - * nghttp2_ksl_free frees resources allocated for |ksl|. If |ksl| is - * NULL, this function does nothing. It does not free the memory - * region pointed by |ksl| itself. - */ -void nghttp2_ksl_free(nghttp2_ksl *ksl); - -/* - * nghttp2_ksl_insert inserts |key| with its associated |data|. On - * successful insertion, the iterator points to the inserted node is - * stored in |*it|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_NOMEM - * Out of memory. - * NGHTTP2_ERR_INVALID_ARGUMENT - * |key| already exists. - */ -int nghttp2_ksl_insert(nghttp2_ksl *ksl, nghttp2_ksl_it *it, - const nghttp2_ksl_key *key, void *data); - -/* - * nghttp2_ksl_remove removes the |key| from |ksl|. - * - * This function assigns the iterator to |*it|, which points to the - * node which is located at the right next of the removed node if |it| - * is not NULL. If |key| is not found, no deletion takes place and - * the return value of nghttp2_ksl_end(ksl) is assigned to |*it|. - * - * This function returns 0 if it succeeds, or one of the following - * negative error codes: - * - * NGHTTP2_ERR_INVALID_ARGUMENT - * |key| does not exist. - */ -int nghttp2_ksl_remove(nghttp2_ksl *ksl, nghttp2_ksl_it *it, - const nghttp2_ksl_key *key); - -/* - * nghttp2_ksl_lower_bound returns the iterator which points to the - * first node which has the key which is equal to |key| or the last - * node which satisfies !compar(&node->key, key). If there is no such - * node, it returns the iterator which satisfies nghttp2_ksl_it_end(it) - * != 0. - */ -nghttp2_ksl_it nghttp2_ksl_lower_bound(nghttp2_ksl *ksl, - const nghttp2_ksl_key *key); - -/* - * nghttp2_ksl_lower_bound_compar works like nghttp2_ksl_lower_bound, - * but it takes custom function |compar| to do lower bound search. - */ -nghttp2_ksl_it nghttp2_ksl_lower_bound_compar(nghttp2_ksl *ksl, - const nghttp2_ksl_key *key, - nghttp2_ksl_compar compar); - -/* - * nghttp2_ksl_update_key replaces the key of nodes which has |old_key| - * with |new_key|. |new_key| must be strictly greater than the - * previous node and strictly smaller than the next node. - */ -void nghttp2_ksl_update_key(nghttp2_ksl *ksl, const nghttp2_ksl_key *old_key, - const nghttp2_ksl_key *new_key); - -/* - * nghttp2_ksl_begin returns the iterator which points to the first - * node. If there is no node in |ksl|, it returns the iterator which - * satisfies nghttp2_ksl_it_end(it) != 0. - */ -nghttp2_ksl_it nghttp2_ksl_begin(const nghttp2_ksl *ksl); - -/* - * nghttp2_ksl_end returns the iterator which points to the node - * following the last node. The returned object satisfies - * nghttp2_ksl_it_end(). If there is no node in |ksl|, it returns the - * iterator which satisfies nghttp2_ksl_it_begin(it) != 0. - */ -nghttp2_ksl_it nghttp2_ksl_end(const nghttp2_ksl *ksl); - -/* - * nghttp2_ksl_len returns the number of elements stored in |ksl|. - */ -size_t nghttp2_ksl_len(nghttp2_ksl *ksl); - -/* - * nghttp2_ksl_clear removes all elements stored in |ksl|. - */ -void nghttp2_ksl_clear(nghttp2_ksl *ksl); - -/* - * nghttp2_ksl_nth_node returns the |n|th node under |blk|. - */ -#define nghttp2_ksl_nth_node(KSL, BLK, N) \ - ((nghttp2_ksl_node *)(void *)((BLK)->nodes + (KSL)->nodelen * (N))) - -/* - * nghttp2_ksl_print prints its internal state in stderr. It assumes - * that the key is of type int64_t. This function should be used for - * the debugging purpose only. - */ -void nghttp2_ksl_print(nghttp2_ksl *ksl); - -/* - * nghttp2_ksl_it_init initializes |it|. - */ -void nghttp2_ksl_it_init(nghttp2_ksl_it *it, const nghttp2_ksl *ksl, - nghttp2_ksl_blk *blk, size_t i); - -/* - * nghttp2_ksl_it_get returns the data associated to the node which - * |it| points to. It is undefined to call this function when - * nghttp2_ksl_it_end(it) returns nonzero. - */ -void *nghttp2_ksl_it_get(const nghttp2_ksl_it *it); - -/* - * nghttp2_ksl_it_next advances the iterator by one. It is undefined - * if this function is called when nghttp2_ksl_it_end(it) returns - * nonzero. - */ -#define nghttp2_ksl_it_next(IT) \ - (++(IT)->i == (IT)->blk->n && (IT)->blk->next \ - ? ((IT)->blk = (IT)->blk->next, (IT)->i = 0) \ - : 0) - -/* - * nghttp2_ksl_it_prev moves backward the iterator by one. It is - * undefined if this function is called when nghttp2_ksl_it_begin(it) - * returns nonzero. - */ -void nghttp2_ksl_it_prev(nghttp2_ksl_it *it); - -/* - * nghttp2_ksl_it_end returns nonzero if |it| points to the beyond the - * last node. - */ -#define nghttp2_ksl_it_end(IT) \ - ((IT)->blk->n == (IT)->i && (IT)->blk->next == NULL) - -/* - * nghttp2_ksl_it_begin returns nonzero if |it| points to the first - * node. |it| might satisfy both nghttp2_ksl_it_begin(&it) and - * nghttp2_ksl_it_end(&it) if the skip list has no node. - */ -int nghttp2_ksl_it_begin(const nghttp2_ksl_it *it); - -/* - * nghttp2_ksl_key returns the key of the node which |it| points to. - * It is undefined to call this function when nghttp2_ksl_it_end(it) - * returns nonzero. - */ -#define nghttp2_ksl_it_key(IT) \ - ((nghttp2_ksl_key *)nghttp2_ksl_nth_node((IT)->ksl, (IT)->blk, (IT)->i)->key) - -#endif /* NGHTTP2_KSL_H */ diff --git a/deps/nghttp2/lib/nghttp2_map.c b/deps/nghttp2/lib/nghttp2_map.c index d12a1f4757b725..5aab90b4daf473 100644 --- a/deps/nghttp2/lib/nghttp2_map.c +++ b/deps/nghttp2/lib/nghttp2_map.c @@ -27,14 +27,16 @@ #include #include +#include #include "nghttp2_helper.h" -#define INITIAL_TABLE_LENGTH 256 +#define NGHTTP2_INITIAL_TABLE_LENBITS 8 int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) { map->mem = mem; - map->tablelen = INITIAL_TABLE_LENGTH; + map->tablelen = 1 << NGHTTP2_INITIAL_TABLE_LENBITS; + map->tablelenbits = NGHTTP2_INITIAL_TABLE_LENBITS; map->table = nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket)); if (map->table == NULL) { @@ -47,151 +49,145 @@ int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) { } void nghttp2_map_free(nghttp2_map *map) { - size_t i; - nghttp2_map_bucket *bkt; - if (!map) { return; } - for (i = 0; i < map->tablelen; ++i) { - bkt = &map->table[i]; - if (bkt->ksl) { - nghttp2_ksl_free(bkt->ksl); - nghttp2_mem_free(map->mem, bkt->ksl); - } - } - nghttp2_mem_free(map->mem, map->table); } -void nghttp2_map_each_free(nghttp2_map *map, - int (*func)(nghttp2_map_entry *entry, void *ptr), +void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr) { uint32_t i; nghttp2_map_bucket *bkt; - nghttp2_ksl_it it; for (i = 0; i < map->tablelen; ++i) { bkt = &map->table[i]; - if (bkt->ptr) { - func(bkt->ptr, ptr); - bkt->ptr = NULL; - assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0); + if (bkt->data == NULL) { continue; } - if (bkt->ksl) { - for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it); - nghttp2_ksl_it_next(&it)) { - func(nghttp2_ksl_it_get(&it), ptr); - } - - nghttp2_ksl_free(bkt->ksl); - nghttp2_mem_free(map->mem, bkt->ksl); - bkt->ksl = NULL; - } + func(bkt->data, ptr); } } -int nghttp2_map_each(nghttp2_map *map, - int (*func)(nghttp2_map_entry *entry, void *ptr), +int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr) { int rv; uint32_t i; nghttp2_map_bucket *bkt; - nghttp2_ksl_it it; for (i = 0; i < map->tablelen; ++i) { bkt = &map->table[i]; - if (bkt->ptr) { - rv = func(bkt->ptr, ptr); - if (rv != 0) { - return rv; - } - assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0); + if (bkt->data == NULL) { continue; } - if (bkt->ksl) { - for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it); - nghttp2_ksl_it_next(&it)) { - rv = func(nghttp2_ksl_it_get(&it), ptr); - if (rv != 0) { - return rv; - } - } + rv = func(bkt->data, ptr); + if (rv != 0) { + return rv; } } + return 0; } -void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key) { - entry->key = key; - entry->next = NULL; +static uint32_t hash(nghttp2_map_key_type key) { + return (uint32_t)key * 2654435769u; } -/* FNV1a hash */ -static uint32_t hash(key_type key, uint32_t mod) { - uint8_t *p, *end; - uint32_t h = 0x811C9DC5u; +static size_t h2idx(uint32_t hash, uint32_t bits) { + return hash >> (32 - bits); +} - p = (uint8_t *)&key; - end = p + sizeof(key_type); +static size_t distance(uint32_t tablelen, uint32_t tablelenbits, + nghttp2_map_bucket *bkt, size_t idx) { + return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1); +} - for (; p != end;) { - h ^= *p++; - h += (h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24); - } +static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash, + nghttp2_map_key_type *pkey, void **pdata) { + uint32_t h = bkt->hash; + nghttp2_map_key_type key = bkt->key; + void *data = bkt->data; + + bkt->hash = *phash; + bkt->key = *pkey; + bkt->data = *pdata; - return h & (mod - 1); + *phash = h; + *pkey = key; + *pdata = data; } -static int less(const nghttp2_ksl_key *lhs, const nghttp2_ksl_key *rhs) { - return *(key_type *)lhs < *(key_type *)rhs; +static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash, + nghttp2_map_key_type key, void *data) { + bkt->hash = hash; + bkt->key = key; + bkt->data = data; } -static int map_insert(nghttp2_map *map, nghttp2_map_bucket *table, - uint32_t tablelen, nghttp2_map_entry *entry) { - uint32_t h = hash(entry->key, tablelen); - nghttp2_map_bucket *bkt = &table[h]; - nghttp2_mem *mem = map->mem; - int rv; +void nghttp2_map_print_distance(nghttp2_map *map) { + uint32_t i; + size_t idx; + nghttp2_map_bucket *bkt; - if (bkt->ptr == NULL && - (bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0)) { - bkt->ptr = entry; - return 0; - } + for (i = 0; i < map->tablelen; ++i) { + bkt = &map->table[i]; - if (!bkt->ksl) { - bkt->ksl = nghttp2_mem_malloc(mem, sizeof(*bkt->ksl)); - if (bkt->ksl == NULL) { - return NGHTTP2_ERR_NOMEM; + if (bkt->data == NULL) { + fprintf(stderr, "@%u \n", i); + continue; } - nghttp2_ksl_init(bkt->ksl, less, sizeof(key_type), mem); + + idx = h2idx(bkt->hash, map->tablelenbits); + fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i, + bkt->hash, bkt->key, idx, + distance(map->tablelen, map->tablelenbits, bkt, idx)); } +} - if (bkt->ptr) { - rv = nghttp2_ksl_insert(bkt->ksl, NULL, &bkt->ptr->key, bkt->ptr); - if (rv != 0) { - return rv; +static int insert(nghttp2_map_bucket *table, uint32_t tablelen, + uint32_t tablelenbits, uint32_t hash, + nghttp2_map_key_type key, void *data) { + size_t idx = h2idx(hash, tablelenbits); + size_t d = 0, dd; + nghttp2_map_bucket *bkt; + + for (;;) { + bkt = &table[idx]; + + if (bkt->data == NULL) { + map_bucket_set_data(bkt, hash, key, data); + return 0; } - bkt->ptr = NULL; - } + dd = distance(tablelen, tablelenbits, bkt, idx); + if (d > dd) { + map_bucket_swap(bkt, &hash, &key, &data); + d = dd; + } else if (bkt->key == key) { + /* TODO This check is just a waste after first swap or if this + function is called from map_resize. That said, there is no + difference with or without this conditional in performance + wise. */ + return NGHTTP2_ERR_INVALID_ARGUMENT; + } - return nghttp2_ksl_insert(bkt->ksl, NULL, &entry->key, entry); + ++d; + idx = (idx + 1) & (tablelen - 1); + } } -/* new_tablelen must be power of 2 */ -static int map_resize(nghttp2_map *map, uint32_t new_tablelen) { +/* new_tablelen must be power of 2 and new_tablelen == (1 << + new_tablelenbits) must hold. */ +static int map_resize(nghttp2_map *map, uint32_t new_tablelen, + uint32_t new_tablelenbits) { uint32_t i; nghttp2_map_bucket *new_table; nghttp2_map_bucket *bkt; - nghttp2_ksl_it it; int rv; new_table = @@ -202,64 +198,38 @@ static int map_resize(nghttp2_map *map, uint32_t new_tablelen) { for (i = 0; i < map->tablelen; ++i) { bkt = &map->table[i]; - - if (bkt->ptr) { - rv = map_insert(map, new_table, new_tablelen, bkt->ptr); - if (rv != 0) { - goto fail; - } - assert(bkt->ksl == NULL || nghttp2_ksl_len(bkt->ksl) == 0); + if (bkt->data == NULL) { continue; } + rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key, + bkt->data); - if (bkt->ksl) { - for (it = nghttp2_ksl_begin(bkt->ksl); !nghttp2_ksl_it_end(&it); - nghttp2_ksl_it_next(&it)) { - rv = map_insert(map, new_table, new_tablelen, nghttp2_ksl_it_get(&it)); - if (rv != 0) { - goto fail; - } - } - } - } - - for (i = 0; i < map->tablelen; ++i) { - bkt = &map->table[i]; - if (bkt->ksl) { - nghttp2_ksl_free(bkt->ksl); - nghttp2_mem_free(map->mem, bkt->ksl); - } + assert(0 == rv); } nghttp2_mem_free(map->mem, map->table); map->tablelen = new_tablelen; + map->tablelenbits = new_tablelenbits; map->table = new_table; return 0; - -fail: - for (i = 0; i < new_tablelen; ++i) { - bkt = &new_table[i]; - if (bkt->ksl) { - nghttp2_ksl_free(bkt->ksl); - nghttp2_mem_free(map->mem, bkt->ksl); - } - } - - return rv; } -int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) { +int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) { int rv; + assert(data); + /* Load factor is 0.75 */ if ((map->size + 1) * 4 > map->tablelen * 3) { - rv = map_resize(map, map->tablelen * 2); + rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1); if (rv != 0) { return rv; } } - rv = map_insert(map, map->table, map->tablelen, new_entry); + + rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key, + data); if (rv != 0) { return rv; } @@ -267,68 +237,75 @@ int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *new_entry) { return 0; } -nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key) { - nghttp2_map_bucket *bkt = &map->table[hash(key, map->tablelen)]; - nghttp2_ksl_it it; +void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) { + uint32_t h = hash(key); + size_t idx = h2idx(h, map->tablelenbits); + nghttp2_map_bucket *bkt; + size_t d = 0; + + for (;;) { + bkt = &map->table[idx]; - if (bkt->ptr) { - if (bkt->ptr->key == key) { - return bkt->ptr; + if (bkt->data == NULL || + d > distance(map->tablelen, map->tablelenbits, bkt, idx)) { + return NULL; } - return NULL; - } - if (bkt->ksl) { - it = nghttp2_ksl_lower_bound(bkt->ksl, &key); - if (nghttp2_ksl_it_end(&it) || - *(key_type *)nghttp2_ksl_it_key(&it) != key) { - return NULL; + if (bkt->key == key) { + return bkt->data; } - return nghttp2_ksl_it_get(&it); - } - return NULL; + ++d; + idx = (idx + 1) & (map->tablelen - 1); + } } -int nghttp2_map_remove(nghttp2_map *map, key_type key) { - nghttp2_map_bucket *bkt = &map->table[hash(key, map->tablelen)]; - int rv; +int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) { + uint32_t h = hash(key); + size_t idx = h2idx(h, map->tablelenbits), didx; + nghttp2_map_bucket *bkt; + size_t d = 0; - if (bkt->ptr) { - if (bkt->ptr->key == key) { - bkt->ptr = NULL; - --map->size; - return 0; - } - return NGHTTP2_ERR_INVALID_ARGUMENT; - } + for (;;) { + bkt = &map->table[idx]; - if (bkt->ksl) { - rv = nghttp2_ksl_remove(bkt->ksl, NULL, &key); - if (rv != 0) { - return rv; + if (bkt->data == NULL || + d > distance(map->tablelen, map->tablelenbits, bkt, idx)) { + return NGHTTP2_ERR_INVALID_ARGUMENT; } - --map->size; - return 0; - } - return NGHTTP2_ERR_INVALID_ARGUMENT; -} + if (bkt->key == key) { + map_bucket_set_data(bkt, 0, 0, NULL); -void nghttp2_map_clear(nghttp2_map *map) { - uint32_t i; - nghttp2_map_bucket *bkt; + didx = idx; + idx = (idx + 1) & (map->tablelen - 1); - for (i = 0; i < map->tablelen; ++i) { - bkt = &map->table[i]; - bkt->ptr = NULL; - if (bkt->ksl) { - nghttp2_ksl_free(bkt->ksl); - nghttp2_mem_free(map->mem, bkt->ksl); - bkt->ksl = NULL; + for (;;) { + bkt = &map->table[idx]; + if (bkt->data == NULL || + distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) { + break; + } + + map->table[didx] = *bkt; + map_bucket_set_data(bkt, 0, 0, NULL); + didx = idx; + + idx = (idx + 1) & (map->tablelen - 1); + } + + --map->size; + + return 0; } + + ++d; + idx = (idx + 1) & (map->tablelen - 1); } +} +void nghttp2_map_clear(nghttp2_map *map) { + memset(map->table, 0, sizeof(*map->table) * map->tablelen); map->size = 0; } diff --git a/deps/nghttp2/lib/nghttp2_map.h b/deps/nghttp2/lib/nghttp2_map.h index 2cf59f698e35bb..1419a09a35b10e 100644 --- a/deps/nghttp2/lib/nghttp2_map.h +++ b/deps/nghttp2/lib/nghttp2_map.h @@ -33,31 +33,23 @@ #include #include "nghttp2_mem.h" -#include "nghttp2_ksl.h" /* Implementation of unordered map */ -typedef int32_t key_type; - -typedef struct nghttp2_map_entry { - struct nghttp2_map_entry *next; - key_type key; -#if SIZEOF_INT_P == 4 - /* we requires 8 bytes aligment */ - int64_t pad; -#endif -} nghttp2_map_entry; +typedef int32_t nghttp2_map_key_type; typedef struct nghttp2_map_bucket { - nghttp2_map_entry *ptr; - nghttp2_ksl *ksl; + uint32_t hash; + nghttp2_map_key_type key; + void *data; } nghttp2_map_bucket; -typedef struct { +typedef struct nghttp2_map { nghttp2_map_bucket *table; nghttp2_mem *mem; size_t size; uint32_t tablelen; + uint32_t tablelenbits; } nghttp2_map; /* @@ -81,21 +73,14 @@ void nghttp2_map_free(nghttp2_map *map); /* * Deallocates each entries using |func| function and any resources * allocated for |map|. The |func| function is responsible for freeing - * given the |entry| object. The |ptr| will be passed to the |func| as + * given the |data| object. The |ptr| will be passed to the |func| as * send argument. The return value of the |func| will be ignored. */ -void nghttp2_map_each_free(nghttp2_map *map, - int (*func)(nghttp2_map_entry *entry, void *ptr), +void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr); /* - * Initializes the |entry| with the |key|. All entries to be inserted - * to the map must be initialized with this function. - */ -void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key); - -/* - * Inserts the new |entry| with the key |entry->key| to the map |map|. + * Inserts the new |data| with the |key| to the map |map|. * * This function returns 0 if it succeeds, or one of the following * negative error codes: @@ -105,25 +90,25 @@ void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key); * NGHTTP2_ERR_NOMEM * Out of memory */ -int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry); +int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data); /* - * Returns the entry associated by the key |key|. If there is no such - * entry, this function returns NULL. + * Returns the data associated by the key |key|. If there is no such + * data, this function returns NULL. */ -nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key); +void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key); /* - * Removes the entry associated by the key |key| from the |map|. The - * removed entry is not freed by this function. + * Removes the data associated by the key |key| from the |map|. The + * removed data is not freed by this function. * * This function returns 0 if it succeeds, or one of the following * negative error codes: * * NGHTTP2_ERR_INVALID_ARGUMENT - * The entry associated by |key| does not exist. + * The data associated by |key| does not exist. */ -int nghttp2_map_remove(nghttp2_map *map, key_type key); +int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key); /* * Removes all entries from |map|. @@ -136,21 +121,22 @@ void nghttp2_map_clear(nghttp2_map *map); size_t nghttp2_map_size(nghttp2_map *map); /* - * Applies the function |func| to each entry in the |map| with the + * Applies the function |func| to each data in the |map| with the * optional user supplied pointer |ptr|. * * If the |func| returns 0, this function calls the |func| with the - * next entry. If the |func| returns nonzero, it will not call the + * next data. If the |func| returns nonzero, it will not call the * |func| for further entries and return the return value of the * |func| immediately. Thus, this function returns 0 if all the * invocations of the |func| return 0, or nonzero value which the last * invocation of |func| returns. * - * Don't use this function to free each entry. Use + * Don't use this function to free each data. Use * nghttp2_map_each_free() instead. */ -int nghttp2_map_each(nghttp2_map *map, - int (*func)(nghttp2_map_entry *entry, void *ptr), +int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr), void *ptr); +void nghttp2_map_print_distance(nghttp2_map *map); + #endif /* NGHTTP2_MAP_H */ diff --git a/deps/nghttp2/lib/nghttp2_session.c b/deps/nghttp2/lib/nghttp2_session.c index 2e7e907f25e199..36f1179f72a225 100644 --- a/deps/nghttp2/lib/nghttp2_session.c +++ b/deps/nghttp2/lib/nghttp2_session.c @@ -666,7 +666,7 @@ int nghttp2_session_server_new3(nghttp2_session **session_ptr, return 0; } -static int free_streams(nghttp2_map_entry *entry, void *ptr) { +static int free_streams(void *entry, void *ptr) { nghttp2_session *session; nghttp2_stream *stream; nghttp2_outbound_item *item; @@ -1102,7 +1102,7 @@ nghttp2_stream *nghttp2_session_open_stream(nghttp2_session *session, (int32_t)session->local_settings.initial_window_size, stream_user_data, mem); - rv = nghttp2_map_insert(&session->streams, &stream->map_entry); + rv = nghttp2_map_insert(&session->streams, stream_id, stream); if (rv != 0) { nghttp2_stream_free(stream); nghttp2_mem_free(mem, stream); @@ -2424,7 +2424,7 @@ static int session_call_on_frame_send(nghttp2_session *session, return 0; } -static int find_stream_on_goaway_func(nghttp2_map_entry *entry, void *ptr) { +static int find_stream_on_goaway_func(void *entry, void *ptr) { nghttp2_close_stream_on_goaway_arg *arg; nghttp2_stream *stream; @@ -4194,8 +4194,7 @@ static int session_process_rst_stream_frame(nghttp2_session *session) { return nghttp2_session_on_rst_stream_received(session, frame); } -static int update_remote_initial_window_size_func(nghttp2_map_entry *entry, - void *ptr) { +static int update_remote_initial_window_size_func(void *entry, void *ptr) { int rv; nghttp2_update_window_size_arg *arg; nghttp2_stream *stream; @@ -4248,8 +4247,7 @@ session_update_remote_initial_window_size(nghttp2_session *session, update_remote_initial_window_size_func, &arg); } -static int update_local_initial_window_size_func(nghttp2_map_entry *entry, - void *ptr) { +static int update_local_initial_window_size_func(void *entry, void *ptr) { int rv; nghttp2_update_window_size_arg *arg; nghttp2_stream *stream; @@ -6432,8 +6430,9 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in, /* CONTINUATION won't bear NGHTTP2_PADDED flag */ - iframe->frame.hd.flags = (uint8_t)( - iframe->frame.hd.flags | (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS)); + iframe->frame.hd.flags = + (uint8_t)(iframe->frame.hd.flags | + (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS)); iframe->frame.hd.length += cont_hd.length; busy = 1; diff --git a/deps/nghttp2/lib/nghttp2_stream.c b/deps/nghttp2/lib/nghttp2_stream.c index dc3a6b11ccbf75..96e1d9fe0f9b7e 100644 --- a/deps/nghttp2/lib/nghttp2_stream.c +++ b/deps/nghttp2/lib/nghttp2_stream.c @@ -62,7 +62,6 @@ void nghttp2_stream_init(nghttp2_stream *stream, int32_t stream_id, int32_t weight, int32_t remote_initial_window_size, int32_t local_initial_window_size, void *stream_user_data, nghttp2_mem *mem) { - nghttp2_map_entry_init(&stream->map_entry, (key_type)stream_id); nghttp2_pq_init(&stream->obq, stream_less, mem); stream->stream_id = stream_id; diff --git a/deps/nghttp2/lib/nghttp2_stream.h b/deps/nghttp2/lib/nghttp2_stream.h index a1b807d295c05c..2846c6aab75705 100644 --- a/deps/nghttp2/lib/nghttp2_stream.h +++ b/deps/nghttp2/lib/nghttp2_stream.h @@ -135,8 +135,6 @@ typedef enum { } nghttp2_http_flag; struct nghttp2_stream { - /* Intrusive Map */ - nghttp2_map_entry map_entry; /* Entry for dep_prev->obq */ nghttp2_pq_entry pq_entry; /* Priority Queue storing direct descendant (nghttp2_stream). Only diff --git a/deps/nghttp2/nghttp2.gyp b/deps/nghttp2/nghttp2.gyp index 21fd6ba5ecf46d..0dcd034b8169da 100644 --- a/deps/nghttp2/nghttp2.gyp +++ b/deps/nghttp2/nghttp2.gyp @@ -44,7 +44,6 @@ 'lib/nghttp2_hd_huffman_data.c', 'lib/nghttp2_helper.c', 'lib/nghttp2_http.c', - 'lib/nghttp2_ksl.c', 'lib/nghttp2_map.c', 'lib/nghttp2_mem.c', 'lib/nghttp2_npn.c', diff --git a/deps/npm/docs/content/using-npm/scripts.md b/deps/npm/docs/content/using-npm/scripts.md index 2f2d53c1c2b64b..fba37c28600b3b 100644 --- a/deps/npm/docs/content/using-npm/scripts.md +++ b/deps/npm/docs/content/using-npm/scripts.md @@ -259,7 +259,7 @@ package.json file, then your package scripts would have the in your code with `process.env.npm_package_name` and `process.env.npm_package_version`, and so on for other fields. -See [`package-json.md`](/using-npm/package-json) for more on package configs. +See [`package-json.md`](/configuring-npm/package-json) for more on package configs. #### current lifecycle event diff --git a/deps/npm/docs/output/commands/npm-ls.html b/deps/npm/docs/output/commands/npm-ls.html index 252e478513ffce..0ce0ef1e18a431 100644 --- a/deps/npm/docs/output/commands/npm-ls.html +++ b/deps/npm/docs/output/commands/npm-ls.html @@ -159,7 +159,7 @@

Description

the results to only the paths to the packages named. Note that nested packages will also show the paths to the specified packages. For example, running npm ls promzard in npm’s source tree will show:

-
npm@7.23.0 /path/to/npm
+
npm@7.24.0 /path/to/npm
 └─┬ init-package-json@0.0.4
   └── promzard@0.1.5
 
diff --git a/deps/npm/docs/output/commands/npm.html b/deps/npm/docs/output/commands/npm.html index 6670f691d59ac6..0956b0ef0d92a6 100644 --- a/deps/npm/docs/output/commands/npm.html +++ b/deps/npm/docs/output/commands/npm.html @@ -148,7 +148,7 @@

Table of contents

npm <command> [args]
 

Version

-

7.23.0

+

7.24.0

Description

npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency diff --git a/deps/npm/docs/output/using-npm/scripts.html b/deps/npm/docs/output/using-npm/scripts.html index 6dcf9a0416e4c2..1b4556a1f85dd1 100644 --- a/deps/npm/docs/output/using-npm/scripts.html +++ b/deps/npm/docs/output/using-npm/scripts.html @@ -379,7 +379,7 @@

package.json vars

npm_package_version set to “1.2.5”. You can access these variables in your code with process.env.npm_package_name and process.env.npm_package_version, and so on for other fields.

-

See package-json.md for more on package configs.

+

See package-json.md for more on package configs.

current lifecycle event

Lastly, the npm_lifecycle_event environment variable is set to whichever stage of the cycle is being executed. So, you could have a diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js index 1589ff589c38e2..99f75b71384fa6 100644 --- a/deps/npm/lib/install.js +++ b/deps/npm/lib/install.js @@ -135,7 +135,8 @@ class Install extends ArboristWorkspaceCmd { // be very strict about engines when trying to update npm itself const npmInstall = args.find(arg => arg.startsWith('npm@') || arg === 'npm') if (isGlobalInstall && npmInstall) { - const npmManifest = await pacote.manifest(npmInstall) + const npmOptions = this.npm.flatOptions + const npmManifest = await pacote.manifest(npmInstall, npmOptions) try { checks.checkEngine(npmManifest, npmManifest.version, process.version) } catch (e) { diff --git a/deps/npm/lib/search/format-package-stream.js b/deps/npm/lib/search/format-package-stream.js index c88df5eb4be04d..fb7d81856d63f4 100644 --- a/deps/npm/lib/search/format-package-stream.js +++ b/deps/npm/lib/search/format-package-stream.js @@ -42,7 +42,7 @@ class JSONOutputStream extends Minipass { } end () { - super.write(this._didFirst ? ']\n' : '\n]\n') + super.write(this._didFirst ? ']\n' : '\n[]\n') super.end() } } diff --git a/deps/npm/lib/utils/config/definitions.js b/deps/npm/lib/utils/config/definitions.js index 092e0fc435cb4e..009f60a7bce61d 100644 --- a/deps/npm/lib/utils/config/definitions.js +++ b/deps/npm/lib/utils/config/definitions.js @@ -2053,10 +2053,14 @@ define('user-agent', { .replace(/\{workspaces\}/gi, inWorkspaces) .replace(/\{ci\}/gi, ciName ? `ci/${ciName}` : '') .trim() + + // We can't clobber the original or else subsequent flattening will fail + // (i.e. when we change the underlying config values) + // obj[key] = flatOptions.userAgent + // user-agent is a unique kind of config item that gets set from a template // and ends up translated. Because of this, the normal "should we set this // to process.env also doesn't work - obj[key] = flatOptions.userAgent process.env.npm_config_user_agent = flatOptions.userAgent }, }) @@ -2140,6 +2144,9 @@ define('workspace', { a workspace which does not yet exist, to create the folder and set it up as a brand new workspace within the project. `, + flatten: (key, obj, flatOptions) => { + definitions['user-agent'].flatten('user-agent', obj, flatOptions) + }, }) define('workspaces', { @@ -2151,6 +2158,9 @@ define('workspaces', { Enable running a command in the context of **all** the configured workspaces. `, + flatten: (key, obj, flatOptions) => { + definitions['user-agent'].flatten('user-agent', obj, flatOptions) + }, }) define('yes', { diff --git a/deps/npm/lib/utils/did-you-mean.js b/deps/npm/lib/utils/did-you-mean.js index 0cfdd035255eb1..c324253af24065 100644 --- a/deps/npm/lib/utils/did-you-mean.js +++ b/deps/npm/lib/utils/did-you-mean.js @@ -3,25 +3,26 @@ const readJson = require('read-package-json-fast') const { cmdList } = require('./cmd-list.js') const didYouMean = async (npm, path, scmd) => { - const bestCmd = cmdList + let best = cmdList .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && scmd !== cmd) .map(str => ` npm ${str} # ${npm.commands[str].description}`) - const pkg = await readJson(`${path}/package.json`) - const { scripts } = pkg // We would already be suggesting this in `npm x` so omit them here const runScripts = ['stop', 'start', 'test', 'restart'] - const bestRun = Object.keys(scripts || {}) - .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && - !runScripts.includes(cmd)) - .map(str => ` npm run ${str} # run the "${str}" package script`) - - const { bin } = pkg - const bestBin = Object.keys(bin || {}) - .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4) - .map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`) - - const best = [...bestCmd, ...bestRun, ...bestBin] + try { + const { bin, scripts } = await readJson(`${path}/package.json`) + best = best.concat( + Object.keys(scripts || {}) + .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4 && + !runScripts.includes(cmd)) + .map(str => ` npm run ${str} # run the "${str}" package script`), + Object.keys(bin || {}) + .filter(cmd => distance(scmd, cmd) < scmd.length * 0.4) + .map(str => ` npm exec ${str} # run the "${str}" command from either this or a remote npm package`) + ) + } catch (_) { + // gracefully ignore not being in a folder w/ a package.json + } if (best.length === 0) return '' diff --git a/deps/npm/lib/utils/error-message.js b/deps/npm/lib/utils/error-message.js index 6e12bcb918eef8..9343d37d541495 100644 --- a/deps/npm/lib/utils/error-message.js +++ b/deps/npm/lib/utils/error-message.js @@ -367,7 +367,7 @@ module.exports = (er, npm) => { detail.push(['signal', er.signal]) if (er.cmd && Array.isArray(er.args)) - detail.push(['command', ...[er.cmd, ...er.args]]) + detail.push(['command', ...[er.cmd, ...er.args.map(replaceInfo)]]) if (er.stdout) detail.push(['', er.stdout.trim()]) diff --git a/deps/npm/lib/view.js b/deps/npm/lib/view.js index f4fc5974eeeca7..0124bfb7d35433 100644 --- a/deps/npm/lib/view.js +++ b/deps/npm/lib/view.js @@ -336,7 +336,7 @@ class View extends BaseCommand { email: color.cyan(manifest._npmUser.email), }), modified: !packument.time ? undefined - : color.yellow(relativeDate(packument.time[packument.version])), + : color.yellow(relativeDate(packument.time[manifest.version])), maintainers: (packument.maintainers || []).map((u) => unparsePerson({ name: color.yellow(u.name), email: color.cyan(u.email), diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index 8ff55b216f2a4b..e9c5d78d82abf1 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -26,7 +26,7 @@ example, running \fBnpm ls promzard\fP in npm's source tree will show: .P .RS 2 .nf -npm@7\.23\.0 /path/to/npm +npm@7\.24\.0 /path/to/npm └─┬ init\-package\-json@0\.0\.4 └── promzard@0\.1\.5 .fi diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index e9e11652387d3e..8e07933b219606 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -10,7 +10,7 @@ npm [args] .RE .SS Version .P -7\.23\.0 +7\.24\.0 .SS Description .P npm is the package manager for the Node JavaScript platform\. It puts diff --git a/deps/npm/node_modules/init-package-json/LICENSE b/deps/npm/node_modules/init-package-json/LICENSE deleted file mode 100644 index 05eeeb88c2ef4c..00000000000000 --- a/deps/npm/node_modules/init-package-json/LICENSE +++ /dev/null @@ -1,15 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR -IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/init-package-json/LICENSE.md b/deps/npm/node_modules/init-package-json/LICENSE.md new file mode 100644 index 00000000000000..845be76f64e789 --- /dev/null +++ b/deps/npm/node_modules/init-package-json/LICENSE.md @@ -0,0 +1,18 @@ +ISC License + +Copyright npm, Inc. + +Permission to use, copy, modify, and/or distribute this +software for any purpose with or without fee is hereby +granted, provided that the above copyright notice and this +permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND NPM DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO +EVENT SHALL NPM BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE +USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/deps/npm/node_modules/init-package-json/default-input.js b/deps/npm/node_modules/init-package-json/lib/default-input.js similarity index 64% rename from deps/npm/node_modules/init-package-json/default-input.js rename to deps/npm/node_modules/init-package-json/lib/default-input.js index d1f65841d6c5a3..0003472975760b 100644 --- a/deps/npm/node_modules/init-package-json/default-input.js +++ b/deps/npm/node_modules/init-package-json/lib/default-input.js @@ -1,5 +1,5 @@ +/* eslint-disable no-undef */ var fs = require('fs') -var glob = require('glob') var path = require('path') var validateLicense = require('validate-npm-package-license') var validateName = require('validate-npm-package-name') @@ -15,35 +15,57 @@ function niceName (n) { return n.replace(/^node-|[.-]js$/g, '').replace(/\s+/g, ' ').replace(/ /g, '-').toLowerCase() } -function readDeps (test, excluded) { return function (cb) { - fs.readdir('node_modules', function (er, dir) { - if (er) return cb() - var deps = {} - var n = dir.length - if (n === 0) return cb(null, deps) - dir.forEach(function (d) { - if (d.match(/^\./)) return next() - if (test !== isTestPkg(d) || excluded[d]) - return next() - - var dp = path.join(dirname, 'node_modules', d, 'package.json') - fs.readFile(dp, 'utf8', function (er, p) { - if (er) return next() - try { p = JSON.parse(p) } - catch (e) { return next() } - if (!p.version) return next() - if (p._requiredBy) { - if (!p._requiredBy.some(function (req) { return req === '#USER' })) return next() +function readDeps (test, excluded) { + return function (cb) { + fs.readdir('node_modules', function (er, dir) { + if (er) { + return cb() + } + var deps = {} + var n = dir.length + if (n === 0) { + return cb(null, deps) + } + dir.forEach(function (d) { + if (d.match(/^\./)) { + return next() + } + if (test !== isTestPkg(d) || excluded[d]) { + return next() } - deps[d] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version - return next() + + var dp = path.join(dirname, 'node_modules', d, 'package.json') + fs.readFile(dp, 'utf8', function (er, p) { + if (er) { + return next() + } + try { + p = JSON.parse(p) + } catch (e) { + return next() + } + if (!p.version) { + return next() + } + if (p._requiredBy) { + if (!p._requiredBy.some(function (req) { + return req === '#USER' + })) { + return next() + } + } + deps[d] = config.get('save-exact') ? p.version : config.get('save-prefix') + p.version + return next() + }) }) + function next () { + if (--n === 0) { + return cb(null, deps) + } + } }) - function next () { - if (--n === 0) return cb(null, deps) - } - }) -}} + } +} var name = niceName(package.name || basename) var spec @@ -54,16 +76,20 @@ try { } var scope = config.get('scope') if (scope) { - if (scope.charAt(0) !== '@') scope = '@' + scope + if (scope.charAt(0) !== '@') { + scope = '@' + scope + } if (spec.scope) { name = scope + '/' + spec.name.split('/')[1] } else { name = scope + '/' + name } } -exports.name = yes ? name : prompt('package name', name, function (data) { +exports.name = yes ? name : prompt('package name', name, function (data) { var its = validateName(data) - if (its.validForNewPackages) return data + if (its.validForNewPackages) { + return data + } var errors = (its.errors || []).concat(its.warnings || []) var er = new Error('Sorry, ' + errors.join(' and ') + '.') er.notValid = true @@ -83,7 +109,9 @@ var version = package.version || exports.version = yes ? version : prompt('version', version, function (version) { - if (semver.valid(version)) return version + if (semver.valid(version)) { + return version + } var er = new Error('Invalid version: "' + version + '"') er.notValid = true return er @@ -96,22 +124,25 @@ if (!package.description) { if (!package.main) { exports.main = function (cb) { fs.readdir(dirname, function (er, f) { - if (er) f = [] + if (er) { + f = [] + } f = f.filter(function (f) { return f.match(/\.js$/) }) - if (f.indexOf('index.js') !== -1) + if (f.indexOf('index.js') !== -1) { f = 'index.js' - else if (f.indexOf('main.js') !== -1) + } else if (f.indexOf('main.js') !== -1) { f = 'main.js' - else if (f.indexOf(basename + '.js') !== -1) + } else if (f.indexOf(basename + '.js') !== -1) { f = basename + '.js' - else + } else { f = f[0] + } - var index = f || 'index.js' + var index = f || 'index.js' return cb(null, yes ? index : prompt('entry point', index)) }) } @@ -121,18 +152,24 @@ if (!package.bin) { exports.bin = function (cb) { fs.readdir(path.resolve(dirname, 'bin'), function (er, d) { // no bins - if (er) return cb() + if (er) { + return cb() + } // just take the first js file we find there, or nada - return cb(null, d.filter(function (f) { - return f.match(/\.js$/) - })[0]) + let r = d.find(f => f.match(/\.js$/)) + if (r) { + r = `bin/${r}` + } + return cb(null, r) }) } } exports.directories = function (cb) { fs.readdir(dirname, function (er, dirs) { - if (er) return cb(er) + if (er) { + return cb(er) + } var res = {} dirs.forEach(function (d) { switch (d) { @@ -143,7 +180,9 @@ exports.directories = function (cb) { case 'lib': return res.lib = d } }) - if (Object.keys(res).length === 0) res = undefined + if (Object.keys(res).length === 0) { + res = undefined + } return cb(null, res) }) } @@ -173,13 +212,15 @@ function setupScripts (d, cb) { } if (!s.test || s.test === notest) { var commands = { - 'tap':'tap test/*.js' - , 'expresso':'expresso test' - , 'mocha':'mocha' + tap: 'tap test/*.js', + expresso: 'expresso test', + mocha: 'mocha', } var command Object.keys(commands).forEach(function (k) { - if (d.indexOf(k) !== -1) command = commands[k] + if (d.indexOf(k) !== -1) { + command = commands[k] + } }) var ps = 'test command' if (yes) { @@ -201,12 +242,18 @@ if (!package.repository) { var i = gconf.indexOf('[remote "origin"]') if (i !== -1) { var u = gconf[i + 1] - if (!u.match(/^\s*url =/)) u = gconf[i + 2] - if (!u.match(/^\s*url =/)) u = null - else u = u.replace(/^\s*url = /, '') + if (!u.match(/^\s*url =/)) { + u = gconf[i + 2] + } + if (!u.match(/^\s*url =/)) { + u = null + } else { + u = u.replace(/^\s*url = /, '') + } } - if (u && u.match(/^git@github.com:/)) + if (u && u.match(/^git@github.com:/)) { u = u.replace(/^git@github.com:/, 'https://github.com/') + } return cb(null, yes ? u : prompt('git repository', u)) }) @@ -215,9 +262,15 @@ if (!package.repository) { if (!package.keywords) { exports.keywords = yes ? '' : prompt('keywords', function (s) { - if (!s) return undefined - if (Array.isArray(s)) s = s.join(' ') - if (typeof s !== 'string') return s + if (!s) { + return undefined + } + if (Array.isArray(s)) { + s = s.join(' ') + } + if (typeof s !== 'string') { + return s + } return s.split(/[\s,]+/) }) } @@ -225,15 +278,15 @@ if (!package.keywords) { if (!package.author) { exports.author = config.get('init.author.name') || config.get('init-author-name') - ? { - "name" : config.get('init.author.name') || + ? { + name: config.get('init.author.name') || config.get('init-author-name'), - "email" : config.get('init.author.email') || + email: config.get('init.author.email') || config.get('init-author-email'), - "url" : config.get('init.author.url') || - config.get('init-author-url') + url: config.get('init.author.url') || + config.get('init-author-url'), } - : yes ? '' : prompt('author') + : yes ? '' : prompt('author') } const defaultDottedInitLicense = config && @@ -248,7 +301,9 @@ var license = package.license || 'ISC' exports.license = yes ? license : prompt('license', license, function (data) { var its = validateLicense(data) - if (its.validForNewPackages) return data + if (its.validForNewPackages) { + return data + } var errors = (its.errors || []).concat(its.warnings || []) var er = new Error('Sorry, ' + errors.join(' and ') + '.') er.notValid = true diff --git a/deps/npm/node_modules/init-package-json/init-package-json.js b/deps/npm/node_modules/init-package-json/lib/init-package-json.js similarity index 79% rename from deps/npm/node_modules/init-package-json/init-package-json.js rename to deps/npm/node_modules/init-package-json/lib/init-package-json.js index 83e7342d0aa4f4..bee79351caab3f 100644 --- a/deps/npm/node_modules/init-package-json/init-package-json.js +++ b/deps/npm/node_modules/init-package-json/lib/init-package-json.js @@ -12,7 +12,6 @@ var read = require('read') // to validate the data object at the end as a worthwhile package // and assign default values for things. -// readJson.extras(file, data, cb) var readJson = require('read-package-json') function yes (conf) { @@ -23,8 +22,10 @@ function yes (conf) { } function init (dir, input, config, cb) { - if (typeof config === 'function') - cb = config, config = {} + if (typeof config === 'function') { + cb = config + config = {} + } // accept either a plain-jane object, or a config object // with a "get" method. @@ -36,7 +37,7 @@ function init (dir, input, config, cb) { }, toJSON: function () { return data - } + }, } } @@ -52,14 +53,18 @@ function init (dir, input, config, cb) { readJson(packageFile, function (er, d) { readJson.extraSet = es - if (er) pkg = {} - else pkg = d + if (er) { + pkg = {} + } else { + pkg = d + } ctx.filename = packageFile ctx.dirname = path.dirname(packageFile) ctx.basename = path.basename(ctx.dirname) - if (!pkg.version || !semver.valid(pkg.version)) + if (!pkg.version || !semver.valid(pkg.version)) { delete pkg.version + } ctx.package = pkg ctx.config = config || {} @@ -71,7 +76,9 @@ function init (dir, input, config, cb) { pz.on('error', cb) pz.on('data', function (data) { Object.keys(data).forEach(function (k) { - if (data[k] !== undefined && data[k] !== null) pkg[k] = data[k] + if (data[k] !== undefined && data[k] !== null) { + pkg[k] = data[k] + } }) // only do a few of these. @@ -81,8 +88,10 @@ function init (dir, input, config, cb) { return fn.name !== 'authors' && fn.name !== 'mans' }) readJson.extras(packageFile, pkg, function (er, pkg) { + if (er) { + return cb(er, pkg) + } readJson.extraSet = es - if (er) return cb(er, pkg) pkg = unParsePeople(pkg) // no need for the readme now. delete pkg.readme @@ -95,13 +104,15 @@ function init (dir, input, config, cb) { delete pkg.gitHead // if the repo is empty, remove it. - if (!pkg.repository) + if (!pkg.repository) { delete pkg.repository + } // readJson filters out empty descriptions, but init-package-json // traditionally leaves them alone - if (!pkg.description) + if (!pkg.description) { pkg.description = data.description + } var d = JSON.stringify(updateDeps(pkg), null, 2) + '\n' function write (yes) { @@ -116,7 +127,7 @@ function init (dir, input, config, cb) { return write(true) } console.log('About to write to %s:\n\n%s\n', packageFile, d) - read({prompt:'Is this OK? ', default: 'yes'}, function (er, ok) { + read({prompt: 'Is this OK? ', default: 'yes'}, function (er, ok) { if (er) { return cb(er) } @@ -129,18 +140,19 @@ function init (dir, input, config, cb) { }) }) }) - } -function updateDeps(depsData) { +function updateDeps (depsData) { // optionalDependencies don't need to be repeated in two places if (depsData.dependencies) { if (depsData.optionalDependencies) { - for (const name of Object.keys(depsData.optionalDependencies)) + for (const name of Object.keys(depsData.optionalDependencies)) { delete depsData.dependencies[name] + } } - if (Object.keys(depsData.dependencies).length === 0) + if (Object.keys(depsData.dependencies).length === 0) { delete depsData.dependencies + } } return depsData @@ -148,21 +160,25 @@ function updateDeps(depsData) { // turn the objects into somewhat more humane strings. function unParsePeople (data) { - if (data.author) data.author = unParsePerson(data.author) - ;["maintainers", "contributors"].forEach(function (set) { - if (!Array.isArray(data[set])) return; + if (data.author) { + data.author = unParsePerson(data.author) + }['maintainers', 'contributors'].forEach(function (set) { + if (!Array.isArray(data[set])) { + return + } data[set] = data[set].map(unParsePerson) }) return data } function unParsePerson (person) { - if (typeof person === "string") return person - var name = person.name || "" + if (typeof person === 'string') { + return person + } + var name = person.name || '' var u = person.url || person.web - var url = u ? (" ("+u+")") : "" + var url = u ? (' (' + u + ')') : '' var e = person.email || person.mail - var email = e ? (" <"+e+">") : "" - return name+email+url + var email = e ? (' <' + e + '>') : '' + return name + email + url } - diff --git a/deps/npm/node_modules/init-package-json/package.json b/deps/npm/node_modules/init-package-json/package.json index 0e07f48f49746d..6d642f6cf6879f 100644 --- a/deps/npm/node_modules/init-package-json/package.json +++ b/deps/npm/node_modules/init-package-json/package.json @@ -1,41 +1,46 @@ { "name": "init-package-json", - "version": "2.0.4", - "main": "init-package-json.js", + "version": "2.0.5", + "main": "lib/init-package-json.js", "scripts": { "test": "tap", "preversion": "npm test", "postversion": "npm publish", - "prepublishOnly": "git push origin --follow-tags" + "prepublishOnly": "git push origin --follow-tags", + "lint": "eslint '**/*.js'", + "postlint": "npm-template-check", + "lintfix": "npm run lint -- --fix", + "snap": "tap", + "posttest": "npm run lint" }, "repository": { "type": "git", "url": "https://github.com/npm/init-package-json.git" }, - "author": "Isaac Z. Schlueter (http://blog.izs.me/)", + "author": "GitHub Inc.", "license": "ISC", "description": "A node module to get your node module started", "dependencies": { - "glob": "^7.1.1", - "npm-package-arg": "^8.1.2", + "npm-package-arg": "^8.1.5", "promzard": "^0.3.0", "read": "~1.0.1", - "read-package-json": "^4.0.0", + "read-package-json": "^4.1.1", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^3.0.0" }, "devDependencies": { "@npmcli/config": "^2.1.0", - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2", - "tap": "^14.11.0" + "@npmcli/template-oss": "^1.0.3", + "tap": "^15.0.9" }, "engines": { "node": ">=10" }, "tap": { - "jobs": "1" + "statements": "94", + "branches": "83", + "lines": "94" }, "keywords": [ "init", @@ -48,7 +53,8 @@ "start" ], "files": [ - "default-input.js", - "init-package-json.js" - ] + "bin", + "lib" + ], + "templateVersion": "1.0.3" } diff --git a/deps/npm/node_modules/minipass/index.js b/deps/npm/node_modules/minipass/index.js index 56cbd665d2526d..ae134a066d77f0 100644 --- a/deps/npm/node_modules/minipass/index.js +++ b/deps/npm/node_modules/minipass/index.js @@ -1,4 +1,8 @@ 'use strict' +const proc = typeof process === 'object' && process ? process : { + stdout: null, + stderr: null, +} const EE = require('events') const Stream = require('stream') const Yallist = require('yallist') @@ -8,6 +12,7 @@ const EOF = Symbol('EOF') const MAYBE_EMIT_END = Symbol('maybeEmitEnd') const EMITTED_END = Symbol('emittedEnd') const EMITTING_END = Symbol('emittingEnd') +const EMITTED_ERROR = Symbol('emittedError') const CLOSED = Symbol('closed') const READ = Symbol('read') const FLUSH = Symbol('flush') @@ -66,6 +71,7 @@ module.exports = class Minipass extends Stream { this[EMITTED_END] = false this[EMITTING_END] = false this[CLOSED] = false + this[EMITTED_ERROR] = null this.writable = true this.readable = true this[BUFFERLENGTH] = 0 @@ -310,7 +316,7 @@ module.exports = class Minipass extends Stream { const ended = this[EMITTED_END] opts = opts || {} - if (dest === process.stdout || dest === process.stderr) + if (dest === proc.stdout || dest === proc.stderr) opts.end = false else opts.end = opts.end !== false @@ -339,6 +345,8 @@ module.exports = class Minipass extends Stream { else if (isEndish(ev) && this[EMITTED_END]) { super.emit(ev) this.removeAllListeners(ev) + } else if (ev === 'error' && this[EMITTED_ERROR]) { + fn.call(this, this[EMITTED_ERROR]) } } } @@ -400,6 +408,8 @@ module.exports = class Minipass extends Stream { // don't emit close before 'end' and 'finish' if (!this[EMITTED_END] && !this[DESTROYED]) return + } else if (ev === 'error') { + this[EMITTED_ERROR] = data } // TODO: replace with a spread operator when Node v4 support drops @@ -452,8 +462,8 @@ module.exports = class Minipass extends Stream { promise () { return new Promise((resolve, reject) => { this.on(DESTROYED, () => reject(new Error('stream destroyed'))) - this.on('end', () => resolve()) this.on('error', er => reject(er)) + this.on('end', () => resolve()) }) } diff --git a/deps/npm/node_modules/minipass/package.json b/deps/npm/node_modules/minipass/package.json index 54f62d56d46d86..165fa662ab4a7c 100644 --- a/deps/npm/node_modules/minipass/package.json +++ b/deps/npm/node_modules/minipass/package.json @@ -1,6 +1,6 @@ { "name": "minipass", - "version": "3.1.3", + "version": "3.1.5", "description": "minimal implementation of a PassThrough stream", "main": "index.js", "dependencies": { @@ -8,7 +8,7 @@ }, "devDependencies": { "end-of-stream": "^1.4.0", - "tap": "^14.6.5", + "tap": "^15.0.9", "through2": "^2.0.3" }, "scripts": { diff --git a/deps/npm/package.json b/deps/npm/package.json index 20b80c7ebe21c7..38b45947706dc7 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "7.23.0", + "version": "7.24.0", "name": "npm", "description": "a package manager for JavaScript", "workspaces": [ @@ -74,7 +74,7 @@ "graceful-fs": "^4.2.8", "hosted-git-info": "^4.0.2", "ini": "^2.0.0", - "init-package-json": "^2.0.4", + "init-package-json": "^2.0.5", "is-cidr": "^4.0.2", "json-parse-even-better-errors": "^2.3.1", "libnpmaccess": "^4.0.2", diff --git a/deps/npm/tap-snapshots/test/lib/config.js.test.cjs b/deps/npm/tap-snapshots/test/lib/config.js.test.cjs index 8f349a6f54249e..dab7ef55f64e82 100644 --- a/deps/npm/tap-snapshots/test/lib/config.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/config.js.test.cjs @@ -146,7 +146,7 @@ exports[`test/lib/config.js TAP config list --json > output matches snapshot 1`] "unicode": false, "update-notifier": true, "usage": false, - "user-agent": "npm/{NPM-VERSION} node/{NODE-VERSION} {PLATFORM} {ARCH} workspaces/false", + "user-agent": "npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}", "version": false, "versions": false, "viewer": "{VIEWER}", @@ -296,7 +296,7 @@ umask = 0 unicode = false update-notifier = true usage = false -user-agent = "npm/{NPM-VERSION} node/{NODE-VERSION} {PLATFORM} {ARCH} workspaces/false" +user-agent = "npm/{npm-version} node/{node-version} {platform} {arch} workspaces/{workspaces} {ci}" ; userconfig = "{HOME}/.npmrc" ; overridden by cli version = false versions = false diff --git a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs index 4eb5ea3bc5df59..c963ca2040e6f5 100644 --- a/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/utils/error-message.js.test.cjs @@ -180,6 +180,40 @@ Object { } ` +exports[`test/lib/utils/error-message.js TAP args are cleaned > must match snapshot 1`] = ` +Object { + "detail": Array [ + Array [ + "signal", + "SIGYOLO", + ], + Array [ + "command", + "some command", + "a", + "r", + "g", + "s", + "https://evil:***@npmjs.org", + ], + Array [ + "", + "stdout", + ], + Array [ + "", + "stderr", + ], + ], + "summary": Array [ + Array [ + "", + "cmd err", + ], + ], +} +` + exports[`test/lib/utils/error-message.js TAP bad engine with config loaded > must match snapshot 1`] = ` Object { "detail": Array [ diff --git a/deps/npm/tap-snapshots/test/lib/view.js.test.cjs b/deps/npm/tap-snapshots/test/lib/view.js.test.cjs index 27ba7b1eb69276..9ed8334138cf85 100644 --- a/deps/npm/tap-snapshots/test/lib/view.js.test.cjs +++ b/deps/npm/tap-snapshots/test/lib/view.js.test.cjs @@ -82,7 +82,7 @@ dist dist-tags: latest: 1.0.0 -published {TIME} ago +published yesterday ` exports[`test/lib/view.js TAP should log info of package in current working dir specific version > must match snapshot 1`] = ` @@ -99,7 +99,7 @@ dist dist-tags: latest: 1.0.0 -published {TIME} ago +published yesterday ` exports[`test/lib/view.js TAP should log package info package from git > must match snapshot 1`] = ` @@ -302,7 +302,24 @@ dist dist-tags: latest: 1.0.0 -published {TIME} ago +published yesterday +` + +exports[`test/lib/view.js TAP should log package info package with semver range > must match snapshot 1`] = ` + + +blue@1.0.0 | Proprietary | deps: none | versions: 2 + +dist +.tarball:http://hm.blue.com/1.0.0.tgz +.shasum:123 +.integrity:--- +.unpackedSize:1 B + +dist-tags: +latest: 1.0.0 + +published yesterday ` exports[`test/lib/view.js TAP workspaces all workspaces --json > must match snapshot 1`] = ` diff --git a/deps/npm/test/lib/search.js b/deps/npm/test/lib/search.js index 510a470f48088e..55b584b8aa7dc5 100644 --- a/deps/npm/test/lib/search.js +++ b/deps/npm/test/lib/search.js @@ -130,6 +130,37 @@ t.test('search --json', (t) => { src.end() }) +t.test('search --json', (t) => { + const src = new Minipass() + src.objectMode = true + + npm.flatOptions.json = true + config.json = true + const libnpmsearch = { + stream () { + return src + }, + } + + const Search = t.mock('../../lib/search.js', { + ...mocks, + libnpmsearch, + }) + const search = new Search(npm) + + search.exec(['foo'], (err) => { + if (err) + throw err + + t.equal(result, '\n[]\n', 'should have expected empty square brackets') + + config.json = false + t.end() + }) + + src.end() +}) + t.test('search --searchexclude --searchopts', t => { npm.flatOptions.search = { ...flatOptions.search, diff --git a/deps/npm/test/lib/utils/config/definitions.js b/deps/npm/test/lib/utils/config/definitions.js index 65193020d050c5..88993303b539cb 100644 --- a/deps/npm/test/lib/utils/config/definitions.js +++ b/deps/npm/test/lib/utils/config/definitions.js @@ -747,7 +747,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectNoCI) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') obj['ci-name'] = 'foo' obj['user-agent'] = definitions['user-agent'].default @@ -755,7 +755,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectCI) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') delete obj['ci-name'] obj.workspaces = true @@ -764,7 +764,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectWorkspaces) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') delete obj.workspaces obj.workspace = ['foo'] @@ -772,7 +772,7 @@ t.test('user-agent', t => { definitions['user-agent'].flatten('user-agent', obj, flat) t.equal(flat.userAgent, expectWorkspaces) t.equal(process.env.npm_config_user_agent, flat.userAgent, 'npm_user_config environment is set') - t.equal(obj['user-agent'], flat.userAgent, 'config user-agent template is translated') + t.not(obj['user-agent'], flat.userAgent, 'config user-agent template is not translated') t.end() }) @@ -853,3 +853,25 @@ t.test('package-lock-only', t => { t.strictSame(flat, { packageLock: false, packageLockOnly: false }) t.end() }) + +t.test('workspaces', t => { + const obj = { + workspaces: true, + 'user-agent': definitions['user-agent'].default, + } + const flat = {} + definitions.workspaces.flatten('workspaces', obj, flat) + t.match(flat.userAgent, /workspaces\/true/) + t.end() +}) + +t.test('workspace', t => { + const obj = { + workspace: ['workspace-a'], + 'user-agent': definitions['user-agent'].default, + } + const flat = {} + definitions.workspace.flatten('workspaces', obj, flat) + t.match(flat.userAgent, /workspaces\/true/) + t.end() +}) diff --git a/deps/npm/test/lib/utils/did-you-mean.js b/deps/npm/test/lib/utils/did-you-mean.js index 15712b665be6eb..1285d5300853bc 100644 --- a/deps/npm/test/lib/utils/did-you-mean.js +++ b/deps/npm/test/lib/utils/did-you-mean.js @@ -5,34 +5,55 @@ const dym = require('../../../lib/utils/did-you-mean.js') t.test('did-you-mean', t => { npm.load(err => { t.notOk(err) - t.test('nistall', async t => { - const result = await dym(npm, npm.localPrefix, 'nistall') - t.match(result, 'npm install') - }) - t.test('sttest', async t => { - const result = await dym(npm, npm.localPrefix, 'sttest') - t.match(result, 'npm test') - t.match(result, 'npm run posttest') + t.test('with package.json', t => { + const testdir = t.testdir({ + 'package.json': JSON.stringify({ + bin: { + npx: 'exists', + }, + scripts: { + install: 'exists', + posttest: 'exists', + }, + }), + }) + t.test('nistall', async t => { + const result = await dym(npm, testdir, 'nistall') + t.match(result, 'npm install') + }) + t.test('sttest', async t => { + const result = await dym(npm, testdir, 'sttest') + t.match(result, 'npm test') + t.match(result, 'npm run posttest') + }) + t.test('npz', async t => { + const result = await dym(npm, testdir, 'npxx') + t.match(result, 'npm exec npx') + }) + t.test('qwuijbo', async t => { + const result = await dym(npm, testdir, 'qwuijbo') + t.match(result, '') + }) + t.end() }) - t.test('npz', async t => { - const result = await dym(npm, npm.localPrefix, 'npxx') - t.match(result, 'npm exec npx') + t.test('with no package.json', t => { + const testdir = t.testdir({}) + t.test('nistall', async t => { + const result = await dym(npm, testdir, 'nistall') + t.match(result, 'npm install') + }) + t.end() }) - t.test('qwuijbo', async t => { - const result = await dym(npm, npm.localPrefix, 'qwuijbo') - t.match(result, '') + t.test('missing bin and script properties', async t => { + const testdir = t.testdir({ + 'package.json': JSON.stringify({ + name: 'missing-bin', + }), + }) + + const result = await dym(npm, testdir, 'nistall') + t.match(result, 'npm install') }) t.end() }) }) - -t.test('missing bin and script properties', async t => { - const path = t.testdir({ - 'package.json': JSON.stringify({ - name: 'missing-bin', - }), - }) - - const result = await dym(npm, path, 'nistall') - t.match(result, 'npm install') -}) diff --git a/deps/npm/test/lib/utils/error-message.js b/deps/npm/test/lib/utils/error-message.js index d1c67a95137c44..6b2b5c9222e77a 100644 --- a/deps/npm/test/lib/utils/error-message.js +++ b/deps/npm/test/lib/utils/error-message.js @@ -201,6 +201,17 @@ t.test('default message', t => { t.end() }) +t.test('args are cleaned', t => { + t.matchSnapshot(errorMessage(Object.assign(new Error('cmd err'), { + cmd: 'some command', + signal: 'SIGYOLO', + args: ['a', 'r', 'g', 's', 'https://evil:password@npmjs.org'], + stdout: 'stdout', + stderr: 'stderr', + }), npm)) + t.end() +}) + t.test('eacces/eperm', t => { const runTest = (windows, loaded, cachePath, cacheDest) => t => { if (windows) diff --git a/deps/npm/test/lib/view.js b/deps/npm/test/lib/view.js index 793917adc6476d..096ababb29ae83 100644 --- a/deps/npm/test/lib/view.js +++ b/deps/npm/test/lib/view.js @@ -17,6 +17,9 @@ const cleanLogs = () => { console.log = fn } +// 25 hours ago +const yesterday = new Date(Date.now() - 1000 * 60 * 60 * 25) + const packument = (nv, opts) => { if (!opts.fullMetadata) throw new Error('must fetch fullMetadata') @@ -40,7 +43,7 @@ const packument = (nv, opts) => { latest: '1.0.0', }, time: { - '1.0.0': '2019-08-06T16:21:09.842Z', + '1.0.0': yesterday, }, versions: { '1.0.0': { @@ -332,6 +335,13 @@ t.test('should log package info', t => { }) }) + t.test('package with semver range', t => { + view.exec(['blue@^1.0.0'], () => { + t.matchSnapshot(logs) + t.end() + }) + }) + t.test('package with no modified time', t => { viewUnicode.exec(['cyan@1.0.0'], () => { t.matchSnapshot(logs) diff --git a/doc/.eslintrc.yaml b/doc/.eslintrc.yaml index 8e01bea6abd8a7..fbc115669a7166 100644 --- a/doc/.eslintrc.yaml +++ b/doc/.eslintrc.yaml @@ -1,14 +1,14 @@ ## Docs-specific linter rules rules: - # ease some restrictions in doc examples + # Ease some restrictions in doc examples no-restricted-properties: off no-undef: off no-unused-expressions: off no-unused-vars: off symbol-description: off - # add new ECMAScript features gradually + # Add new ECMAScript features gradually no-var: error prefer-const: error prefer-rest-params: error diff --git a/doc/api/addons.md b/doc/api/addons.md index 78814a97bba594..a906306b2cd1bc 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -1,6 +1,7 @@ # C++ addons + _Addons_ are dynamically-linked shared objects written in C++. The diff --git a/doc/api/assert.md b/doc/api/assert.md index 5215ea06816e3a..3848cde97f65e8 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -456,7 +456,9 @@ An alias of [`assert.ok()`][]. @@ -1127,7 +1129,9 @@ assert.doesNotThrow( @@ -1635,7 +1641,9 @@ instead of the [`AssertionError`][]. > Stability: 1 - Experimental @@ -458,7 +462,9 @@ multiple worker threads. ### `new buffer.Blob([sources[, options]])` * Returns: {Promise} @@ -498,14 +506,18 @@ the `Blob` data. ### `blob.size` The total size of the `Blob` in bytes. ### `blob.slice([start, [end, [type]]])` * `start` {number} The starting index. @@ -526,7 +538,9 @@ Returns a new `ReadableStream` that allows the content of the `Blob` to be read. ### `blob.text()` * Returns: {Promise} @@ -536,7 +550,9 @@ UTF-8 string. ### `blob.type` * Type: {string} @@ -574,7 +590,7 @@ mc1.port2.postMessage(blob); mc2.port2.postMessage(blob); // The Blob is still usable after posting. -data.text().then(console.log); +blob.text().then(console.log); ``` ```cjs @@ -601,7 +617,7 @@ mc1.port2.postMessage(blob); mc2.port2.postMessage(blob); // The Blob is still usable after posting. -data.text().then(console.log); +blob.text().then(console.log); ``` ## Class: `Buffer` diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 3f67459effd8ec..340a0f0577733d 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -146,7 +146,9 @@ exec('"my script.cmd" a b', (err, stdout, stderr) => { + Node.js comes with a variety of CLI options. These options expose built-in @@ -189,7 +190,9 @@ code from strings throw an exception instead. This does not affect the Node.js ### `--dns-result-order=order` Set the default value of `verbatim` in [`dns.lookup()`][] and @@ -212,7 +215,9 @@ against FIPS-compatible OpenSSL.) @@ -362,7 +367,9 @@ be added. ### `--heapsnapshot-near-heap-limit=max_count` > Stability: 1 - Experimental @@ -600,7 +607,7 @@ This option is a no-op. It is kept for compatibility. ### `--no-addons` Disable the `node-addons` exports condition as well as disable loading @@ -631,7 +638,7 @@ dynamically when `async_hooks` is enabled. ### `--no-global-search-paths` Do not search modules from global paths like `$HOME/.node_modules` and @@ -646,7 +653,9 @@ Silence all process warnings (including deprecations). ### `--node-memory-debug` Enable extra debug checks for memory leaks in Node.js internals. This is diff --git a/doc/api/corepack.md b/doc/api/corepack.md index f5ee64e5158e10..fc6e2ab15e81e4 100644 --- a/doc/api/corepack.md +++ b/doc/api/corepack.md @@ -1,6 +1,7 @@ # Corepack + > Stability: 1 - Experimental diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 00bdfbc6fdc5a2..b01203493b059e 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -3375,7 +3375,7 @@ generateKey('hmac', { length: 64 }, (err, key) => { + Node.js APIs might be deprecated for any of the following reasons: @@ -2706,6 +2707,9 @@ Use `fs.rm(path, { recursive: true, force: true })`, ### DEP0148: Folder mappings in `"exports"` (trailing `"/"`) @@ -2823,7 +2829,7 @@ changes: - version: REPLACEME pr-url: https://github.com/nodejs/node/pull/40117 description: Runtime deprecation. - - version: REPLACEME + - version: v16.10.0 pr-url: https://github.com/nodejs/node/pull/40039 description: Documentation-only deprecation with `--pending-deprecation` support. @@ -2834,6 +2840,28 @@ Type: Runtime The remapping of specifiers ending in `"/"` like `import 'pkg/x/'` is deprecated for package `"exports"` and `"imports"` pattern resolutions. +### DEP0XXX: `.aborted` property and `'abort'`, `'aborted'` event in `http` + + +Type: Documentation-only + +Move to {Stream} API instead, as the [`http.ClientRequest`][], +[`http.ServerResponse`][], and [`http.IncomingMessage`][] are all stream-based. +Check `stream.destroyed` instead of the `.aborted` property, and listen for +`'close'` instead of `'abort'`, `'aborted'` event. + +The `.aborted` property and `'abort'` event are only useful for detecting +`.abort()` calls. For closing a request early, use the Stream +`.destroy([error])` then check the `.destroyed` property and `'close'` event +should have the same effect. The receiving end should also check the +[`readable.readableEnded`][] value on [`http.IncomingMessage`][] to get whether +it was an aborted or graceful destroy. + [Legacy URL API]: url.md#legacy-url-api [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 @@ -2891,6 +2919,9 @@ for package `"exports"` and `"imports"` pattern resolutions. [`fs.read()`]: fs.md#fsreadfd-buffer-offset-length-position-callback [`fs.readSync()`]: fs.md#fsreadsyncfd-buffer-offset-length-position [`fs.stat()`]: fs.md#fsstatpath-options-callback +[`http.ClientRequest`]: http.md#class-httpclientrequest +[`http.IncomingMessage`]: http.md#class-httpincomingmessage +[`http.ServerResponse`]: http.md#class-httpserverresponse [`http.get()`]: http.md#httpgetoptions-callback [`http.request()`]: http.md#httprequestoptions-callback [`https.get()`]: https.md#httpsgetoptions-callback @@ -2903,6 +2934,7 @@ for package `"exports"` and `"imports"` pattern resolutions. [`process.env`]: process.md#processenv [`process.mainModule`]: process.md#processmainmodule [`punycode`]: punycode.md +[`readable.readableEnded`]: stream.md#readablereadableended [`request.abort()`]: http.md#requestabort [`request.connection`]: http.md#requestconnection [`request.destroy()`]: http.md#requestdestroyerror @@ -2964,6 +2996,5 @@ for package `"exports"` and `"imports"` pattern resolutions. [legacy `urlObject`]: url.md#legacy-urlobject [static methods of `crypto.Certificate()`]: crypto.md#class-certificate [subpath exports]: packages.md#subpath-exports -[subpath folder mappings]: packages.md#subpath-folder-mappings [subpath imports]: packages.md#subpath-imports [subpath patterns]: packages.md#subpath-patterns diff --git a/doc/api/diagnostics_channel.md b/doc/api/diagnostics_channel.md index 15ee98fd2177f5..6c4ace3bbd615e 100644 --- a/doc/api/diagnostics_channel.md +++ b/doc/api/diagnostics_channel.md @@ -79,6 +79,12 @@ if (channel.hasSubscribers) { #### `diagnostics_channel.hasSubscribers(name)` + + * `name` {string|symbol} The channel name * Returns: {boolean} If there are active subscribers @@ -106,6 +112,12 @@ if (diagnostics_channel.hasSubscribers('my-channel')) { #### `diagnostics_channel.channel(name)` + + * `name` {string|symbol} The channel name * Returns: {Channel} The named channel object @@ -127,6 +139,12 @@ const channel = diagnostics_channel.channel('my-channel'); ### Class: `Channel` + + The class `Channel` represents an individual named channel within the data pipeline. It is use to track subscribers and to publish messages when there are subscribers present. It exists as a separate object to avoid channel @@ -137,6 +155,12 @@ with `new Channel(name)` is not supported. #### `channel.hasSubscribers` + + * Returns: {boolean} If there are active subscribers Check if there are active subscribers to this channel. This is helpful if @@ -167,6 +191,12 @@ if (channel.hasSubscribers) { #### `channel.publish(message)` + + * `message` {any} The message to send to the channel subscribers Publish a message to any subscribers to the channel. This will trigger @@ -194,6 +224,12 @@ channel.publish({ #### `channel.subscribe(onMessage)` + + * `onMessage` {Function} The handler to receive channel messages * `message` {any} The message data * `name` {string|symbol} The name of the channel @@ -224,6 +260,12 @@ channel.subscribe((message, name) => { #### `channel.unsubscribe(onMessage)` + + * `onMessage` {Function} The previous subscribed handler to remove Remove a message handler previously registered to this channel with diff --git a/doc/api/dns.md b/doc/api/dns.md index ef90e15a04dc4b..1a5ecd80b9f3b3 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -97,7 +97,9 @@ The following methods from the `dns` module are available: * `order` {string} must be `'ipv4first'` or `'verbatim'`. @@ -1168,7 +1172,9 @@ is one of the [DNS error codes](). ### `dnsPromises.setDefaultResultOrder(order)` * `order` {string} must be `'ipv4first'` or `'verbatim'`. diff --git a/doc/api/documentation.md b/doc/api/documentation.md index a7747d91c16ee3..9100354b361644 100644 --- a/doc/api/documentation.md +++ b/doc/api/documentation.md @@ -1,6 +1,7 @@ # About this documentation + Welcome to the official API reference documentation for Node.js! @@ -51,6 +52,7 @@ a command-line flag. Experimental features may also emit a [warning][]. ## Stability overview + ## JSON output diff --git a/doc/api/errors.md b/doc/api/errors.md index a03b1f6fc2572a..b0b0753f400401 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1,6 +1,7 @@ # Errors + Applications running in Node.js will generally experience four categories of @@ -1002,7 +1003,9 @@ An unknown Diffie-Hellman group name was given. See ### `ERR_CRYPTO_UNSUPPORTED_OPERATION` An attempt to invoke an unsupported crypto operation was made. @@ -1030,7 +1033,7 @@ The [debugger][] timed out waiting for the required host/port to be free. ### `ERR_DLOPEN_DISABLED` Loading native addons has been disabled using [`--no-addons`][]. @@ -1667,7 +1670,9 @@ An IP address is not valid. ### `ERR_INVALID_MODULE` An attempt was made to load a module that does not exist or was otherwise not diff --git a/doc/api/esm.md b/doc/api/esm.md index a3aa832e7c8d82..9ec67330000907 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -1,7 +1,9 @@ # Modules: ECMAScript modules + + @@ -295,7 +299,9 @@ added: - v13.9.0 - v12.16.2 changes: - - version: v16.2.0 + - version: + - v16.2.0 + - v14.18.0 pr-url: https://github.com/nodejs/node/pull/38587 description: Add support for WHATWG `URL` object to `parentURL` parameter. --> @@ -615,7 +621,7 @@ CommonJS modules loaded. * `defaultResolve` {Function} The Node.js default resolver. * Returns: {Object} * `format` {string|null|undefined} - `'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'` + `'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'` * `url` {string} The absolute url to the import target (such as `file://…`) The `resolve` hook returns the resolved file URL for a given module specifier @@ -686,7 +692,7 @@ export async function resolve(specifier, context, defaultResolve) { * `url` {string} * `context` {Object} * `format` {string|null|undefined} The format optionally supplied by the - `resolve` hook. + `resolve` hook. * `defaultLoad` {Function} * Returns: {Object} * `format` {string} @@ -1066,9 +1072,8 @@ The resolver can throw the following errors: > 1. Set _resolved_ to the URL resolution of _specifier_ relative to > _parentURL_. > 1. Otherwise, if _specifier_ starts with _"#"_, then -> 1. Set _resolved_ to the destructured value of the result of -> **PACKAGE_IMPORTS_RESOLVE**(_specifier_, _parentURL_, -> _defaultConditions_). +> 1. Set _resolved_ to the result of **PACKAGE_IMPORTS_RESOLVE**(_specifier_, +> _parentURL_, _defaultConditions_). > 1. Otherwise, > 1. Note: _specifier_ is now a bare specifier. > 1. Set _resolved_ the result of @@ -1101,7 +1106,7 @@ The resolver can throw the following errors: > 1. If _packageName_ starts with _"."_ or contains _"\\"_ or _"%"_, then > 1. Throw an _Invalid Module Specifier_ error. > 1. Let _packageSubpath_ be _"."_ concatenated with the substring of -> _packageSpecifier_ from the position at the length of _packageName_. +> _packageSpecifier_ from the position at the length of _packageName_. > 1. Let _selfUrl_ be the result of > **PACKAGE_SELF_RESOLVE**(_packageName_, _packageSubpath_, _parentURL_). > 1. If _selfUrl_ is not **undefined**, return _selfUrl_. @@ -1119,11 +1124,10 @@ The resolver can throw the following errors: > 1. If _pjson_ is not **null** and _pjson_._exports_ is not **null** or > **undefined**, then > 1. Let _exports_ be _pjson.exports_. -> 1. Return the _resolved_ destructured value of the result of -> **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _packageSubpath_, -> _pjson.exports_, _defaultConditions_). +> 1. Return the result of **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, +> _packageSubpath_, _pjson.exports_, _defaultConditions_). > 1. Otherwise, if _packageSubpath_ is equal to _"."_, then -> 1. Return the result applying the legacy **LOAD_AS_DIRECTORY** +> 1. Return the result of applying the legacy **LOAD_AS_DIRECTORY** > CommonJS resolver to _packageURL_, throwing a _Module Not Found_ > error for no resolution. > 1. Otherwise, @@ -1140,13 +1144,14 @@ The resolver can throw the following errors: > **undefined**, then > 1. Return **undefined**. > 1. If _pjson.name_ is equal to _packageName_, then -> 1. Return the _resolved_ destructured value of the result of -> **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _subpath_, _pjson.exports_, -> _defaultConditions_). +> 1. Return the result of **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, +> _subpath_, _pjson.exports_, _defaultConditions_). > 1. Otherwise, return **undefined**. **PACKAGE_EXPORTS_RESOLVE**(_packageURL_, _subpath_, _exports_, _conditions_) +> 1. If _subpath_ ends in _"/"_, then +> 1. Throw an _Invalid Module Specifier_ error. > 1. If _exports_ is an Object with both a key starting with _"."_ and a key not > starting with _"."_, throw an _Invalid Package Configuration_ error. > 1. If _subpath_ is equal to _"."_, then @@ -1160,53 +1165,45 @@ The resolver can throw the following errors: > 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**( > _packageURL_, _mainExport_, _""_, **false**, **false**, > _conditions_). -> 1. If _resolved_ is not **null** or **undefined**, then -> 1. Return _resolved_. +> 1. If _resolved_ is not **null** or **undefined**, return _resolved_. > 1. Otherwise, if _exports_ is an Object and all keys of _exports_ start with > _"."_, then > 1. Let _matchKey_ be the string _"./"_ concatenated with _subpath_. -> 1. Let _resolvedMatch_ be result of **PACKAGE_IMPORTS_EXPORTS_RESOLVE**( +> 1. Let _resolved_ be the result of **PACKAGE_IMPORTS_EXPORTS_RESOLVE**( > _matchKey_, _exports_, _packageURL_, **false**, _conditions_). -> 1. If _resolvedMatch_._resolve_ is not **null** or **undefined**, then -> 1. Return _resolvedMatch_. +> 1. If _resolved_ is not **null** or **undefined**, return _resolved_. > 1. Throw a _Package Path Not Exported_ error. **PACKAGE_IMPORTS_RESOLVE**(_specifier_, _parentURL_, _conditions_) > 1. Assert: _specifier_ begins with _"#"_. -> 1. If _specifier_ is exactly equal to _"#"_ or starts with _"#/"_, then +> 1. If _specifier_ is exactly equal to _"#"_, starts with _"#/"_, or ends in +> _"/"_, then > 1. Throw an _Invalid Module Specifier_ error. > 1. Let _packageURL_ be the result of **READ_PACKAGE_SCOPE**(_parentURL_). > 1. If _packageURL_ is not **null**, then > 1. Let _pjson_ be the result of **READ_PACKAGE_JSON**(_packageURL_). > 1. If _pjson.imports_ is a non-null Object, then -> 1. Let _resolvedMatch_ be the result of -> **PACKAGE_IMPORTS_EXPORTS_RESOLVE**(_specifier_, _pjson.imports_, -> _packageURL_, **true**, _conditions_). -> 1. If _resolvedMatch_._resolve_ is not **null** or **undefined**, then -> 1. Return _resolvedMatch_. +> 1. Let _resolved_ be the result of **PACKAGE_IMPORTS_EXPORTS_RESOLVE**( +> _specifier_, _pjson.imports_, _packageURL_, **true**, _conditions_). +> 1. If _resolved_ is not **null** or **undefined**, return _resolved_. > 1. Throw a _Package Import Not Defined_ error. **PACKAGE_IMPORTS_EXPORTS_RESOLVE**(_matchKey_, _matchObj_, _packageURL_, _isImports_, _conditions_) -> 1. If _matchKey_ is a key of _matchObj_ and does not end in _"/"_ or contain -> _"*"_, then +> 1. Assert: _matchKey_ does not end in _"/"_. +> 1. If _matchKey_ is a key of _matchObj_ and does not contain _"*"_, then > 1. Let _target_ be the value of _matchObj_\[_matchKey_\]. -> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**( -> _packageURL_, _target_, _""_, **false**, _isImports_, _conditions_). -> 1. Return the object _{ resolved, exact: **true** }_. -> 1. Let _expansionKeys_ be the list of keys of _matchObj_ either ending in -> _"/"_ or containing only a single _"*"_, sorted by the sorting function -> **PATTERN_KEY_COMPARE** which orders in descending order of specificity. +> 1. Return the result of **PACKAGE_TARGET_RESOLVE**(_packageURL_, _target_, +> _""_, **false**, _isImports_, _conditions_). +> 1. Let _expansionKeys_ be the list of keys of _matchObj_ containing only a +> single _"*"_, sorted by the sorting function **PATTERN_KEY_COMPARE** which +> orders in descending order of specificity. > 1. For each key _expansionKey_ in _expansionKeys_, do -> 1. Let _patternBase_ be **null**. -> 1. If _expansionKey_ contains _"*"_, set _patternBase_ to the substring of -> _expansionKey_ up to but excluding the first _"*"_ character. -> 1. If _patternBase_ is not **null** and _matchKey_ starts with but is not -> equal to _patternBase_, then -> 1. If _matchKey_ ends with _"/"_, throw an _Invalid Module Specifier_ -> error. +> 1. Let _patternBase_ be the substring of _expansionKey_ up to but excluding +> the first _"*"_ character. +> 1. If _matchKey_ starts with but is not equal to _patternBase_, then > 1. Let _patternTrailer_ be the substring of _expansionKey_ from the > index after the first _"*"_ character. > 1. If _patternTrailer_ has zero length, or if _matchKey_ ends with @@ -1216,20 +1213,9 @@ _isImports_, _conditions_) > 1. Let _subpath_ be the substring of _matchKey_ starting at the > index of the length of _patternBase_ up to the length of > _matchKey_ minus the length of _patternTrailer_. -> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**( -> _packageURL_, _target_, _subpath_, **true**, _isImports_, -> _conditions_). -> 1. Return the object _{ resolved, exact: **true** }_. -> 1. Otherwise if _patternBase_ is **null** and _matchKey_ starts with -> _expansionKey_, then -> 1. Let _target_ be the value of _matchObj_\[_expansionKey_\]. -> 1. Let _subpath_ be the substring of _matchKey_ starting at the -> index of the length of _expansionKey_. -> 1. Let _resolved_ be the result of **PACKAGE_TARGET_RESOLVE**( -> _packageURL_, _target_, _subpath_, **false**, _isImports_, -> _conditions_). -> 1. Return the object _{ resolved, exact: **false** }_. -> 1. Return the object _{ resolved: **null**, exact: **true** }_. +> 1. Return the result of **PACKAGE_TARGET_RESOLVE**(_packageURL_, +> _target_, _subpath_, **true**, _isImports_, _conditions_). +> 1. Return **null**. **PATTERN_KEY_COMPARE**(_keyA_, _keyB_) diff --git a/doc/api/fs.md b/doc/api/fs.md index e3aa603dc5a870..8433f6ce832192 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -230,6 +230,99 @@ try { } ``` +#### `filehandle.createReadStream([options])` + + +* `options` {Object} + * `encoding` {string} **Default:** `null` + * `autoClose` {boolean} **Default:** `true` + * `emitClose` {boolean} **Default:** `true` + * `start` {integer} + * `end` {integer} **Default:** `Infinity` + * `highWaterMark` {integer} **Default:** `64 * 1024` +* Returns: {fs.ReadStream} + +Unlike the 16 kb default `highWaterMark` for a {stream.Readable}, the stream +returned by this method has a default `highWaterMark` of 64 kb. + +`options` can include `start` and `end` values to read a range of bytes from +the file instead of the entire file. Both `start` and `end` are inclusive and +start counting at 0, allowed values are in the +[0, [`Number.MAX_SAFE_INTEGER`][]] range. If `start` is +omitted or `undefined`, `filehandle.createReadStream()` reads sequentially from +the current file position. The `encoding` can be any one of those accepted by +{Buffer}. + +If the `FileHandle` points to a character device that only supports blocking +reads (such as keyboard or sound card), read operations do not finish until data +is available. This can prevent the process from exiting and the stream from +closing naturally. + +By default, the stream will emit a `'close'` event after it has been +destroyed. Set the `emitClose` option to `false` to change this behavior. + +```mjs +import { open } from 'fs/promises'; + +const fd = await open('/dev/input/event0'); +// Create a stream from some character device. +const stream = fd.createReadStream(); +setTimeout(() => { + stream.close(); // This may not close the stream. + // Artificially marking end-of-stream, as if the underlying resource had + // indicated end-of-file by itself, allows the stream to close. + // This does not cancel pending read operations, and if there is such an + // operation, the process may still not be able to exit successfully + // until it finishes. + stream.push(null); + stream.read(0); +}, 100); +``` + +If `autoClose` is false, then the file descriptor won't be closed, even if +there's an error. It is the application's responsibility to close it and make +sure there's no file descriptor leak. If `autoClose` is set to true (default +behavior), on `'error'` or `'end'` the file descriptor will be closed +automatically. + +An example to read the last 10 bytes of a file which is 100 bytes long: + +```mjs +import { open } from 'fs/promises'; + +const fd = await open('sample.txt'); +fd.createReadStream({ start: 90, end: 99 }); +``` + +#### `filehandle.createWriteStream([options])` + + +* `options` {Object} + * `encoding` {string} **Default:** `'utf8'` + * `autoClose` {boolean} **Default:** `true` + * `emitClose` {boolean} **Default:** `true` + * `start` {integer} +* Returns: {fs.WriteStream} + +`options` may also include a `start` option to allow writing data at some +position past the beginning of the file, allowed values are in the +[0, [`Number.MAX_SAFE_INTEGER`][]] range. Modifying a file rather than replacing +it may require the `flags` `open` option to be set to `r+` rather than the +default `r`. The `encoding` can be any one of those accepted by {Buffer}. + +If `autoClose` is set to true (default behavior) on `'error'` or `'finish'` +the file descriptor will be closed automatically. If `autoClose` is false, +then the file descriptor won't be closed, even if there's an error. +It is the application's responsibility to close it and make sure there's no +file descriptor leak. + +By default, the stream will emit a `'close'` event after it has been +destroyed. Set the `emitClose` option to `false` to change this behavior. + #### `filehandle.datasync()` @@ -1298,7 +1393,9 @@ The `atime` and `mtime` arguments follow these rules: ### `fsPromises.watch(filename[, options])` * `filename` {string|Buffer|URL} @@ -1349,12 +1446,14 @@ All the [caveats][] for `fs.watch()` also apply to `fsPromises.watch()`. @@ -6601,7 +6700,7 @@ a string, a {Buffer}, or a {URL} object using the `file:` protocol. #### String paths -String form paths are interpreted as UTF-8 character sequences identifying +String from paths are interpreted as UTF-8 character sequences identifying the absolute or relative filename. Relative paths will be resolved relative to the current working directory as determined by calling `process.cwd()`. @@ -6925,8 +7024,6 @@ the file contents. [MSDN-Rel-Path]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file#fully-qualified-vs-relative-paths [MSDN-Using-Streams]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/using-streams [Naming Files, Paths, and Namespaces]: https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file -[Readable Stream]: stream.md#class-streamreadable -[Writable Stream]: stream.md#class-streamwritable [`AHAFS`]: https://developer.ibm.com/articles/au-aix_event_infrastructure/ [`Buffer.byteLength`]: buffer.md#static-method-bufferbytelengthstring-encoding [`FSEvents`]: https://developer.apple.com/documentation/coreservices/file_system_events diff --git a/doc/api/globals.md b/doc/api/globals.md index 79f0932b1813ea..701ab79d57b733 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -1,6 +1,7 @@ # Global objects + These objects are available in all modules. The following variables may appear diff --git a/doc/api/http.md b/doc/api/http.md index 0f5f5a8bb1145d..d059469de294c6 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -407,8 +407,11 @@ body which has been transmitted are equal or not. ### Event: `'abort'` +> Stability: 0 - Deprecated. Listen for the `'close'` event instead. + Emitted when the request has been aborted by the client. This event is only emitted on the first call to `abort()`. @@ -564,7 +567,7 @@ added: v0.7.8 --> Emitted when the underlying socket times out from inactivity. This only notifies -that the socket has been idle. The request must be aborted manually. +that the socket has been idle. The request must be destroyed manually. See also: [`request.setTimeout()`][]. @@ -645,12 +648,15 @@ in the response to be dropped and the socket to be destroyed. ### `request.aborted` +> Stability: 0 - Deprecated. Check [`request.destroyed`][] instead. + * {boolean} The `request.aborted` property will be `true` if the request has @@ -1354,17 +1360,17 @@ explicitly. ### `server.maxRequestsPerSocket` -* {number} Requests per socket. **Default:** null (no limit) +* {number} Requests per socket. **Default:** 0 (no limit) The maximum number of requests socket can handle before closing keep alive connection. -A value of `null` will disable the limit. +A value of `0` will disable the limit. -When limit is reach it will set `Connection` header value to `closed`, +When the limit is reached it will set the `Connection` header value to `close`, but will not actually close the connection, subsequent requests sent after the limit is reached will get `503 Service Unavailable` as a response. @@ -1988,8 +1994,11 @@ may be reused multiple times in case of keep-alive. ### Event: `'aborted'` +> Stability: 0 - Deprecated. Listen for `'close'` event instead. + Emitted when the request has been aborted. ### Event: `'close'` @@ -2002,8 +2011,11 @@ Indicates that the underlying connection was closed. ### `message.aborted` +> Stability: 0 - Deprecated. Check `message.destroyed` from {stream.Readable}. + * {boolean} The `message.aborted` property will be `true` if the request has @@ -2851,7 +2863,9 @@ This can be overridden for servers and client requests by passing the * `windowSize` {number} @@ -2625,7 +2627,9 @@ the given `Buffer` as generated by `http2.getPackedSettings()`. ### `http2.sensitiveHeaders` * {symbol} diff --git a/doc/api/https.md b/doc/api/https.md index 98a845994a78fa..a2dbeb473a994d 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -251,13 +251,15 @@ Global instance of [`https.Agent`][] for all HTTPS client requests. + Node.js has many features that make it easier to write internationalized diff --git a/doc/api/module.md b/doc/api/module.md index 0079d726c3ce7c..519240841a644f 100644 --- a/doc/api/module.md +++ b/doc/api/module.md @@ -1,6 +1,7 @@ # Modules: `module` API + diff --git a/doc/api/modules.md b/doc/api/modules.md index b3f62e078b4091..900c2c158b5a44 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -280,9 +280,12 @@ irrespective of whether or not `./foo` and `./FOO` are the same file. ## Core modules + @@ -773,6 +776,7 @@ added: v0.1.16 --> + * {Object} diff --git a/doc/api/n-api.md b/doc/api/n-api.md index b8b389a2ba6f7a..24963af7f90878 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -1,6 +1,7 @@ # Node-API + > Stability: 2 - Stable @@ -5981,6 +5982,7 @@ This API may only be called from the main thread. diff --git a/doc/api/net.md b/doc/api/net.md index d06622f90b7f6e..6d5487b6748441 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -1,6 +1,7 @@ # Net + > Stability: 2 - Stable @@ -57,7 +58,9 @@ net.createServer().listen( ## Class: `net.BlockList` The `BlockList` object can be used with some network APIs to specify rules for @@ -66,7 +69,9 @@ IP subnets. ### `blockList.addAddress(address[, type])` * `address` {string|net.SocketAddress} An IPv4 or IPv6 address. @@ -76,7 +81,9 @@ Adds a rule to block the given IP address. ### `blockList.addRange(start, end[, type])` * `start` {string|net.SocketAddress} The starting IPv4 or IPv6 address in the @@ -89,7 +96,9 @@ Adds a rule to block a range of IP addresses from `start` (inclusive) to ### `blockList.addSubnet(net, prefix[, type])` * `net` {string|net.SocketAddress} The network IPv4 or IPv6 address. @@ -102,7 +111,9 @@ Adds a rule to block a range of IP addresses specified as a subnet mask. ### `blockList.check(address[, type])` * `address` {string|net.SocketAddress} The IP address to check @@ -129,7 +140,9 @@ console.log(blockList.check('::ffff:123.123.123.123', 'ipv6')); // Prints: true ### `blockList.rules` * Type: {string[]} @@ -138,11 +151,15 @@ The list of rules added to the blocklist. ## Class: `net.SocketAddress` ### `new net.SocketAddress([options])` * `options` {Object} @@ -155,28 +172,36 @@ added: v15.14.0 ### `socketaddress.address` * Type {string} ### `socketaddress.family` * Type {string} Either `'ipv4'` or `'ipv6'`. ### `socketaddress.flowlabel` * Type {number} ### `socketaddress.port` * Type {number} diff --git a/doc/api/os.md b/doc/api/os.md index 85469a56293cc6..990d4cce9e45b3 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -124,7 +124,9 @@ are always 0. ## `os.devNull` * {string} diff --git a/doc/api/packages.md b/doc/api/packages.md index 4aee6b77ecbe11..a04e18421b83ba 100644 --- a/doc/api/packages.md +++ b/doc/api/packages.md @@ -1,7 +1,9 @@ # Modules: Packages + + - -> Stability: 0 - Deprecated: Use subpath patterns instead. - -Before subpath patterns were supported, a trailing `"/"` suffix was used to -support folder mappings: - -```json -{ - "exports": { - "./features/": "./features/" - } -} -``` - -_This feature will be removed in a future release._ - -Instead, use direct [subpath patterns][]: - -```json -{ - "exports": { - "./features/*": "./features/*.js" - } -} -``` - -The benefit of patterns over folder exports is that packages can always be -imported by consumers without subpath file extensions being necessary. - ### Exports sugar * `options` {Object} @@ -935,19 +937,25 @@ implement the `enable()` and `disable()` methods. ## Class: `RecordableHistogram extends Histogram` ### `histogram.record(val)` * `val` {number|bigint} The amount to record in the histogram. ### `histogram.recordDelta()` Calculates the amount of time (in nanoseconds) that has passed since the diff --git a/doc/api/policy.md b/doc/api/policy.md index 01b3eba0a33084..0d53352788a32c 100644 --- a/doc/api/policy.md +++ b/doc/api/policy.md @@ -1,6 +1,7 @@ # Policies + > Stability: 1 - Experimental diff --git a/doc/api/process.md b/doc/api/process.md index eda27917c86902..91b23a3f31d704 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -1,6 +1,7 @@ # Process + @@ -627,7 +628,9 @@ The `*-deprecation` command-line flags only affect warnings that use the name ### Event: `'worker'` * `worker` {Worker} The {Worker} that was created. @@ -665,6 +668,7 @@ A few of the warning types that are most common include: ### Signal events + Signal events will be emitted when the Node.js process receives a signal. Please @@ -2218,7 +2222,9 @@ program memory allocations. ## `process.memoryUsage.rss()` * Returns: {integer} @@ -2596,7 +2602,7 @@ tarball. that are no longer supported). * `'Dubnium'` for the 10.x LTS line beginning with 10.13.0. * `'Erbium'` for the 12.x LTS line beginning with 12.13.0. - For other LTS Release code names, see [Node.js Changelog Archive](https://github.com/nodejs/node/blob/HEAD/doc/changelogs/CHANGELOG_ARCHIVE.md) + For other LTS Release code names, see [Node.js Changelog Archive](https://github.com/nodejs/node/blob/HEAD/doc/changelogs/CHANGELOG_ARCHIVE.md) ```js @@ -3251,7 +3257,9 @@ This feature is not available in [`Worker`][] threads. ## `process.setSourceMapsEnabled(val)` > Stability: 1 - Experimental diff --git a/doc/api/readline.md b/doc/api/readline.md index cf2cf8a15377ce..6c782fcc2d4364 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -118,7 +118,9 @@ rl.on('line', (input) => { ### Event: `'history'` The `'history'` event is emitted whenever the history array has changed. @@ -466,7 +468,9 @@ asynchronous iteration may result in missed lines. @@ -535,6 +539,8 @@ line prompts are included in the calculations. added: REPLACEME --> +> Stability: 1 - Experimental + ### Class: `readlinePromises.Interface` + > Stability: 2 - Stable diff --git a/doc/api/stream.md b/doc/api/stream.md index b3b1f628b3a116..f2a725012414d2 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1274,7 +1274,9 @@ Returns whether the stream was destroyed or errored before emitting `'end'`. ##### `readable.readableDidRead` > Stability: 1 - Experimental diff --git a/doc/api/synopsis.md b/doc/api/synopsis.md index 2bbf53cdec4967..5bfdebc32c6c1b 100644 --- a/doc/api/synopsis.md +++ b/doc/api/synopsis.md @@ -3,6 +3,7 @@ ## Usage + `node [options] [V8 options] [script.js | -e "script" | - ] [arguments]` diff --git a/doc/api/tls.md b/doc/api/tls.md index 34165f9f571e88..ccd1bab90e9d39 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1416,17 +1416,19 @@ being issued by trusted CA (`options.ca`). * `url` {URL} The [WHATWG URL][] object to convert to an options object. diff --git a/doc/api/util.md b/doc/api/util.md index ac768c38c7eb39..ea8bbd5e286887 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -1308,7 +1308,9 @@ The encoding supported by the `TextEncoder` instance. Always set to `'utf-8'`. ## `util.toUSVString(string)` * `string` {string} diff --git a/doc/api/v8.md b/doc/api/v8.md index f94231451a5982..d4972163cc6f80 100644 --- a/doc/api/v8.md +++ b/doc/api/v8.md @@ -228,6 +228,7 @@ setTimeout(() => { v8.setFlagsFromString('--notrace_gc'); }, 60e3); @@ -241,6 +242,7 @@ records and optimize code. This can be used in conjunction with diff --git a/doc/api/vm.md b/doc/api/vm.md index cff8c9b6e23bf3..b7cde0e3b69381 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -798,7 +798,7 @@ added: * `evaluateCallback` {Function} Called when the module is evaluated. * `options` * `identifier` {string} String used in stack traces. - **Default:** `'vm:module(i)'` where `i` is a context-specific ascending + **Default:** `'vm:module(i)'` where `i` is a context-specific ascending index. * `context` {Object} The [contextified][] object as returned by the `vm.createContext()` method, to compile and evaluate this `Module` in. diff --git a/doc/api/worker_threads.md b/doc/api/worker_threads.md index 33f2811a83c877..f9a1d91b4519c6 100644 --- a/doc/api/worker_threads.md +++ b/doc/api/worker_threads.md @@ -63,7 +63,9 @@ specifically `argv` and `execArgv` options. ## `worker.getEnvironmentData(key)` > Stability: 1 - Experimental @@ -280,7 +282,9 @@ new Worker('process.env.SET_IN_WORKER = "foo"', { eval: true, env: SHARE_ENV }) ## `worker.setEnvironmentData(key[, value])` > Stability: 1 - Experimental @@ -527,10 +531,14 @@ are part of the channel. - - + diff --git a/doc/changelogs/CHANGELOG_IOJS.md b/doc/changelogs/CHANGELOG_IOJS.md index cb6832ab574e1b..1760c92a9c7202 100644 --- a/doc/changelogs/CHANGELOG_IOJS.md +++ b/doc/changelogs/CHANGELOG_IOJS.md @@ -1,8 +1,6 @@ # io.js ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V010.md b/doc/changelogs/CHANGELOG_V010.md index 5d375fa17ffba3..461e1b8b9602c2 100644 --- a/doc/changelogs/CHANGELOG_V010.md +++ b/doc/changelogs/CHANGELOG_V010.md @@ -1,8 +1,6 @@ # Node.js 0.10 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V012.md b/doc/changelogs/CHANGELOG_V012.md index 8cfe45a7d48a33..a5b25427a3ab48 100644 --- a/doc/changelogs/CHANGELOG_V012.md +++ b/doc/changelogs/CHANGELOG_V012.md @@ -1,8 +1,6 @@ # Node.js 0.12 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V10.md b/doc/changelogs/CHANGELOG_V10.md index 21711f018e2151..d67acd69004caa 100644 --- a/doc/changelogs/CHANGELOG_V10.md +++ b/doc/changelogs/CHANGELOG_V10.md @@ -1,8 +1,6 @@ # Node.js 10 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V11.md b/doc/changelogs/CHANGELOG_V11.md index 8ff4527f81f9f8..67e1c106734e42 100644 --- a/doc/changelogs/CHANGELOG_V11.md +++ b/doc/changelogs/CHANGELOG_V11.md @@ -1,8 +1,6 @@ # Node.js 11 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V12.md b/doc/changelogs/CHANGELOG_V12.md index 01887997cf953f..78113f37bada7b 100644 --- a/doc/changelogs/CHANGELOG_V12.md +++ b/doc/changelogs/CHANGELOG_V12.md @@ -1,8 +1,6 @@ # Node.js 12 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V13.md b/doc/changelogs/CHANGELOG_V13.md index 412824b14d2f65..5241cc3461c2e8 100644 --- a/doc/changelogs/CHANGELOG_V13.md +++ b/doc/changelogs/CHANGELOG_V13.md @@ -1,8 +1,6 @@ # Node.js 13 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V14.md b/doc/changelogs/CHANGELOG_V14.md index 1af9d1fb427d5c..af78f885606c39 100644 --- a/doc/changelogs/CHANGELOG_V14.md +++ b/doc/changelogs/CHANGELOG_V14.md @@ -1,8 +1,6 @@ # Node.js 14 ChangeLog - - - +
@@ -11,6 +9,7 @@ '); + }, + + tableData() { + /** @type {number} */ + // @ts-expect-error Custom. + const column = this.getData('tableColumn'); // @ts-expect-error Custom. + + if (column in this.getData('tableAlign')) { + this.tag(''); + this.setData('tableColumn', column + 1); + } else { + // Stop capturing. + this.resume(); + } + }, + + tableHead() { + this.lineEndingIfNeeded(); + this.tag(''); + this.setData('slurpOneLineEnding', true); // Slurp the line ending from the delimiter row. + }, + + tableHeader() { + this.tag(''); // @ts-expect-error Custom. + + this.setData('tableColumn', this.getData('tableColumn') + 1); + }, + + tableRow() { + /** @type {Align[]} */ + // @ts-expect-error Custom. + const align = this.getData('tableAlign'); + /** @type {number} */ + // @ts-expect-error Custom. + + let column = this.getData('tableColumn'); + + while (column < align.length) { + this.lineEndingIfNeeded(); // @ts-expect-error `null` is fine as an index. + + this.tag(''); + column++; + } + + this.setData('tableColumn', column); + this.lineEndingIfNeeded(); + this.tag(''); + } + } +}; +/** + * @param {string} $0 + * @param {string} $1 + * @returns {string} + */ + +function replace$1($0, $1) { + // Pipes work, backslashes don’t (but can’t escape pipes). + return $1 === '|' ? $1 : $0 +} + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + */ + +/** @type {Extension} */ +const gfmTable = { + flow: { + null: { + tokenize: tokenizeTable, + resolve: resolveTable + } + } +}; +const setextUnderlineMini = { + tokenize: tokenizeSetextUnderlineMini, + partial: true +}; +const nextPrefixedOrBlank = { + tokenize: tokenizeNextPrefixedOrBlank, + partial: true +}; +/** @type {Resolver} */ + +function resolveTable(events, context) { + let index = -1; + /** @type {Token} */ + + let token; + /** @type {boolean|undefined} */ + + let inHead; + /** @type {boolean|undefined} */ + + let inDelimiterRow; + /** @type {boolean|undefined} */ + + let inRow; + /** @type {Token} */ + + let cell; + /** @type {Token} */ + + let content; + /** @type {Token} */ + + let text; + /** @type {number|undefined} */ + + let contentStart; + /** @type {number|undefined} */ + + let contentEnd; + /** @type {number|undefined} */ + + let cellStart; + + while (++index < events.length) { + token = events[index][1]; + + if (inRow) { + if (token.type === 'temporaryTableCellContent') { + contentStart = contentStart || index; + contentEnd = index; + } + + if ( + // Combine separate content parts into one. + (token.type === 'tableCellDivider' || token.type === 'tableRow') && + contentEnd + ) { + content = { + type: 'tableContent', + // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + start: events[contentStart][1].start, + end: events[contentEnd][1].end + }; + text = { + type: 'chunkText', + start: content.start, + end: content.end, + // @ts-expect-error It’s fine. + contentType: 'text' + }; + events.splice( + // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + contentStart, // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + contentEnd - contentStart + 1, + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ); // @ts-expect-error `contentStart` is defined if `contentEnd` is too. + + index -= contentEnd - contentStart - 3; + contentStart = undefined; + contentEnd = undefined; + } + } + + if ( + events[index][0] === 'exit' && + cellStart && + cellStart + 1 < index && + (token.type === 'tableCellDivider' || + (token.type === 'tableRow' && + (cellStart + 3 < index || + events[cellStart][1].type !== 'whitespace'))) + ) { + cell = { + type: inDelimiterRow + ? 'tableDelimiter' + : inHead + ? 'tableHeader' + : 'tableData', + start: events[cellStart][1].start, + end: events[index][1].end + }; + events.splice(index + (token.type === 'tableCellDivider' ? 1 : 0), 0, [ + 'exit', + cell, + context + ]); + events.splice(cellStart, 0, ['enter', cell, context]); + index += 2; + cellStart = index + 1; + } + + if (token.type === 'tableRow') { + inRow = events[index][0] === 'enter'; + + if (inRow) { + cellStart = index + 1; + } + } + + if (token.type === 'tableDelimiterRow') { + inDelimiterRow = events[index][0] === 'enter'; + + if (inDelimiterRow) { + cellStart = index + 1; + } + } + + if (token.type === 'tableHead') { + inHead = events[index][0] === 'enter'; + } + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeTable(effects, ok, nok) { + const self = this; + /** @type {Align[]} */ + + const align = []; + let tableHeaderCount = 0; + /** @type {boolean|undefined} */ + + let seenDelimiter; + /** @type {boolean|undefined} */ + + let hasDash; + return start + /** @type {State} */ + + function start(code) { + // @ts-expect-error Custom. + effects.enter('table')._align = align; + effects.enter('tableHead'); + effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. + + if (code === 124) { + return cellDividerHead(code) + } + + tableHeaderCount++; + effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. + + return inCellContentHead(code) + } + /** @type {State} */ + + function cellDividerHead(code) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + seenDelimiter = true; + return cellBreakHead + } + /** @type {State} */ + + function cellBreakHead(code) { + if (code === null || markdownLineEnding(code)) { + return atRowEndHead(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceHead + } + + if (seenDelimiter) { + seenDelimiter = undefined; + tableHeaderCount++; + } + + if (code === 124) { + return cellDividerHead(code) + } // Anything else is cell content. + + effects.enter('temporaryTableCellContent'); + return inCellContentHead(code) + } + /** @type {State} */ + + function inWhitespaceHead(code) { + if (markdownSpace(code)) { + effects.consume(code); + return inWhitespaceHead + } + + effects.exit('whitespace'); + return cellBreakHead(code) + } + /** @type {State} */ + + function inCellContentHead(code) { + // EOF, whitespace, pipe + if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { + effects.exit('temporaryTableCellContent'); + return cellBreakHead(code) + } + + effects.consume(code); + return code === 92 ? inCellContentEscapeHead : inCellContentHead + } + /** @type {State} */ + + function inCellContentEscapeHead(code) { + if (code === 92 || code === 124) { + effects.consume(code); + return inCellContentHead + } // Anything else. + + return inCellContentHead(code) + } + /** @type {State} */ + + function atRowEndHead(code) { + if (code === null) { + return nok(code) + } + + effects.exit('tableRow'); + effects.exit('tableHead'); + return effects.attempt( + { + tokenize: tokenizeRowEnd, + partial: true + }, + atDelimiterLineStart, + nok + )(code) + } + /** @type {State} */ + + function atDelimiterLineStart(code) { + // To do: is the lazy setext thing still needed? + return effects.check( + setextUnderlineMini, + nok, // Support an indent before the delimiter row. + factorySpace(effects, rowStartDelimiter, 'linePrefix', 4) + )(code) + } + /** @type {State} */ + + function rowStartDelimiter(code) { + // If there’s another space, or we’re at the EOL/EOF, exit. + if (code === null || markdownLineEndingOrSpace(code)) { + return nok(code) + } + + effects.enter('tableDelimiterRow'); + return atDelimiterRowBreak(code) + } + /** @type {State} */ + + function atDelimiterRowBreak(code) { + if (code === null || markdownLineEnding(code)) { + return rowEndDelimiter(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceDelimiter + } + + if (code === 45) { + effects.enter('tableDelimiterFiller'); + effects.consume(code); + hasDash = true; + align.push(null); + return inFillerDelimiter + } + + if (code === 58) { + effects.enter('tableDelimiterAlignment'); + effects.consume(code); + effects.exit('tableDelimiterAlignment'); + align.push('left'); + return afterLeftAlignment + } // If we start with a pipe, we open a cell marker. + + if (code === 124) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + return atDelimiterRowBreak + } + + return nok(code) + } + /** @type {State} */ + + function inWhitespaceDelimiter(code) { + if (markdownSpace(code)) { + effects.consume(code); + return inWhitespaceDelimiter + } + + effects.exit('whitespace'); + return atDelimiterRowBreak(code) + } + /** @type {State} */ + + function inFillerDelimiter(code) { + if (code === 45) { + effects.consume(code); + return inFillerDelimiter + } + + effects.exit('tableDelimiterFiller'); + + if (code === 58) { + effects.enter('tableDelimiterAlignment'); + effects.consume(code); + effects.exit('tableDelimiterAlignment'); + align[align.length - 1] = + align[align.length - 1] === 'left' ? 'center' : 'right'; + return afterRightAlignment + } + + return atDelimiterRowBreak(code) + } + /** @type {State} */ + + function afterLeftAlignment(code) { + if (code === 45) { + effects.enter('tableDelimiterFiller'); + effects.consume(code); + hasDash = true; + return inFillerDelimiter + } // Anything else is not ok. + + return nok(code) + } + /** @type {State} */ + + function afterRightAlignment(code) { + if (code === null || markdownLineEnding(code)) { + return rowEndDelimiter(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceDelimiter + } // `|` + + if (code === 124) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + return atDelimiterRowBreak + } + + return nok(code) + } + /** @type {State} */ + + function rowEndDelimiter(code) { + effects.exit('tableDelimiterRow'); // Exit if there was no dash at all, or if the header cell count is not the + // delimiter cell count. + + if (!hasDash || tableHeaderCount !== align.length) { + return nok(code) + } + + if (code === null) { + return tableClose(code) + } + + return effects.check( + nextPrefixedOrBlank, + tableClose, + effects.attempt( + { + tokenize: tokenizeRowEnd, + partial: true + }, + factorySpace(effects, bodyStart, 'linePrefix', 4), + tableClose + ) + )(code) + } + /** @type {State} */ + + function tableClose(code) { + effects.exit('table'); + return ok(code) + } + /** @type {State} */ + + function bodyStart(code) { + effects.enter('tableBody'); + return rowStartBody(code) + } + /** @type {State} */ + + function rowStartBody(code) { + effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. + + if (code === 124) { + return cellDividerBody(code) + } + + effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. + + return inCellContentBody(code) + } + /** @type {State} */ + + function cellDividerBody(code) { + effects.enter('tableCellDivider'); + effects.consume(code); + effects.exit('tableCellDivider'); + return cellBreakBody + } + /** @type {State} */ + + function cellBreakBody(code) { + if (code === null || markdownLineEnding(code)) { + return atRowEndBody(code) + } + + if (markdownSpace(code)) { + effects.enter('whitespace'); + effects.consume(code); + return inWhitespaceBody + } // `|` + + if (code === 124) { + return cellDividerBody(code) + } // Anything else is cell content. + + effects.enter('temporaryTableCellContent'); + return inCellContentBody(code) + } + /** @type {State} */ + + function inWhitespaceBody(code) { + if (markdownSpace(code)) { + effects.consume(code); + return inWhitespaceBody + } + + effects.exit('whitespace'); + return cellBreakBody(code) + } + /** @type {State} */ + + function inCellContentBody(code) { + // EOF, whitespace, pipe + if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { + effects.exit('temporaryTableCellContent'); + return cellBreakBody(code) + } + + effects.consume(code); + return code === 92 ? inCellContentEscapeBody : inCellContentBody + } + /** @type {State} */ + + function inCellContentEscapeBody(code) { + if (code === 92 || code === 124) { + effects.consume(code); + return inCellContentBody + } // Anything else. + + return inCellContentBody(code) + } + /** @type {State} */ + + function atRowEndBody(code) { + effects.exit('tableRow'); + + if (code === null) { + return tableBodyClose(code) + } + + return effects.check( + nextPrefixedOrBlank, + tableBodyClose, + effects.attempt( + { + tokenize: tokenizeRowEnd, + partial: true + }, + factorySpace(effects, rowStartBody, 'linePrefix', 4), + tableBodyClose + ) + )(code) + } + /** @type {State} */ + + function tableBodyClose(code) { + effects.exit('tableBody'); + return tableClose(code) + } + /** @type {Tokenizer} */ + + function tokenizeRowEnd(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return lineStart + } + /** @type {State} */ + + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } + } +} // Based on micromark, but that won’t work as we’re in a table, and that expects +// content. +// + +/** @type {Tokenizer} */ + +function tokenizeSetextUnderlineMini(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + if (code !== 45) { + return nok(code) + } + + effects.enter('setextUnderline'); + return sequence(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === 45) { + effects.consume(code); + return sequence + } + + return whitespace(code) + } + /** @type {State} */ + + function whitespace(code) { + if (code === null || markdownLineEnding(code)) { + return ok(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return whitespace + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeNextPrefixedOrBlank(effects, ok, nok) { + let size = 0; + return start + /** @type {State} */ + + function start(code) { + // This is a check, so we don’t care about tokens, but we open a bogus one + // so we’re valid. + effects.enter('check'); // EOL. + + effects.consume(code); + return whitespace + } + /** @type {State} */ + + function whitespace(code) { + if (code === -1 || code === 32) { + effects.consume(code); + size++; + return size === 4 ? ok : whitespace + } // EOF or whitespace + + if (code === null || markdownLineEndingOrSpace(code)) { + return ok(code) + } // Anything else. + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').CompileContext} CompileContext + */ + +/** + * An opening or closing tag, followed by a case-insensitive specific tag name, + * followed by HTML whitespace, a greater than, or a slash. + */ +const reFlow = + /<(\/?)(iframe|noembed|noframes|plaintext|script|style|title|textarea|xmp)(?=[\t\n\f\r />])/gi; + +/** + * As HTML (text) parses tags separately (and v. strictly), we don’t need to be + * global. + */ +const reText = new RegExp('^' + reFlow.source, 'i'); + +/** @type {HtmlExtension} */ +const gfmTagfilterHtml = { + exit: { + htmlFlowData(token) { + exitHtmlData.call(this, token, reFlow); + }, + htmlTextData(token) { + exitHtmlData.call(this, token, reText); + } + } +}; + +/** + * @this {CompileContext} + * @param {Token} token + * @param {RegExp} filter + */ +function exitHtmlData(token, filter) { + let value = this.sliceSerialize(token); + + if (this.options.allowDangerousHtml) { + value = value.replace(filter, '<$1$2'); + } + + this.raw(this.encode(value)); +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +/** @type {HtmlExtension} */ +const gfmTaskListItemHtml = { + enter: { + taskListCheck() { + this.tag(''); + }, + + taskListCheckValueChecked() { + this.tag('checked="" '); + } + } +}; + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Code} Code + */ +const tasklistCheck = { + tokenize: tokenizeTasklistCheck +}; +const gfmTaskListItem = { + text: { + [91]: tasklistCheck + } +}; +/** @type {Tokenizer} */ + +function tokenizeTasklistCheck(effects, ok, nok) { + const self = this; + return open + /** @type {State} */ + + function open(code) { + if ( + // Exit if there’s stuff before. + self.previous !== null || // Exit if not in the first content that is the first child of a list + // item. + !self._gfmTasklistFirstContentOfListItem + ) { + return nok(code) + } + + effects.enter('taskListCheck'); + effects.enter('taskListCheckMarker'); + effects.consume(code); + effects.exit('taskListCheckMarker'); + return inside + } + /** @type {State} */ + + function inside(code) { + if (markdownSpace(code)) { + effects.enter('taskListCheckValueUnchecked'); + effects.consume(code); + effects.exit('taskListCheckValueUnchecked'); + return close + } + + if (code === 88 || code === 120) { + effects.enter('taskListCheckValueChecked'); + effects.consume(code); + effects.exit('taskListCheckValueChecked'); + return close + } + + return nok(code) + } + /** @type {State} */ + + function close(code) { + if (code === 93) { + effects.enter('taskListCheckMarker'); + effects.consume(code); + effects.exit('taskListCheckMarker'); + effects.exit('taskListCheck'); + return effects.check( + { + tokenize: spaceThenNonSpace + }, + ok, + nok + ) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function spaceThenNonSpace(effects, ok, nok) { + const self = this; + return factorySpace(effects, after, 'whitespace') + /** @type {State} */ + + function after(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'whitespace' && + code !== null && + !markdownLineEndingOrSpace(code) + ? ok(code) + : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-extension-gfm-strikethrough').Options} Options + */ + +/** + * Support GFM or markdown on github.com. + * + * @param {Options} [options] + * @returns {Extension} + */ +function gfm(options) { + return combineExtensions([ + gfmAutolinkLiteral, + gfmStrikethrough(options), + gfmTable, + gfmTaskListItem + ]) +} + +/** @type {HtmlExtension} */ +combineHtmlExtensions([ + gfmAutolinkLiteralHtml, + gfmStrikethroughHtml, + gfmTableHtml, + gfmTagfilterHtml, + gfmTaskListItemHtml +]); + +/** + * Get the total count of `character` in `value`. + * + * @param {any} value Content, coerced to string + * @param {string} character Single character to look for + * @return {number} Number of times `character` occurred in `value`. + */ +function ccount(value, character) { + var source = String(value); + var count = 0; + var index; + + if (typeof character !== 'string') { + throw new Error('Expected character') + } + + index = source.indexOf(character); + + while (index !== -1) { + count++; + index = source.indexOf(character, index + character.length); + } + + return count +} + +/** + * @typedef Options Configuration. + * @property {Test} [ignore] `unist-util-is` test used to assert parents + * + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Content} Content + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').Text} Text + * @typedef {Content|Root} Node + * @typedef {Extract} Parent + * + * @typedef {import('unist-util-visit-parents').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + * + * @typedef RegExpMatchObject + * @property {number} index + * @property {string} input + * + * @typedef {string|RegExp} Find + * @typedef {string|ReplaceFunction} Replace + * + * @typedef {[Find, Replace]} FindAndReplaceTuple + * @typedef {Object.} FindAndReplaceSchema + * @typedef {Array.} FindAndReplaceList + * + * @typedef {[RegExp, ReplaceFunction]} Pair + * @typedef {Array.} Pairs + */ + +const own$1 = {}.hasOwnProperty; + +/** + * @param tree mdast tree + * @param find Value to find and remove. When `string`, escaped and made into a global `RegExp` + * @param [replace] Value to insert. + * * When `string`, turned into a Text node. + * * When `Function`, called with the results of calling `RegExp.exec` as + * arguments, in which case it can return a single or a list of `Node`, + * a `string` (which is wrapped in a `Text` node), or `false` to not replace + * @param [options] Configuration. + */ +const findAndReplace = + /** + * @type {( + * ((tree: Node, find: Find, replace?: Replace, options?: Options) => Node) & + * ((tree: Node, schema: FindAndReplaceSchema|FindAndReplaceList, options?: Options) => Node) + * )} + **/ + ( + /** + * @param {Node} tree + * @param {Find|FindAndReplaceSchema|FindAndReplaceList} find + * @param {Replace|Options} [replace] + * @param {Options} [options] + */ + function (tree, find, replace, options) { + /** @type {Options|undefined} */ + let settings; + /** @type {FindAndReplaceSchema|FindAndReplaceList} */ + let schema; + + if (typeof find === 'string' || find instanceof RegExp) { + // @ts-expect-error don’t expect options twice. + schema = [[find, replace]]; + settings = options; + } else { + schema = find; + // @ts-expect-error don’t expect replace twice. + settings = replace; + } + + if (!settings) { + settings = {}; + } + + const ignored = convert(settings.ignore || []); + const pairs = toPairs(schema); + let pairIndex = -1; + + while (++pairIndex < pairs.length) { + visitParents(tree, 'text', visitor); + } + + return tree + + /** @type {import('unist-util-visit-parents').Visitor} */ + function visitor(node, parents) { + let index = -1; + /** @type {Parent|undefined} */ + let grandparent; + + while (++index < parents.length) { + const parent = /** @type {Parent} */ (parents[index]); + + if ( + ignored( + parent, + // @ts-expect-error mdast vs. unist parent. + grandparent ? grandparent.children.indexOf(parent) : undefined, + grandparent + ) + ) { + return + } + + grandparent = parent; + } + + if (grandparent) { + return handler(node, grandparent) + } + } + + /** + * @param {Text} node + * @param {Parent} parent + * @returns {VisitorResult} + */ + function handler(node, parent) { + const find = pairs[pairIndex][0]; + const replace = pairs[pairIndex][1]; + let start = 0; + // @ts-expect-error: TS is wrong, some of these children can be text. + let index = parent.children.indexOf(node); + /** @type {Array.} */ + let nodes = []; + /** @type {number|undefined} */ + let position; + + find.lastIndex = 0; + + let match = find.exec(node.value); + + while (match) { + position = match.index; + // @ts-expect-error this is perfectly fine, typescript. + let value = replace(...match, { + index: match.index, + input: match.input + }); + + if (typeof value === 'string') { + value = value.length > 0 ? {type: 'text', value} : undefined; + } + + if (value !== false) { + if (start !== position) { + nodes.push({ + type: 'text', + value: node.value.slice(start, position) + }); + } + + if (Array.isArray(value)) { + nodes.push(...value); + } else if (value) { + nodes.push(value); + } + + start = position + match[0].length; + } + + if (!find.global) { + break + } + + match = find.exec(node.value); + } + + if (position === undefined) { + nodes = [node]; + index--; + } else { + if (start < node.value.length) { + nodes.push({type: 'text', value: node.value.slice(start)}); + } + + parent.children.splice(index, 1, ...nodes); + } + + return index + nodes.length + 1 + } + } + ); + +/** + * @param {FindAndReplaceSchema|FindAndReplaceList} schema + * @returns {Pairs} + */ +function toPairs(schema) { + /** @type {Pairs} */ + const result = []; + + if (typeof schema !== 'object') { + throw new TypeError('Expected array or object as schema') + } + + if (Array.isArray(schema)) { + let index = -1; + + while (++index < schema.length) { + result.push([ + toExpression(schema[index][0]), + toFunction(schema[index][1]) + ]); + } + } else { + /** @type {string} */ + let key; + + for (key in schema) { + if (own$1.call(schema, key)) { + result.push([toExpression(key), toFunction(schema[key])]); + } + } + } + + return result +} + +/** + * @param {Find} find + * @returns {RegExp} + */ +function toExpression(find) { + return typeof find === 'string' ? new RegExp(escapeStringRegexp(find), 'g') : find +} + +/** + * @param {Replace} replace + * @returns {ReplaceFunction} + */ +function toFunction(replace) { + return typeof replace === 'function' ? replace : () => replace +} + +/** + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Transform} FromMarkdownTransform + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown/lib/types.js').Options} ToMarkdownExtension + * @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction + * @typedef {import('mdast-util-find-and-replace').RegExpMatchObject} RegExpMatchObject + * @typedef {import('mdast-util-find-and-replace').PhrasingContent} PhrasingContent + */ + +const inConstruct = 'phrasing'; +const notInConstruct = ['autolink', 'link', 'image', 'label']; + +/** @type {FromMarkdownExtension} */ +const gfmAutolinkLiteralFromMarkdown = { + transforms: [transformGfmAutolinkLiterals], + enter: { + literalAutolink: enterLiteralAutolink, + literalAutolinkEmail: enterLiteralAutolinkValue, + literalAutolinkHttp: enterLiteralAutolinkValue, + literalAutolinkWww: enterLiteralAutolinkValue + }, + exit: { + literalAutolink: exitLiteralAutolink, + literalAutolinkEmail: exitLiteralAutolinkEmail, + literalAutolinkHttp: exitLiteralAutolinkHttp, + literalAutolinkWww: exitLiteralAutolinkWww + } +}; + +/** @type {ToMarkdownExtension} */ +const gfmAutolinkLiteralToMarkdown = { + unsafe: [ + { + character: '@', + before: '[+\\-.\\w]', + after: '[\\-.\\w]', + inConstruct, + notInConstruct + }, + { + character: '.', + before: '[Ww]', + after: '[\\-.\\w]', + inConstruct, + notInConstruct + }, + {character: ':', before: '[ps]', after: '\\/', inConstruct, notInConstruct} + ] +}; + +/** @type {FromMarkdownHandle} */ +function enterLiteralAutolink(token) { + this.enter({type: 'link', title: null, url: '', children: []}, token); +} + +/** @type {FromMarkdownHandle} */ +function enterLiteralAutolinkValue(token) { + this.config.enter.autolinkProtocol.call(this, token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolinkHttp(token) { + this.config.exit.autolinkProtocol.call(this, token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolinkWww(token) { + this.config.exit.data.call(this, token); + const node = /** @type {Link} */ (this.stack[this.stack.length - 1]); + node.url = 'http://' + this.sliceSerialize(token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolinkEmail(token) { + this.config.exit.autolinkEmail.call(this, token); +} + +/** @type {FromMarkdownHandle} */ +function exitLiteralAutolink(token) { + this.exit(token); +} + +/** @type {FromMarkdownTransform} */ +function transformGfmAutolinkLiterals(tree) { + findAndReplace( + tree, + [ + [/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi, findUrl], + [/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/g, findEmail] + ], + {ignore: ['link', 'linkReference']} + ); +} + +/** + * @type {ReplaceFunction} + * @param {string} _ + * @param {string} protocol + * @param {string} domain + * @param {string} path + * @param {RegExpMatchObject} match + */ +// eslint-disable-next-line max-params +function findUrl(_, protocol, domain, path, match) { + let prefix = ''; + + // Not an expected previous character. + if (!previous(match)) { + return false + } + + // Treat `www` as part of the domain. + if (/^w/i.test(protocol)) { + domain = protocol + domain; + protocol = ''; + prefix = 'http://'; + } + + if (!isCorrectDomain(domain)) { + return false + } + + const parts = splitUrl(domain + path); + + if (!parts[0]) return false + + /** @type {PhrasingContent} */ + const result = { + type: 'link', + title: null, + url: prefix + protocol + parts[0], + children: [{type: 'text', value: protocol + parts[0]}] + }; + + if (parts[1]) { + return [result, {type: 'text', value: parts[1]}] + } + + return result +} + +/** + * @type {ReplaceFunction} + * @param {string} _ + * @param {string} atext + * @param {string} label + * @param {RegExpMatchObject} match + */ +function findEmail(_, atext, label, match) { + if ( + // Not an expected previous character. + !previous(match, true) || + // Label ends in not allowed character. + /[_-\d]$/.test(label) + ) { + return false + } + + return { + type: 'link', + title: null, + url: 'mailto:' + atext + '@' + label, + children: [{type: 'text', value: atext + '@' + label}] + } +} + +/** + * @param {string} domain + * @returns {boolean} + */ +function isCorrectDomain(domain) { + const parts = domain.split('.'); + + if ( + parts.length < 2 || + (parts[parts.length - 1] && + (/_/.test(parts[parts.length - 1]) || + !/[a-zA-Z\d]/.test(parts[parts.length - 1]))) || + (parts[parts.length - 2] && + (/_/.test(parts[parts.length - 2]) || + !/[a-zA-Z\d]/.test(parts[parts.length - 2]))) + ) { + return false + } + + return true +} + +/** + * @param {string} url + * @returns {[string, string|undefined]} + */ +function splitUrl(url) { + const trailExec = /[!"&'),.:;<>?\]}]+$/.exec(url); + /** @type {number} */ + let closingParenIndex; + /** @type {number} */ + let openingParens; + /** @type {number} */ + let closingParens; + /** @type {string|undefined} */ + let trail; + + if (trailExec) { + url = url.slice(0, trailExec.index); + trail = trailExec[0]; + closingParenIndex = trail.indexOf(')'); + openingParens = ccount(url, '('); + closingParens = ccount(url, ')'); + + while (closingParenIndex !== -1 && openingParens > closingParens) { + url += trail.slice(0, closingParenIndex + 1); + trail = trail.slice(closingParenIndex + 1); + closingParenIndex = trail.indexOf(')'); + closingParens++; + } + } + + return [url, trail] +} + +/** + * @param {RegExpMatchObject} match + * @param {boolean} [email=false] + * @returns {boolean} + */ +function previous(match, email) { + const code = match.input.charCodeAt(match.index - 1); + + return ( + (match.index === 0 || + unicodeWhitespace(code) || + unicodePunctuation(code)) && + (!email || code !== 47) + ) +} + +/** + * @typedef {import('mdast').Delete} Delete + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle + */ + +/** @type {FromMarkdownExtension} */ +const gfmStrikethroughFromMarkdown = { + canContainEols: ['delete'], + enter: {strikethrough: enterStrikethrough}, + exit: {strikethrough: exitStrikethrough} +}; + +/** @type {ToMarkdownExtension} */ +const gfmStrikethroughToMarkdown = { + unsafe: [{character: '~', inConstruct: 'phrasing'}], + handlers: {delete: handleDelete} +}; + +handleDelete.peek = peekDelete; + +/** @type {FromMarkdownHandle} */ +function enterStrikethrough(token) { + this.enter({type: 'delete', children: []}, token); +} + +/** @type {FromMarkdownHandle} */ +function exitStrikethrough(token) { + this.exit(token); +} + +/** + * @type {ToMarkdownHandle} + * @param {Delete} node + */ +function handleDelete(node, _, context) { + const exit = context.enter('emphasis'); + const value = containerPhrasing(node, context, {before: '~', after: '~'}); + exit(); + return '~~' + value + '~~' +} + +/** @type {ToMarkdownHandle} */ +function peekDelete() { + return '~' +} + +/** + * @typedef MarkdownTableOptions + * @property {string|null|Array.} [align] + * @property {boolean} [padding=true] + * @property {boolean} [delimiterStart=true] + * @property {boolean} [delimiterStart=true] + * @property {boolean} [delimiterEnd=true] + * @property {boolean} [alignDelimiters=true] + * @property {(value: string) => number} [stringLength] + */ + +/** + * Create a table from a matrix of strings. + * + * @param {Array.>} table + * @param {MarkdownTableOptions} [options] + * @returns {string} + */ +function markdownTable(table, options) { + const settings = options || {}; + const align = (settings.align || []).concat(); + const stringLength = settings.stringLength || defaultStringLength; + /** @type {number[]} Character codes as symbols for alignment per column. */ + const alignments = []; + let rowIndex = -1; + /** @type {string[][]} Cells per row. */ + const cellMatrix = []; + /** @type {number[][]} Sizes of each cell per row. */ + const sizeMatrix = []; + /** @type {number[]} */ + const longestCellByColumn = []; + let mostCellsPerRow = 0; + /** @type {number} */ + let columnIndex; + /** @type {string[]} Cells of current row */ + let row; + /** @type {number[]} Sizes of current row */ + let sizes; + /** @type {number} Sizes of current cell */ + let size; + /** @type {string} Current cell */ + let cell; + /** @type {string[]} Chunks of current line. */ + let line; + /** @type {string} */ + let before; + /** @type {string} */ + let after; + /** @type {number} */ + let code; + + // This is a superfluous loop if we don’t align delimiters, but otherwise we’d + // do superfluous work when aligning, so optimize for aligning. + while (++rowIndex < table.length) { + columnIndex = -1; + row = []; + sizes = []; + + if (table[rowIndex].length > mostCellsPerRow) { + mostCellsPerRow = table[rowIndex].length; + } + + while (++columnIndex < table[rowIndex].length) { + cell = serialize(table[rowIndex][columnIndex]); + + if (settings.alignDelimiters !== false) { + size = stringLength(cell); + sizes[columnIndex] = size; + + if ( + longestCellByColumn[columnIndex] === undefined || + size > longestCellByColumn[columnIndex] + ) { + longestCellByColumn[columnIndex] = size; + } + } + + row.push(cell); + } + + cellMatrix[rowIndex] = row; + sizeMatrix[rowIndex] = sizes; + } + + // Figure out which alignments to use. + columnIndex = -1; + + if (typeof align === 'object' && 'length' in align) { + while (++columnIndex < mostCellsPerRow) { + alignments[columnIndex] = toAlignment(align[columnIndex]); + } + } else { + code = toAlignment(align); + + while (++columnIndex < mostCellsPerRow) { + alignments[columnIndex] = code; + } + } + + // Inject the alignment row. + columnIndex = -1; + row = []; + sizes = []; + + while (++columnIndex < mostCellsPerRow) { + code = alignments[columnIndex]; + before = ''; + after = ''; + + if (code === 99 /* `c` */) { + before = ':'; + after = ':'; + } else if (code === 108 /* `l` */) { + before = ':'; + } else if (code === 114 /* `r` */) { + after = ':'; + } + + // There *must* be at least one hyphen-minus in each alignment cell. + size = + settings.alignDelimiters === false + ? 1 + : Math.max( + 1, + longestCellByColumn[columnIndex] - before.length - after.length + ); + + cell = before + '-'.repeat(size) + after; + + if (settings.alignDelimiters !== false) { + size = before.length + size + after.length; + + if (size > longestCellByColumn[columnIndex]) { + longestCellByColumn[columnIndex] = size; + } + + sizes[columnIndex] = size; + } + + row[columnIndex] = cell; + } + + // Inject the alignment row. + cellMatrix.splice(1, 0, row); + sizeMatrix.splice(1, 0, sizes); + + rowIndex = -1; + /** @type {string[]} */ + const lines = []; + + while (++rowIndex < cellMatrix.length) { + row = cellMatrix[rowIndex]; + sizes = sizeMatrix[rowIndex]; + columnIndex = -1; + line = []; + + while (++columnIndex < mostCellsPerRow) { + cell = row[columnIndex] || ''; + before = ''; + after = ''; + + if (settings.alignDelimiters !== false) { + size = longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0); + code = alignments[columnIndex]; + + if (code === 114 /* `r` */) { + before = ' '.repeat(size); + } else if (code === 99 /* `c` */) { + if (size % 2) { + before = ' '.repeat(size / 2 + 0.5); + after = ' '.repeat(size / 2 - 0.5); + } else { + before = ' '.repeat(size / 2); + after = before; + } + } else { + after = ' '.repeat(size); + } + } + + if (settings.delimiterStart !== false && !columnIndex) { + line.push('|'); + } + + if ( + settings.padding !== false && + // Don’t add the opening space if we’re not aligning and the cell is + // empty: there will be a closing space. + !(settings.alignDelimiters === false && cell === '') && + (settings.delimiterStart !== false || columnIndex) + ) { + line.push(' '); + } + + if (settings.alignDelimiters !== false) { + line.push(before); + } + + line.push(cell); + + if (settings.alignDelimiters !== false) { + line.push(after); + } + + if (settings.padding !== false) { + line.push(' '); + } + + if ( + settings.delimiterEnd !== false || + columnIndex !== mostCellsPerRow - 1 + ) { + line.push('|'); + } + } + + lines.push( + settings.delimiterEnd === false + ? line.join('').replace(/ +$/, '') + : line.join('') + ); + } + + return lines.join('\n') +} + +/** + * @param {string|null|undefined} [value] + * @returns {string} + */ +function serialize(value) { + return value === null || value === undefined ? '' : String(value) +} + +/** + * @param {string} value + * @returns {number} + */ +function defaultStringLength(value) { + return value.length +} + +/** + * @param {string|null|undefined} value + * @returns {number} + */ +function toAlignment(value) { + const code = typeof value === 'string' ? value.charCodeAt(0) : 0; + + return code === 67 /* `C` */ || code === 99 /* `c` */ + ? 99 /* `c` */ + : code === 76 /* `L` */ || code === 108 /* `l` */ + ? 108 /* `l` */ + : code === 82 /* `R` */ || code === 114 /* `r` */ + ? 114 /* `r` */ + : 0 +} + +/** + * @typedef {import('mdast').AlignType} AlignType + * @typedef {import('mdast').Table} Table + * @typedef {import('mdast').TableRow} TableRow + * @typedef {import('mdast').TableCell} TableCell + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('markdown-table').MarkdownTableOptions} MarkdownTableOptions + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Context} ToMarkdownContext + * + * @typedef Options + * @property {boolean} [tableCellPadding=true] + * @property {boolean} [tablePipeAlign=true] + * @property {MarkdownTableOptions['stringLength']} [stringLength] + */ + +/** @type {FromMarkdownExtension} */ +const gfmTableFromMarkdown = { + enter: { + table: enterTable, + tableData: enterCell, + tableHeader: enterCell, + tableRow: enterRow + }, + exit: { + codeText: exitCodeText, + table: exitTable, + tableData: exit, + tableHeader: exit, + tableRow: exit + } +}; + +/** @type {FromMarkdownHandle} */ +function enterTable(token) { + /** @type {AlignType[]} */ + // @ts-expect-error: `align` is custom. + const align = token._align; + this.enter({type: 'table', align, children: []}, token); + this.setData('inTable', true); +} + +/** @type {FromMarkdownHandle} */ +function exitTable(token) { + this.exit(token); + this.setData('inTable'); +} + +/** @type {FromMarkdownHandle} */ +function enterRow(token) { + this.enter({type: 'tableRow', children: []}, token); +} + +/** @type {FromMarkdownHandle} */ +function exit(token) { + this.exit(token); +} + +/** @type {FromMarkdownHandle} */ +function enterCell(token) { + this.enter({type: 'tableCell', children: []}, token); +} + +// Overwrite the default code text data handler to unescape escaped pipes when +// they are in tables. +/** @type {FromMarkdownHandle} */ +function exitCodeText(token) { + let value = this.resume(); + + if (this.getData('inTable')) { + value = value.replace(/\\([\\|])/g, replace); + } + + const node = /** @type {InlineCode} */ (this.stack[this.stack.length - 1]); + node.value = value; + this.exit(token); +} + +/** + * @param {string} $0 + * @param {string} $1 + * @returns {string} + */ +function replace($0, $1) { + // Pipes work, backslashes don’t (but can’t escape pipes). + return $1 === '|' ? $1 : $0 +} + +/** + * @param {Options} [options] + * @returns {ToMarkdownExtension} + */ +function gfmTableToMarkdown(options) { + const settings = options || {}; + const padding = settings.tableCellPadding; + const alignDelimiters = settings.tablePipeAlign; + const stringLength = settings.stringLength; + const around = padding ? ' ' : '|'; + + return { + unsafe: [ + {character: '\r', inConstruct: 'tableCell'}, + {character: '\n', inConstruct: 'tableCell'}, + // A pipe, when followed by a tab or space (padding), or a dash or colon + // (unpadded delimiter row), could result in a table. + {atBreak: true, character: '|', after: '[\t :-]'}, + // A pipe in a cell must be encoded. + {character: '|', inConstruct: 'tableCell'}, + // A colon must be followed by a dash, in which case it could start a + // delimiter row. + {atBreak: true, character: ':', after: '-'}, + // A delimiter row can also start with a dash, when followed by more + // dashes, a colon, or a pipe. + // This is a stricter version than the built in check for lists, thematic + // breaks, and setex heading underlines though: + // + {atBreak: true, character: '-', after: '[:|-]'} + ], + handlers: { + table: handleTable, + tableRow: handleTableRow, + tableCell: handleTableCell, + inlineCode: inlineCodeWithTable + } + } + + /** + * @type {ToMarkdownHandle} + * @param {Table} node + */ + function handleTable(node, _, context) { + // @ts-expect-error: fixed in `markdown-table@3.0.1`. + return serializeData(handleTableAsData(node, context), node.align) + } + + /** + * This function isn’t really used normally, because we handle rows at the + * table level. + * But, if someone passes in a table row, this ensures we make somewhat sense. + * + * @type {ToMarkdownHandle} + * @param {TableRow} node + */ + function handleTableRow(node, _, context) { + const row = handleTableRowAsData(node, context); + // `markdown-table` will always add an align row + const value = serializeData([row]); + return value.slice(0, value.indexOf('\n')) + } + + /** + * @type {ToMarkdownHandle} + * @param {TableCell} node + */ + function handleTableCell(node, _, context) { + const exit = context.enter('tableCell'); + const subexit = context.enter('phrasing'); + const value = containerPhrasing(node, context, { + before: around, + after: around + }); + subexit(); + exit(); + return value + } + + /** + * @param {Array.>} matrix + * @param {Array.} [align] + */ + function serializeData(matrix, align) { + return markdownTable(matrix, { + align, + alignDelimiters, + padding, + stringLength + }) + } + + /** + * @param {Table} node + * @param {ToMarkdownContext} context + */ + function handleTableAsData(node, context) { + const children = node.children; + let index = -1; + /** @type {Array.>} */ + const result = []; + const subexit = context.enter('table'); + + while (++index < children.length) { + result[index] = handleTableRowAsData(children[index], context); + } + + subexit(); + + return result + } + + /** + * @param {TableRow} node + * @param {ToMarkdownContext} context + */ + function handleTableRowAsData(node, context) { + const children = node.children; + let index = -1; + /** @type {Array.} */ + const result = []; + const subexit = context.enter('tableRow'); + + while (++index < children.length) { + result[index] = handleTableCell(children[index], node, context); + } + + subexit(); + + return result + } + + /** + * @type {ToMarkdownHandle} + * @param {InlineCode} node + */ + function inlineCodeWithTable(node, parent, context) { + let value = inlineCode(node, parent, context); + + if (context.stack.includes('tableCell')) { + value = value.replace(/\|/g, '\\$&'); + } + + return value + } +} + +/** + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').BlockContent} BlockContent + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle + */ + +/** @type {FromMarkdownExtension} */ +const gfmTaskListItemFromMarkdown = { + exit: { + taskListCheckValueChecked: exitCheck, + taskListCheckValueUnchecked: exitCheck, + paragraph: exitParagraphWithTaskListItem + } +}; + +/** @type {ToMarkdownExtension} */ +const gfmTaskListItemToMarkdown = { + unsafe: [{atBreak: true, character: '-', after: '[:|-]'}], + handlers: {listItem: listItemWithTaskListItem} +}; + +/** @type {FromMarkdownHandle} */ +function exitCheck(token) { + // We’re always in a paragraph, in a list item. + this.stack[this.stack.length - 2].checked = + token.type === 'taskListCheckValueChecked'; +} + +/** @type {FromMarkdownHandle} */ +function exitParagraphWithTaskListItem(token) { + const parent = this.stack[this.stack.length - 2]; + /** @type {Paragraph} */ + // @ts-expect-error: must be true. + const node = this.stack[this.stack.length - 1]; + /** @type {BlockContent[]} */ + // @ts-expect-error: check whether `parent` is a `listItem` later. + const siblings = parent.children; + const head = node.children[0]; + let index = -1; + /** @type {Paragraph|undefined} */ + let firstParaghraph; + + if ( + parent && + parent.type === 'listItem' && + typeof parent.checked === 'boolean' && + head && + head.type === 'text' + ) { + while (++index < siblings.length) { + const sibling = siblings[index]; + if (sibling.type === 'paragraph') { + firstParaghraph = sibling; + break + } + } + + if (firstParaghraph === node) { + // Must start with a space or a tab. + head.value = head.value.slice(1); + + if (head.value.length === 0) { + node.children.shift(); + } else { + // @ts-expect-error: must be true. + head.position.start.column++; + // @ts-expect-error: must be true. + head.position.start.offset++; + // @ts-expect-error: must be true. + node.position.start = Object.assign({}, head.position.start); + } + } + } + + this.exit(token); +} + +/** + * @type {ToMarkdownHandle} + * @param {ListItem} node + */ +function listItemWithTaskListItem(node, parent, context) { + const head = node.children[0]; + let value = listItem(node, parent, context); + + if (typeof node.checked === 'boolean' && head && head.type === 'paragraph') { + value = value.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/, check); + } + + return value + + /** + * @param {string} $0 + * @returns {string} + */ + function check($0) { + return $0 + '[' + (node.checked ? 'x' : ' ') + '] ' + } +} + +/** + * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension + * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension + * + * @typedef {import('mdast-util-gfm-table').Options} Options + */ + +/** + * @type {Array.} + */ +const gfmFromMarkdown = [ + gfmAutolinkLiteralFromMarkdown, + gfmStrikethroughFromMarkdown, + gfmTableFromMarkdown, + gfmTaskListItemFromMarkdown +]; + +/** + * @param {Options} [options] + * @returns {ToMarkdownExtension} + */ +function gfmToMarkdown(options) { + return { + extensions: [ + gfmAutolinkLiteralToMarkdown, + gfmStrikethroughToMarkdown, + gfmTableToMarkdown(options), + gfmTaskListItemToMarkdown + ] + } +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('micromark-extension-gfm').Options & import('mdast-util-gfm').Options} Options + */ + +/** + * Plugin to support GitHub Flavored Markdown (GFM). + * + * @type {import('unified').Plugin<[Options?]|void[], Root>} + */ +function remarkGfm(options = {}) { + const data = this.data(); + + add('micromarkExtensions', gfm(options)); + add('fromMarkdownExtensions', gfmFromMarkdown); + add('toMarkdownExtensions', gfmToMarkdown(options)); + + /** + * @param {string} field + * @param {unknown} value + */ + function add(field, value) { + const list = /** @type {unknown[]} */ ( + // Other extensions + /* c8 ignore next 2 */ + data[field] ? data[field] : (data[field] = []) + ); + + list.push(value); + } +} + +/** + * @typedef {import('vfile').VFileValue} Value + * @typedef {import('vfile').VFileOptions} Options + * @typedef {import('vfile').BufferEncoding} BufferEncoding + * + * @typedef {number|string} Mode + * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, flag?: string}} ReadOptions + * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, mode: Mode?, flag?: string}} WriteOptions + * + * @typedef {string|Uint8Array} Path Path of the file. + * @typedef {Path|URL|Options|VFile} Compatible Things that can be + * passed to the function. + */ + +/** + * Create a virtual file from a description. + * If `options` is a string or a buffer, it’s used as the path. + * If it’s a VFile itself, it’s returned instead. + * In all other cases, the options are passed through to `vfile()`. + * + * @param {Compatible} [options] + * @returns {VFile} + */ +function toVFile(options) { + if (typeof options === 'string' || options instanceof URL$1) { + options = {path: options}; + } else if (isBuffer(options)) { + options = {path: String(options)}; + } + + return looksLikeAVFile(options) ? options : new VFile(options) +} + +/** + * Create a virtual file and read it in, synchronously. + * + * @param {Compatible} description + * @param {ReadOptions} [options] + * @returns {VFile} + */ +function readSync(description, options) { + const file = toVFile(description); + file.value = fs.readFileSync(path$1.resolve(file.cwd, file.path), options); + return file +} + +/** + * Create a virtual file and write it in, synchronously. + * + * @param {Compatible} description + * @param {WriteOptions} [options] + * @returns {VFile} + */ +function writeSync(description, options) { + const file = toVFile(description); + fs.writeFileSync(path$1.resolve(file.cwd, file.path), file.value || '', options); + return file +} + +const read = + /** + * @type {{ + * (description: Compatible, options: ReadOptions, callback: Callback): void + * (description: Compatible, callback: Callback): void + * (description: Compatible, options?: ReadOptions): Promise + * }} + */ + ( + /** + * Create a virtual file and read it in, asynchronously. + * + * @param {Compatible} description + * @param {ReadOptions} [options] + * @param {Callback} [callback] + */ + function (description, options, callback) { + const file = toVFile(description); + + if (!callback && typeof options === 'function') { + callback = options; + options = null; + } + + if (!callback) { + return new Promise(executor) + } + + executor(resolve, callback); + + /** + * @param {VFile} result + */ + function resolve(result) { + callback(null, result); + } + + /** + * @param {(x: VFile) => void} resolve + * @param {(x: Error, y?: VFile) => void} reject + */ + function executor(resolve, reject) { + /** @type {string} */ + let fp; + + try { + fp = path$1.resolve(file.cwd, file.path); + } catch (error) { + return reject(error) + } + + fs.readFile(fp, options, done); + + /** + * @param {Error} error + * @param {Value} result + */ + function done(error, result) { + if (error) { + reject(error); + } else { + file.value = result; + resolve(file); + } + } + } + } + ); + +const write = + /** + * @type {{ + * (description: Compatible, options: WriteOptions, callback: Callback): void + * (description: Compatible, callback: Callback): void + * (description: Compatible, options?: WriteOptions): Promise + * }} + */ + ( + /** + * Create a virtual file and write it in, asynchronously. + * + * @param {Compatible} description + * @param {WriteOptions} [options] + * @param {Callback} [callback] + */ + function (description, options, callback) { + const file = toVFile(description); + + // Weird, right? Otherwise `fs` doesn’t accept it. + if (!callback && typeof options === 'function') { + callback = options; + options = undefined; + } + + if (!callback) { + return new Promise(executor) + } + + executor(resolve, callback); + + /** + * @param {VFile} result + */ + function resolve(result) { + callback(null, result); + } + + /** + * @param {(x: VFile) => void} resolve + * @param {(x: Error, y?: VFile) => void} reject + */ + function executor(resolve, reject) { + /** @type {string} */ + let fp; + + try { + fp = path$1.resolve(file.cwd, file.path); + } catch (error) { + return reject(error) + } + + fs.writeFile(fp, file.value || '', options, done); + + /** + * @param {Error} error + */ + function done(error) { + if (error) { + reject(error); + } else { + resolve(file); + } + } + } + } + ); + +/** + * @param {Compatible} value + * @returns {value is VFile} + */ +function looksLikeAVFile(value) { + return ( + value && + typeof value === 'object' && + 'message' in value && + 'messages' in value + ) +} + +toVFile.readSync = readSync; +toVFile.writeSync = writeSync; +toVFile.read = read; +toVFile.write = write; + +function hasFlag(flag, argv = process$1.argv) { + const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf('--'); + return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); +} + +const {env} = process$1; + +let flagForceColor; +if (hasFlag('no-color') || + hasFlag('no-colors') || + hasFlag('color=false') || + hasFlag('color=never')) { + flagForceColor = 0; +} else if (hasFlag('color') || + hasFlag('colors') || + hasFlag('color=true') || + hasFlag('color=always')) { + flagForceColor = 1; +} + +function envForceColor() { + if ('FORCE_COLOR' in env) { + if (env.FORCE_COLOR === 'true') { + return 1; + } + + if (env.FORCE_COLOR === 'false') { + return 0; + } + + return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + } +} + +function translateLevel(level) { + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3 + }; +} + +function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { + const noFlagForceColor = envForceColor(); + if (noFlagForceColor !== undefined) { + flagForceColor = noFlagForceColor; + } + + const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; + + if (forceColor === 0) { + return 0; + } + + if (sniffFlags) { + if (hasFlag('color=16m') || + hasFlag('color=full') || + hasFlag('color=truecolor')) { + return 3; + } + + if (hasFlag('color=256')) { + return 2; + } + } + + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } + + const min = forceColor || 0; + + if (env.TERM === 'dumb') { + return min; + } + + if (process$1.platform === 'win32') { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split('.'); + if ( + Number(osRelease[0]) >= 10 && + Number(osRelease[2]) >= 10586 + ) { + return Number(osRelease[2]) >= 14931 ? 3 : 2; + } + + return 1; + } + + if ('CI' in env) { + if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { + return 1; + } + + return min; + } + + if ('TEAMCITY_VERSION' in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === 'truecolor') { + return 3; + } + + if ('TERM_PROGRAM' in env) { + const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); + + switch (env.TERM_PROGRAM) { + case 'iTerm.app': + return version >= 3 ? 3 : 2; + case 'Apple_Terminal': + return 2; + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { + return 1; + } + + if ('COLORTERM' in env) { + return 1; + } + + return min; +} + +function createSupportsColor(stream, options = {}) { + const level = _supportsColor(stream, { + streamIsTTY: stream && stream.isTTY, + ...options + }); + + return translateLevel(level); +} + +const supportsColor = { + stdout: createSupportsColor({isTTY: tty.isatty(1)}), + stderr: createSupportsColor({isTTY: tty.isatty(2)}) +}; + +function ansiRegex({onlyFirst = false} = {}) { + const pattern = [ + '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', + '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' + ].join('|'); + + return new RegExp(pattern, onlyFirst ? undefined : 'g'); +} + +function stripAnsi(string) { + if (typeof string !== 'string') { + throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); + } + + return string.replace(ansiRegex(), ''); +} + +/* eslint-disable yoda */ + +function isFullwidthCodePoint(codePoint) { + if (!Number.isInteger(codePoint)) { + return false; + } + + // Code points are derived from: + // https://unicode.org/Public/UNIDATA/EastAsianWidth.txt + return codePoint >= 0x1100 && ( + codePoint <= 0x115F || // Hangul Jamo + codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET + codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET + // CJK Radicals Supplement .. Enclosed CJK Letters and Months + (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) || + // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A + (0x3250 <= codePoint && codePoint <= 0x4DBF) || + // CJK Unified Ideographs .. Yi Radicals + (0x4E00 <= codePoint && codePoint <= 0xA4C6) || + // Hangul Jamo Extended-A + (0xA960 <= codePoint && codePoint <= 0xA97C) || + // Hangul Syllables + (0xAC00 <= codePoint && codePoint <= 0xD7A3) || + // CJK Compatibility Ideographs + (0xF900 <= codePoint && codePoint <= 0xFAFF) || + // Vertical Forms + (0xFE10 <= codePoint && codePoint <= 0xFE19) || + // CJK Compatibility Forms .. Small Form Variants + (0xFE30 <= codePoint && codePoint <= 0xFE6B) || + // Halfwidth and Fullwidth Forms + (0xFF01 <= codePoint && codePoint <= 0xFF60) || + (0xFFE0 <= codePoint && codePoint <= 0xFFE6) || + // Kana Supplement + (0x1B000 <= codePoint && codePoint <= 0x1B001) || + // Enclosed Ideographic Supplement + (0x1F200 <= codePoint && codePoint <= 0x1F251) || + // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane + (0x20000 <= codePoint && codePoint <= 0x3FFFD) + ); +} + +var emojiRegex = function () { + // https://mths.be/emoji + return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; +}; + +function stringWidth(string) { + if (typeof string !== 'string' || string.length === 0) { + return 0; + } + + string = stripAnsi(string); + + if (string.length === 0) { + return 0; + } + + string = string.replace(emojiRegex(), ' '); + + let width = 0; + + for (let index = 0; index < string.length; index++) { + const codePoint = string.codePointAt(index); + + // Ignore control characters + if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) { + continue; + } + + // Ignore combining characters + if (codePoint >= 0x300 && codePoint <= 0x36F) { + continue; + } + + // Surrogates + if (codePoint > 0xFFFF) { + index++; + } + + width += isFullwidthCodePoint(codePoint) ? 2 : 1; + } + + return width; +} + +/** + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + * + * @typedef Statistics + * @property {number} fatal Fatal errors (`fatal: true`) + * @property {number} warn warning errors (`fatal: false`) + * @property {number} info informational messages (`fatal: null|undefined`) + * @property {number} nonfatal warning + info + * @property {number} total nonfatal + fatal + */ + +/** + * Get stats for a file, list of files, or list of messages. + * + * @param {Array.|VFile|VFileMessage} [value] + * @returns {Statistics} + */ +function statistics(value) { + var result = {true: 0, false: 0, null: 0}; + + if (value) { + if (Array.isArray(value)) { + list(value); + } else { + one(value); + } + } + + return { + fatal: result.true, + nonfatal: result.false + result.null, + warn: result.false, + info: result.null, + total: result.true + result.false + result.null + } + + /** + * @param {Array.} value + * @returns {void} + */ + function list(value) { + var index = -1; + + while (++index < value.length) { + one(value[index]); + } + } + + /** + * @param {VFile|VFileMessage} value + * @returns {void} + */ + function one(value) { + if ('messages' in value) return list(value.messages) + + result[ + value.fatal === undefined || value.fatal === null + ? null + : Boolean(value.fatal) + ]++; + } +} + +/** + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + */ + +var severities = {true: 2, false: 1, null: 0, undefined: 0}; + +/** + * @template {VFile} F + * @param {F} file + * @returns {F} + */ +function sort(file) { + file.messages.sort(comparator); + return file +} + +/** + * @param {VFileMessage} a + * @param {VFileMessage} b + * @returns {number} + */ +function comparator(a, b) { + return ( + check(a, b, 'line') || + check(a, b, 'column') || + severities[b.fatal] - severities[a.fatal] || + compare(a, b, 'source') || + compare(a, b, 'ruleId') || + compare(a, b, 'reason') || + 0 + ) +} + +/** + * @param {VFileMessage} a + * @param {VFileMessage} b + * @param {string} property + * @returns {number} + */ +function check(a, b, property) { + return (a[property] || 0) - (b[property] || 0) +} + +/** + * @param {VFileMessage} a + * @param {VFileMessage} b + * @param {string} property + * @returns {number} + */ +function compare(a, b, property) { + return String(a[property] || '').localeCompare(b[property] || '') +} + +/** + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + * @typedef {import('vfile-statistics').Statistics} Statistics + * + * @typedef Options + * @property {boolean} [color] + * @property {boolean} [silent=false] + * @property {boolean} [quiet=false] + * @property {boolean} [verbose=false] + * @property {string} [defaultName=''] + * + * @typedef _Row + * @property {string} place + * @property {string} label + * @property {string} reason + * @property {string} ruleId + * @property {string} source + * + * @typedef _FileRow + * @property {'file'} type + * @property {VFile} file + * @property {Statistics} stats + * + * @typedef {{[x: string]: number}} _Sizes + * + * @typedef _Info + * @property {Array.<_FileRow|_Row>} rows + * @property {Statistics} stats + * @property {_Sizes} sizes + */ + +const own = {}.hasOwnProperty; + +// @ts-expect-error Types are incorrect. +const supported = supportsColor.stderr.hasBasic; + +// `log-symbols` without chalk, ignored for Windows: +/* c8 ignore next 4 */ +const chars = + process.platform === 'win32' + ? {error: '×', warning: '‼'} + : {error: '✖', warning: '⚠'}; + +const labels = { + true: 'error', + false: 'warning', + null: 'info', + undefined: 'info' +}; + +/** + * Report a file’s messages. + * + * @param {Error|VFile|Array.} [files] + * @param {Options} [options] + * @returns {string} + */ +function reporter(files, options = {}) { + /** @type {boolean|undefined} */ + let one; + + if (!files) { + return '' + } + + // Error. + if ('name' in files && 'message' in files) { + return String(files.stack || files) + } + + // One file. + if (!Array.isArray(files)) { + one = true; + files = [files]; + } + + return format$1(transform(files, options), one, options) +} + +/** + * @param {Array.} files + * @param {Options} options + * @returns {_Info} + */ +function transform(files, options) { + /** @type {Array.<_FileRow|_Row>} */ + const rows = []; + /** @type {Array.} */ + const all = []; + /** @type {_Sizes} */ + const sizes = {}; + let index = -1; + + while (++index < files.length) { + // @ts-expect-error it works fine. + const messages = sort({messages: [...files[index].messages]}).messages; + /** @type {Array.<_Row>} */ + const messageRows = []; + let offset = -1; + + while (++offset < messages.length) { + const message = messages[offset]; + + if (!options.silent || message.fatal) { + all.push(message); + + const row = { + place: stringifyPosition( + message.position + ? message.position.end.line && message.position.end.column + ? message.position + : message.position.start + : undefined + ), + label: labels[/** @type {keyof labels} */ (String(message.fatal))], + reason: + (message.stack || message.message) + + (options.verbose && message.note ? '\n' + message.note : ''), + ruleId: message.ruleId || '', + source: message.source || '' + }; + + /** @type {keyof row} */ + let key; + + for (key in row) { + // eslint-disable-next-line max-depth + if (own.call(row, key)) { + sizes[key] = Math.max(size(row[key]), sizes[key] || 0); + } + } + + messageRows.push(row); + } + } + + if ((!options.quiet && !options.silent) || messageRows.length > 0) { + rows.push( + {type: 'file', file: files[index], stats: statistics(messages)}, + ...messageRows + ); + } + } + + return {rows, stats: statistics(all), sizes} +} + +/** + * @param {_Info} map + * @param {boolean|undefined} one + * @param {Options} options + */ +// eslint-disable-next-line complexity +function format$1(map, one, options) { + /** @type {boolean} */ + const enabled = + options.color === undefined || options.color === null + ? supported + : options.color; + /** @type {Array.} */ + const lines = []; + let index = -1; + + while (++index < map.rows.length) { + const row = map.rows[index]; + + if ('type' in row) { + const stats = row.stats; + let line = row.file.history[0] || options.defaultName || ''; + + line = + one && !options.defaultName && !row.file.history[0] + ? '' + : (enabled + ? '\u001B[4m' /* Underline. */ + + (stats.fatal + ? '\u001B[31m' /* Red. */ + : stats.total + ? '\u001B[33m' /* Yellow. */ + : '\u001B[32m') /* Green. */ + + line + + '\u001B[39m\u001B[24m' + : line) + + (row.file.stored && row.file.path !== row.file.history[0] + ? ' > ' + row.file.path + : ''); + + if (!stats.total) { + line = + (line ? line + ': ' : '') + + (row.file.stored + ? enabled + ? '\u001B[33mwritten\u001B[39m' /* Yellow. */ + : 'written' + : 'no issues found'); + } + + if (line) { + if (index && !('type' in map.rows[index - 1])) { + lines.push(''); + } + + lines.push(line); + } + } else { + let reason = row.reason; + const match = /\r?\n|\r/.exec(reason); + /** @type {string} */ + let rest; + + if (match) { + rest = reason.slice(match.index); + reason = reason.slice(0, match.index); + } else { + rest = ''; + } + + lines.push( + ( + ' ' + + ' '.repeat(map.sizes.place - size(row.place)) + + row.place + + ' ' + + (enabled + ? (row.label === 'error' + ? '\u001B[31m' /* Red. */ + : '\u001B[33m') /* Yellow. */ + + row.label + + '\u001B[39m' + : row.label) + + ' '.repeat(map.sizes.label - size(row.label)) + + ' ' + + reason + + ' '.repeat(map.sizes.reason - size(reason)) + + ' ' + + row.ruleId + + ' '.repeat(map.sizes.ruleId - size(row.ruleId)) + + ' ' + + (row.source || '') + ).replace(/ +$/, '') + rest + ); + } + } + + const stats = map.stats; + + if (stats.fatal || stats.warn) { + let line = ''; + + if (stats.fatal) { + line = + (enabled + ? '\u001B[31m' /* Red. */ + chars.error + '\u001B[39m' + : chars.error) + + ' ' + + stats.fatal + + ' ' + + (labels.true + (stats.fatal === 1 ? '' : 's')); + } + + if (stats.warn) { + line = + (line ? line + ', ' : '') + + (enabled + ? '\u001B[33m' /* Yellow. */ + chars.warning + '\u001B[39m' + : chars.warning) + + ' ' + + stats.warn + + ' ' + + (labels.false + (stats.warn === 1 ? '' : 's')); + } + + if (stats.total !== stats.fatal && stats.total !== stats.warn) { + line = stats.total + ' messages (' + line + ')'; + } + + lines.push('', line); + } + + return lines.join('\n') +} + +/** + * Get the length of `value`, ignoring ANSI sequences. + * + * @param {string} value + * @returns {number} + */ +function size(value) { + const match = /\r?\n|\r/.exec(value); + return stringWidth(match ? value.slice(0, match.index) : value) +} + +const paths = process.argv.slice(2); + +if (!paths.length) { + console.error('Usage: lint-md.mjs [ ...]'); + process.exit(1); +} + +let format = false; + +if (paths[0] === '--format') { + paths.shift(); + format = true; +} + +const linter = unified() + .use(remarkParse) + .use(remarkGfm) + .use(remarkPresetLintNode) + .use(remarkStringify); + +paths.forEach(async (path) => { + const file = await read(path); + const result = await linter.process(file); + if (format) { + fs.writeFileSync(path, result.toString()); + } else if (result.messages.length) { + process.exitCode = 1; + console.error(reporter(result)); + } +}); diff --git a/tools/lint-md/lint-md.src.mjs b/tools/lint-md/lint-md.src.mjs new file mode 100644 index 00000000000000..63d77b496b0b36 --- /dev/null +++ b/tools/lint-md/lint-md.src.mjs @@ -0,0 +1,40 @@ +import fs from 'fs'; + +import { unified } from 'unified'; +import remarkParse from 'remark-parse'; +import remarkStringify from 'remark-stringify'; +import presetLintNode from 'remark-preset-lint-node'; +import gfm from 'remark-gfm'; +import { read } from 'to-vfile'; +import { reporter } from 'vfile-reporter'; + +const paths = process.argv.slice(2); + +if (!paths.length) { + console.error('Usage: lint-md.mjs [ ...]'); + process.exit(1); +} + +let format = false; + +if (paths[0] === '--format') { + paths.shift(); + format = true; +} + +const linter = unified() + .use(remarkParse) + .use(gfm) + .use(presetLintNode) + .use(remarkStringify); + +paths.forEach(async (path) => { + const file = await read(path); + const result = await linter.process(file); + if (format) { + fs.writeFileSync(path, result.toString()); + } else if (result.messages.length) { + process.exitCode = 1; + console.error(reporter(result)); + } +}); diff --git a/tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs b/tools/lint-md/list-released-versions-from-changelogs.mjs similarity index 92% rename from tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs rename to tools/lint-md/list-released-versions-from-changelogs.mjs index f134e122985d85..52eb50d673e3a7 100755 --- a/tools/node-lint-md-cli-rollup/src/list-released-versions-from-changelogs.mjs +++ b/tools/lint-md/list-released-versions-from-changelogs.mjs @@ -3,7 +3,7 @@ import fs from 'node:fs'; import { createInterface } from 'node:readline'; -const dataFolder = new URL('../../../doc/changelogs/', import.meta.url); +const dataFolder = new URL('../../doc/changelogs/', import.meta.url); const result = []; async function getVersionsFromFile(file) { diff --git a/tools/node-lint-md-cli-rollup/package-lock.json b/tools/lint-md/package-lock.json similarity index 69% rename from tools/node-lint-md-cli-rollup/package-lock.json rename to tools/lint-md/package-lock.json index fd8ca9c653065a..d8066be8c3cdc4 100644 --- a/tools/node-lint-md-cli-rollup/package-lock.json +++ b/tools/lint-md/package-lock.json @@ -1,121 +1,25 @@ { - "name": "node-lint-md-cli-rollup", - "version": "2.0.2", + "name": "lint-md", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "node-lint-md-cli-rollup", - "version": "2.0.2", + "name": "lint-md", + "version": "1.0.0", "dependencies": { - "markdown-extensions": "^1.1.1", - "remark": "^14.0.1", "remark-gfm": "^2.0.0", + "remark-parse": "^10.0.0", "remark-preset-lint-node": "^3.0.1", - "unified-args": "^9.0.2" + "remark-stringify": "^10.0.0", + "to-vfile": "^7.2.2", + "unified": "^10.1.0", + "vfile-reporter": "^7.0.2" }, "devDependencies": { "@rollup/plugin-commonjs": "^20.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.4", - "rollup": "^2.56.3", - "shx": "^0.3.3" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" + "@rollup/plugin-node-resolve": "^13.0.5", + "rollup": "^2.57.0" } }, "node_modules/@rollup/plugin-commonjs": { @@ -139,22 +43,10 @@ "rollup": "^2.38.3" } }, - "node_modules/@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", - "dev": true, - "dependencies": { - "@rollup/pluginutils": "^3.0.8" - }, - "peerDependencies": { - "rollup": "^1.20.0 || ^2.0.0" - } - }, "node_modules/@rollup/plugin-node-resolve": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz", - "integrity": "sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.5.tgz", + "integrity": "sha512-mVaw6uxtvuGx/XCI4qBQXsDZJUfyx5vp39iE0J/7Hd6wDhEbjHr6aES7Nr9yWbuE0BY+oKp6N7Bq6jX5NCGNmQ==", "dev": true, "dependencies": { "@rollup/pluginutils": "^3.1.0", @@ -194,14 +86,6 @@ "integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==", "dev": true }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -224,16 +108,6 @@ "@types/unist": "*" } }, - "node_modules/@types/is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha512-brJKf2boFhUxTDxlpI7cstwiUtA2ovm38UzFTi9aZI6//ARncaV+Q5ALjCaJqXaMtdZk/oPTJnSutugsZR6h8A==" - }, - "node_modules/@types/js-yaml": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", - "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" - }, "node_modules/@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -248,9 +122,10 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "node_modules/@types/node": { - "version": "16.7.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.13.tgz", - "integrity": "sha512-pLUPDn+YG3FYEt/pHI74HmnJOWzeR+tOIQzUx93pi9M7D8OE7PSLr97HboXwk5F+JS+TLtWuzCOW97AHjmOXXA==" + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", + "dev": true }, "node_modules/@types/parse5": { "version": "6.0.1", @@ -271,11 +146,6 @@ "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==" }, - "node_modules/@types/text-table": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@types/text-table/-/text-table-0.2.2.tgz", - "integrity": "sha512-dGoI5Af7To0R2XE8wJuc6vwlavWARsCh3UKJPjWs1YEqGUqfgBI/j/4GX0yf19/DsDPPf0YAXWAp8psNeIehLg==" - }, "node_modules/@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -292,32 +162,6 @@ "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -335,41 +179,19 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, "node_modules/builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", @@ -382,25 +204,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/builtins": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.0.0.tgz", - "integrity": "sha512-qC0E2Dxgou1IHhvJSLwGDSTvokbRovU5zZFuDY6oY8Y2lF3nGt5Ad8YZK7GMtqzY84Wu7pXTPeHQeHcXSXsRhw==", - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ccount": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.0.tgz", @@ -410,21 +213,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/character-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz", @@ -461,47 +249,11 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/co": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "node_modules/comma-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", @@ -520,21 +272,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "node_modules/debug": { "version": "4.3.2", @@ -566,14 +305,6 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -596,62 +327,17 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "node_modules/fault": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.0.tgz", - "integrity": "sha512-JsDj9LFcoC+4ChII1QpXPA7YIaY8zmqPYw7h9j5n7St7a0BBKfNnwEBAUQRBx70o2q4rs+BeSNHk8Exm6xE7fQ==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -668,9 +354,10 @@ "dev": true }, "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -686,17 +373,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -710,11 +386,14 @@ } }, "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/hast-util-from-parse5": { @@ -816,30 +495,11 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-meta-resolve": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-1.1.1.tgz", - "integrity": "sha512-JiTuIvVyPaUg11eTrNDx5bgQ/yMKMZffc7YSjvQeSMXy58DO2SQ8BtAf3xteZvmzvjYh14wnqNjL8XVeDy2o9A==", - "dependencies": { - "builtins": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -848,21 +508,8 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true }, "node_modules/is-alphabetical": { "version": "2.0.0", @@ -886,22 +533,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -945,19 +576,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=" - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", @@ -969,17 +587,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-hexadecimal": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz", @@ -995,14 +602,6 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-plain-obj": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", @@ -1023,11 +622,6 @@ "@types/estree": "*" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1039,65 +633,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/libnpmconfig": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", - "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", - "dependencies": { - "figgy-pudding": "^3.5.1", - "find-up": "^3.0.0", - "ini": "^1.3.5" - } - }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "node_modules/load-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-4.0.1.tgz", - "integrity": "sha512-4kMi+mOSn/TR51pDo4tgxROHfBHXsrcyEYSGHcJ1o6TtRaP2PsRM5EwmYbj1uiLDvbfA/ohwuSWZJzqGiai8Dw==", - "dependencies": { - "import-meta-resolve": "^1.0.0", - "libnpmconfig": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/longest-streak": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.0.tgz", @@ -1127,14 +662,6 @@ "sourcemap-codec": "^1.4.4" } }, - "node_modules/markdown-extensions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/markdown-table": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.1.tgz", @@ -1168,15 +695,16 @@ } }, "node_modules/mdast-util-from-markdown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.0.tgz", - "integrity": "sha512-uj2G60sb7z1PNOeElFwCC9b/Se/lFXuLhVKFOAY2EHz/VvgbupTQRNXPoZl7rGpXYL6BNZgcgaybrlSWbo7n/g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.1.tgz", + "integrity": "sha512-KGPH5sDqbov0PWOEtElsLqLYC9tGGaOzznl6ss+rjDJP4bPe1t7T/K3oYwXPKTn+YzPUdorYirbz9pXEkapyYQ==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", - "mdast-util-to-string": "^3.0.0", + "mdast-util-to-string": "^3.1.0", "micromark": "^3.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", @@ -1204,9 +732,9 @@ } }, "node_modules/mdast-util-gfm-autolink-literal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.1.tgz", - "integrity": "sha512-dCUDNYXCytIonTHIUOZXp5S3FWd1XAt6IVH1fBfH6BbUF9U+9m1T9XllfHPvKJCccKNI+0RlYmQJ0rfMTDxEtA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.2.tgz", + "integrity": "sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==", "dependencies": { "@types/mdast": "^3.0.0", "ccount": "^2.0.0", @@ -1270,15 +798,15 @@ } }, "node_modules/mdast-util-to-markdown": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.1.tgz", - "integrity": "sha512-yj0UexEfdH0Zqw9CztzC5+J6OZKgCY6K0ommn56SBlPKIV3NGqk1Wo/zw1Q0e/kHb50wmQ8O9cwbOl7vmaJjxg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.3.tgz", + "integrity": "sha512-040jJYtjOUdbvYAXCfPrpLJRdvMOmR33KRqlhT4r+fEbVM+jao1RMbA8RmGeRmw8RAj3vQ+HvhIaJPijvnOwCg==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", "mdast-util-to-string": "^3.0.0", - "parse-entities": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", "zwitch": "^2.0.0" }, @@ -1647,6 +1175,26 @@ "micromark-util-symbol": "^1.0.0" } }, + "node_modules/micromark-util-decode-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.0.tgz", + "integrity": "sha512-4g5UJ8P/J8wuRKUXCcB7udQuOBXpLyvBQSLSuznfBLCG+thKG6UTwFnXfHkrr/1wddprkUbPatCzxDjrJ+5zDg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "parse-entities": "^3.0.0" + } + }, "node_modules/micromark-util-encode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz", @@ -1787,6 +1335,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1794,65 +1343,20 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "dependencies": { "wrappy": "1" } }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, "node_modules/parse-entities": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz", @@ -1870,40 +1374,16 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "engines": { - "node": ">=4" - } - }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -1918,6 +1398,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -1942,42 +1423,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/rehype": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.0.tgz", @@ -2022,21 +1467,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remark": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.1.tgz", - "integrity": "sha512-7zLG3u8EUjOGuaAS9gUNJPD2j+SqDqAFHv2g6WMpE5CU9rZ6e3IKDM12KHZ3x+YNje+NMAuN55yx8S5msGSx7Q==", - "dependencies": { - "@types/mdast": "^3.0.0", - "remark-parse": "^10.0.0", - "remark-stringify": "^10.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/remark-gfm": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-2.0.0.tgz", @@ -2053,9 +1483,9 @@ } }, "node_modules/remark-lint": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.0.1.tgz", - "integrity": "sha512-q4VFsA7LEG4REJhR2P4A6CU9b4cCQL53845CX74Z4N/W0EgB9mm/GXpYzjbEqgkMPl5ctP8yp/vBYTNmjfUCtw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.1.0.tgz", + "integrity": "sha512-47ZaPj1HSs17nqsu3CPg4nIhaj+XTEXJM9cpFybhyA4lzVRZiRXy43BokbEjBt0f1fhY3coQoOh16jJeGBvrJg==", "dependencies": { "@types/mdast": "^3.0.0", "remark-message-control": "^7.0.0", @@ -2067,9 +1497,9 @@ } }, "node_modules/remark-lint-blockquote-indentation": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.0.1.tgz", - "integrity": "sha512-CfjXeaomk3bxt1Y0Z4T/cKVoE+8lm5jw5C+jz8EieWNIziGNUlDxIAbMk1F1sO8EXc4LjkbTSq4zz8h1vOHkew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.1.0.tgz", + "integrity": "sha512-BX9XhW7yjnEp7kEMasBIQnIGOeQJYLrrQSMFoBNURLjPMBslSUrABFXUZI6hwFo5fd0dF9Wv1xt9zvSbrU9B7g==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2085,9 +1515,9 @@ } }, "node_modules/remark-lint-checkbox-character-style": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.0.1.tgz", - "integrity": "sha512-f/Dvcw4tsWWv0vx4POVZXZmiytsyGMCKmPiMefz4zfy9hTwTGngp9EZhbDivHXiqd5YTUhvjYXFITEfVdxH4qA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.1.0.tgz", + "integrity": "sha512-wV3NN4j21XoC3l76mmbU/kSl4Yx0SK91lHTEpimx9PBbRtb0cb/YZiyE3bkNSXGoj6iWDcB2asF4U4rRcT5t5A==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2101,9 +1531,9 @@ } }, "node_modules/remark-lint-checkbox-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.0.1.tgz", - "integrity": "sha512-uv4qIBdIxGshQ1a84a2RClbX39lYfWgPm3Wg35EJbSWPpe+KWt4rYi9nxB51dIEUXw3KAujlOVougPwhAZROuA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.1.0.tgz", + "integrity": "sha512-K2R9V1C/ezs2SfLsh5SdXlOuJVWaUwA2LsbjIp+jcd+Dt8otJ4Rul741ypL4Sji/vaxrQi5f4+iLYpfrUtjfDQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2118,9 +1548,9 @@ } }, "node_modules/remark-lint-code-block-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.0.1.tgz", - "integrity": "sha512-B6338x1UggrAMe4gdmk1No2L/OkK1d1uCelekj6cnl+Pi5/HLlSw3lXIaOTRNIXOccT1zMmNApA4sDZ5qsQWtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.1.0.tgz", + "integrity": "sha512-Hv4YQ8ueLGpjItla4CkcOkcfGj+nlquqylDgCm1/xKnW+Ke2a4qVTMVJrP9Krp4FWmXgktJLDHjhRH+pzhDXLg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2135,9 +1565,9 @@ } }, "node_modules/remark-lint-definition-spacing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.0.1.tgz", - "integrity": "sha512-jtCUaZ+6KP4nNutBoiWoqBfa2sMsD4uvvFbuU5MOlzI0wlMmaeAq1pxWuNtkK+w8AEk/8CzfCUrLct5w65KSLQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.1.0.tgz", + "integrity": "sha512-cJlT3+tjTTA3mv3k2ogdOELSdbkpGKDNZ1qwba0ReSCdNCVbxcejZ/rrU96n/guv34XgqFyDrzoc7kcxU8oyEg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2151,9 +1581,9 @@ } }, "node_modules/remark-lint-fenced-code-flag": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.0.1.tgz", - "integrity": "sha512-HsEhvalGxCauZO6OAnaVzIBycfaHLuyZxy1KlniWXQJKZ6EjRAsWwkZHYx9qfPl/ZW7zDG+xAoWTqdHjZW/BTg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.1.0.tgz", + "integrity": "sha512-s96DWERWUeDi3kcDbW6TQo4vRUsGJUNhT1XEsmUzYlwJJ+2uGit9O5dAxvEnwF3gZxp/09hPsQ+QSxilC1sxLg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2168,9 +1598,9 @@ } }, "node_modules/remark-lint-fenced-code-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.0.1.tgz", - "integrity": "sha512-vFRjlzyxtG3zdvmlTn6cV1YiZAivQwOzYRNnH5KavC39EZHDxqjQl84QTXshgfCzFupvYCi6ykATIa7obgx9jg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.1.0.tgz", + "integrity": "sha512-klvbiQBINePA51Icprq7biFCyZzbtsASwOa6WCzW/KpAFz2V9a57PTuZkO9MtdDhW0vLoHgsQ4b0P1MD7JHMEw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2184,9 +1614,9 @@ } }, "node_modules/remark-lint-file-extension": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.0.1.tgz", - "integrity": "sha512-A2N6XoLPbYyRhgXyTI7WlW9Nb9QvXQNXG514hjHdNNd0cL+5P4JU6vivgZiYfViCzOLgsys6hwhXBSC9ZQ45tw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.1.0.tgz", + "integrity": "sha512-3T2n5/FsQ2CcDDubO5F8h7a/GyzTCy+R9XF8L9L9dVuZoxl4AWr1J6AmxE02bTy4g/TMH90juLELT08WGR6D9Q==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2198,9 +1628,9 @@ } }, "node_modules/remark-lint-final-definition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.0.1.tgz", - "integrity": "sha512-bzha13GTKFnQ0h4ZvaHadK6HxM2eRJj/yj59aXyvJkHFNx7i0sQn1884t3yYM4ppdDmO+cCMMgsVo8DxE8ifFA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.1.0.tgz", + "integrity": "sha512-XUbCNX7EFc/f8PvdQeXl2d5eu2Nksb2dCxIri+QvL/ykQ0MluXTNUfVsasDfNp9OYFBbTuBf27WiffOTOwOHRw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2215,9 +1645,9 @@ } }, "node_modules/remark-lint-final-newline": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.0.1.tgz", - "integrity": "sha512-vv1LT36frgc0FVc7V52CdOxqh1TqGcNvAVD89935sb9wpEELiUfbGG1Xb9PVZoIaVQcFo8qEDWCvfhsKTKk8Nw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.1.0.tgz", + "integrity": "sha512-jD9zIfk+DYAhho7mGkNtT4+3Bn6eiOVYzEJUUqNZp1GMtCY69gyVCK7Oef3S2Z6xLJUlZvC2vZmezhn0URUl7w==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2229,9 +1659,9 @@ } }, "node_modules/remark-lint-first-heading-level": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.0.1.tgz", - "integrity": "sha512-3ym0v/aMFpHTGv2/DPln6NHB2DFnx6Nbd+3Z9kf6wfnJCzXNA3zXyCKt11i5MPzUV5wlwButcW+JkPDtDJsfog==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.1.0.tgz", + "integrity": "sha512-8OV6BEjB5JSUCQRNk+z8MFyqu5Cdtk7TCR6Y6slC4b8vYlj26VecG5Fo4nLXdSj9/Tx01z59Od2FzBRV+6A1Xg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2245,9 +1675,9 @@ } }, "node_modules/remark-lint-hard-break-spaces": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.0.1.tgz", - "integrity": "sha512-CPjbfc9DcV4Qy3d8jyhh/QXsLD5uRtweb0d04p2MyzMDrqwXAq5X4MW3rId3JbVVl7o1AKXq1FdvqIMrh9Rpuw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.1.0.tgz", + "integrity": "sha512-0nUJpsH0ibYtsxv3QS29C3axzyVZBz6RD28XWmelcuCfApWluDlW4pM8r0qa1lE1UrLVd3MocKpa4i1AKbkcsg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2262,9 +1692,9 @@ } }, "node_modules/remark-lint-heading-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.0.1.tgz", - "integrity": "sha512-/9rsTE+coYdUgT/spxg4ioorG2W5XdabLHajKjTOOQ4ME8Wa5fXHMJ3WpK3Vnz8ZKP7WQwTTPsKWIHcy5d6C+w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.1.0.tgz", + "integrity": "sha512-wQliHPDoK+YwMcuD3kxw6wudlXhYW5OUz0+z5sFIpg06vx7OfJEASo6d6G1zYG+KkEesZx1SP0SoyHV4urKYmg==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -2279,9 +1709,9 @@ } }, "node_modules/remark-lint-list-item-bullet-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.0.1.tgz", - "integrity": "sha512-7XjtSLUwvxHi28/q9XMzYy7A+agpArvLlTksD0r1jj5MpGYTSUW9b54rRRV3JxHJMoX+ZJ9juId6GmVaUZwsTg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.1.0.tgz", + "integrity": "sha512-KmVTNeaTXkAzm21wLv0GKYXMDU5EwlBncGNb9z4fyQx/mAsX+KWVw71b6+zdeai+hAF8ErENaN48DgLxQ/Z3Ug==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2295,9 +1725,9 @@ } }, "node_modules/remark-lint-list-item-indent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.0.1.tgz", - "integrity": "sha512-5/H5B2g6TTpJZiwMmBa/Drexwq5Dw50QoypTUgXwFETz91s7zvjy+IGGVoVv0L0LM0rCwblmgtLomqeWIyo9sA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.1.0.tgz", + "integrity": "sha512-+dTStrxiMz9beP+oe48ItMUHzIpMOivBs1+FU44o1AT6mExDGvDdt4jMtLCpPrZVFbzzIS00kf5FEDLqjNiaHg==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2313,9 +1743,9 @@ } }, "node_modules/remark-lint-maximum-line-length": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.0.1.tgz", - "integrity": "sha512-R4hiRRx46xa3NE/AY8IKzPTRVyq1ZWrtWVd2KfWwNHmj7a6ASjb75DPzGyckZ46UAQq9mSBPsgL5Rfhq5XmggA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.1.0.tgz", + "integrity": "sha512-EfXXQsrmdyoMdzlZ0yDjSPeEHv+os444SsTvrwPwrJWxj39fudakweM3xAk2NgDJc7UrcCZzKH+4yNDmL0NcvQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2330,9 +1760,9 @@ } }, "node_modules/remark-lint-no-auto-link-without-protocol": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.0.1.tgz", - "integrity": "sha512-FdbB9O4SegELBreglpOXhMyusKORPS0X7KrBY/V+tDo4+2sJHMEEdiN4RbK2ofWwRP7V+muZ5WrscLliuAExQg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.1.0.tgz", + "integrity": "sha512-GqZXDu/xfajWCEPhS8UjO9dYMTlY5lD8ShoYIaouUgz3nNQvLwX33pTKqfRpd/R9EmV1uQw0PCJ6TYwhBrnOXQ==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -2348,9 +1778,9 @@ } }, "node_modules/remark-lint-no-blockquote-without-marker": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.0.1.tgz", - "integrity": "sha512-3aUFCV1BSqO15MuJ6fQept36An/vLo9VgAj1TRWk4Gsnaewbq7haT/m6eiYn5Ia8t2sSBbv4LKz1lwnj5nOVPQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.1.0.tgz", + "integrity": "sha512-t9ohZSpHIZdlCp+h2nemFD/sM3Am6ZZEczaBpmTQn+OoKrZjpDRrMTb/60OBGXJXHNazfqRwm96unvM4qDs4+Q==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2366,9 +1796,9 @@ } }, "node_modules/remark-lint-no-consecutive-blank-lines": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.0.1.tgz", - "integrity": "sha512-nvwglXFdR8ubTjSduK3cVdgBaKCH/DqV0kVkCKSQmLEl8NyozFH03VB/bhQDCrmSeNt6rYClBF0ppaHT27OmpA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.1.0.tgz", + "integrity": "sha512-4gn7lPXAw9hw08apENVNvWjdtuNtgtHPA0mjqgjTszXC92IY1YW8zGfxChCLvCJ1bG4/isI6Ctx+ZmmQoZEW1Q==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -2385,9 +1815,9 @@ } }, "node_modules/remark-lint-no-duplicate-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.0.1.tgz", - "integrity": "sha512-gwQe65dW2fkMQR02hwlHtc0OOvshst+gXMOEwd1/fpIb6OORpMiK6ueoNBxCnKSsKqftjWV0JXVdZ7MfKKxQQw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.1.0.tgz", + "integrity": "sha512-kBBKK/btn6p0yOiVhB6mnasem7+RUCRjifoe58y/Um56qQsh1GtX6YHVNnboO7fp9aq46MKC2Yc93pEj5yEbDg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2403,9 +1833,9 @@ } }, "node_modules/remark-lint-no-file-name-articles": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.0.1.tgz", - "integrity": "sha512-9kZ/ydzJlntswJjsQEbPPx0tc6uAPuowmG/3aOCSE+6CjJ+bCQZiVLL3VhjktNyzFxDGTDN6LlbVwiyIHEUMwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.1.0.tgz", + "integrity": "sha512-+4gembcykiLnrsTxk4ld2fg3n3TgvHGBO6qMsRmjh5k2m2riwnewM80xfCGXrEVi5cciGIhmv4iU7uicp+WEVQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2417,9 +1847,9 @@ } }, "node_modules/remark-lint-no-file-name-consecutive-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.0.1.tgz", - "integrity": "sha512-e9ei9KwQSRzUQeYHEhCKUMDeavFOIj46NtuyZxYtrklOcblvaZLAV133UcFHk5CimdUj3dzTtFZebHdpvu5omw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.1.0.tgz", + "integrity": "sha512-jnQcsYaV8OkUMmFcXr/RWkJFKw30lqEtYTfmb9n/AUsBFeQt53cYYZjA+6AgvKSUW3be7CY2XptReTuM4jSHpQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2431,9 +1861,9 @@ } }, "node_modules/remark-lint-no-file-name-outer-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.0.1.tgz", - "integrity": "sha512-INp+0gW5T2j6+sHglmDmCLL7/goVKCryXyf+ZApB5oWYBpVr2fLnHEHTUmkbQkksxe7me+VsB+WW/KN1PXGrtw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.1.0.tgz", + "integrity": "sha512-R0eXcFpsfjXI4djN/AF734kydS+p5frZW6NsUzpEfLt5Eu/MhOuii2LvV/G1ujyclZAELpvZlV+sW4083SHi3g==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2445,9 +1875,9 @@ } }, "node_modules/remark-lint-no-heading-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.0.1.tgz", - "integrity": "sha512-IRYlydfT0Xt4AEs5OKSBGP9hLNDckd1mKcV8crnNu91HhcmFVJznzsLV1QrUTTI94cwkSmSWqpjNzsDrKGPbIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.1.0.tgz", + "integrity": "sha512-+V92BV7r4Ajc8/oe5DhHeMrn3pZHIoLyqLYM6YgkW2hPMn+eCLVAcrfdOiiVrBpgUNpZMIM9x7UwOq0O4hAr8A==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -2464,9 +1894,9 @@ } }, "node_modules/remark-lint-no-heading-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.0.1.tgz", - "integrity": "sha512-LjRsRJOPT1M5MwvGxGEPIHzB713chWgJF5v/FNaHnniLgBrwIbpmsqEhAAam/+i593B5tx84ZyaCf8ujXTP0gg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.1.0.tgz", + "integrity": "sha512-hy9W3YoHWR1AbsOAbhZDwzJAKmdLekmKhc5iC9VfEWVfXsSNHwjAoct4mrBNMEUcfFYhcOTKfyrIXwy1D7fXaw==", "dependencies": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -2482,9 +1912,9 @@ } }, "node_modules/remark-lint-no-inline-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.0.1.tgz", - "integrity": "sha512-UcjJ2XTf7kOmQo5mU/5AV+Gth1YYGcp+gYU4gS/CzdOLYstqsS/W+IN6ALJjEbdbtSyfWCElpxI4p/mW16Z90A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.1.0.tgz", + "integrity": "sha512-0dbIgBUhVIkIn8xji2b/j1tG+ETbzE+ZEYNtCRTsNCjFwvyvgzElWKMLHoLzTpXYAN8I5dQhyFcy8Qa/RXg3AA==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -2499,9 +1929,9 @@ } }, "node_modules/remark-lint-no-literal-urls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.0.1.tgz", - "integrity": "sha512-3OAFcaZawfrFgZGrpuZlNPyuvfIURtUzDN7/Bl2X42ivqx4ih1OH9LtiBgz+J0g1DEWnC5ebOmDr7x6XLM76Fw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.1.0.tgz", + "integrity": "sha512-FvSE16bvwMLh89kZzvyXnWh8MZ2WU+msSqfbF3pU/0YpnpxfRev9ShFRS1k8wVm5BdzSqhwplv4chLnAWg53yw==", "dependencies": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -2517,9 +1947,9 @@ } }, "node_modules/remark-lint-no-multiple-toplevel-headings": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.0.1.tgz", - "integrity": "sha512-K62PKOOanFiFM4R0oHlo1PKWJa0dPPasQl28yzk6G2xZzqc5eJm5S3d0grU479jqEUbDQMaDQw282hO6WR/MbA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.1.0.tgz", + "integrity": "sha512-F4z867UaYjWdWFzR4ZpPi+EIzoUcU/QtdEVftdVKNdBEy1pq2A/vdTUa/PGtc+LLeQn04mJ/SGPC2s7eMWAZfg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2535,9 +1965,9 @@ } }, "node_modules/remark-lint-no-shell-dollars": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.0.1.tgz", - "integrity": "sha512-QvnA8Ltj3FPaAqUu0DebKYv66LFndTk0fXVZ9rQWOjTEVIKImy9Dy59kVqwYMpCwZbJkpigu2bMl/7UG/BA0XA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.1.0.tgz", + "integrity": "sha512-f4+NPey3yzd9TpDka5Bs3W+MMJBPz6bQ7zK3M9Qc133lqZ81hKMGVRrOBafS1RNqD5htLZbbGyCoJa476QtW1w==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2551,9 +1981,9 @@ } }, "node_modules/remark-lint-no-shortcut-reference-image": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.0.1.tgz", - "integrity": "sha512-0o0YO88Atib0eWloy5ZbL2IZ1axMNysbJI5j58sxMjEwLq1JORtGOR9Z6aHsOccS5yseeenw5w3DoMLB9PtJtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.1.0.tgz", + "integrity": "sha512-uTXysJw749c42QnFt+DfG5NJTjfcQdM5gYGLugb/vgUwN8dzPu6DiGM3ih1Erwha6qEseV00FpFvDexHbQvJNw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2567,9 +1997,9 @@ } }, "node_modules/remark-lint-no-shortcut-reference-link": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.0.1.tgz", - "integrity": "sha512-uXujnVm5LXLtGyJkTIbn/uxDRu507B9vC8TieiX6HX8OjVeDWUjtcVJOaqeyLJGjV0Ri1Y+AegMNWx5eDBHTDQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.1.0.tgz", + "integrity": "sha512-SmM/sICFnlMx4PcuXIMJmyqTyI1+FQMOGh51GmLDWoyjbblP2hXD4UqrYLhAeV0aPQSNKwMXNNW0aysjdoWL0A==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2583,9 +2013,9 @@ } }, "node_modules/remark-lint-no-table-indentation": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.0.1.tgz", - "integrity": "sha512-GYBX5P1Vj0gO7S7JLU2tpYR5rg9xbeccPQ0ZgHYK4d7T9FjDwfE1hrdvlha3k8s3CFKqQ7MC0OgQw/2IN413MA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.1.0.tgz", + "integrity": "sha512-OJg95FHBZKyEUlnmHyMQ2j9qs5dnxk3oX1TQuREpFDgzQMh/Bcyc+CegmsDMDiyNyrs1QgDwubCWmAYWgdy4Gw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2600,9 +2030,9 @@ } }, "node_modules/remark-lint-no-tabs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.0.1.tgz", - "integrity": "sha512-B2q1I+fyRDvWTQxCC91NoEvz0KzI9e6Yhu1TdOLkwc02hMWj869G165Rh+EcBKGW/CLKuMPhIn2XtL86emqZRw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.1.0.tgz", + "integrity": "sha512-QjMDKdwoKtZyvqHvRQS6Wwy/sy2KwLGbjGJumGXhzYS6fU7r/EimYcCbNb0NgxJhs3sLhWKZB9m/W0hH6LYbnA==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2635,9 +2065,9 @@ } }, "node_modules/remark-lint-no-undefined-references": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.0.1.tgz", - "integrity": "sha512-mmNJO30TYMxwfFJPHkwKNRaW63sU9ffhpb4xkyhyHDmnsplQ96RVYR4WGOXw0/wR+gZECmFtBU+OIWz0cbaiEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.1.0.tgz", + "integrity": "sha512-xnBd6ZLWv9Lnf1dH6bC/IYywbzxloUNJwiJY2OzhtZUMsqH8Xw5ZAidhxIW3k+3K8Fs2WSwp7HjIzjp7ZSiuDA==", "dependencies": { "@types/mdast": "^3.0.0", "micromark-util-normalize-identifier": "^1.0.0", @@ -2654,9 +2084,9 @@ } }, "node_modules/remark-lint-no-unused-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.0.1.tgz", - "integrity": "sha512-bcbboInyb8vAPtYakZdaxRQsDIdQnV5WvUdc03PWFlG8YtGOhRQ57SPc+4uVH+VwHoq+lsEsRszr4sOXuuopxw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.1.0.tgz", + "integrity": "sha512-poSmPeY5wZYLXhiUV+rbrkWNNENjoUq2lUb/Ho34zorMeV70FNBEV+zv1A6Ri8+jplUDeLi1lqC0uBTlTAUuLQ==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2670,9 +2100,9 @@ } }, "node_modules/remark-lint-ordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-CGXvolLwfZIxG9hm4o7OXQXEEpu3r5oyTpYGteJDtOSrpVrBSqFKNq7lfhKYFQkcg2AMJYrH9XEexrYvAoUQOQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-/sYOjCK+FkAhwheIHjL65TxQKJ8infTVsDi5Dbl6XHaXiAzKjvZhwW4uJqgduufozlriI63DF68YMv5y6tyXsw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2699,9 +2129,9 @@ } }, "node_modules/remark-lint-rule-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.0.1.tgz", - "integrity": "sha512-j1e60nfZJk0C6mvDZkiFwVu0b58f219ATlMNaZ9h8QdQhdxD/0kUnizJ7xW3wS4sHtCgkKGctAp04Ma0c+Dkhg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.1.0.tgz", + "integrity": "sha512-Z2tW9kBNCdD8l+kG7bTKanfciqGGJt8HnBmV9eE3oIqVDzqWJoIQ8kVBDGh6efeOAlWDDDHGIp/jb4i/CJ/kvg==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2715,9 +2145,9 @@ } }, "node_modules/remark-lint-strong-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.0.1.tgz", - "integrity": "sha512-J5dJviBd747vXBkFuA2j/Ni7RjTg+Mg2GgXlPHtbgDnal51CdN2WXDmbVG/A98+3P18MlysvQ7KnBrSiiuGBpQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.1.0.tgz", + "integrity": "sha512-YkGZ2J1vayVa/uSWUOuqKzB3ot1RgtsAd/Kz7L2ve8lDDIjnxn+bUufaS6cN9K5/ADprryd1hdE29YRVj6Vs3g==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2731,9 +2161,9 @@ } }, "node_modules/remark-lint-table-cell-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.0.1.tgz", - "integrity": "sha512-NdF0WHFOaMjeumRIrGHXVadwWkgnfJuMb96FGbf1HvSEv9l41PHkS1KTsL6Zoe1Cva57niAuarMv6xzcJqVjrA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.1.0.tgz", + "integrity": "sha512-2FqYGR6IsO5HdmvBe15iwD8XI9xjyMBegKuJWK50bWAsIVdR1b80nfXxKDQ6lRDK6LZ7+iATxzTo0Fl3+TLmgw==", "dependencies": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -2748,9 +2178,9 @@ } }, "node_modules/remark-lint-table-pipes": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.0.1.tgz", - "integrity": "sha512-om6i8SMSjMsR/mYlx5cMSoxXK+EFI8/n73qCVx/RAhFCIsW4TFR+gYmgFTyLr5Mp4vqjV3uYBIR9Ucv6Johauw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.1.0.tgz", + "integrity": "sha512-kI50VXlEW9zUdMh8Y9T7vornqpnMr+Ywy+sUzEuhhmWeFIYcIsBbZTHA1253FgjA/iMkLPzByYWj1xGlUGL1jw==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2764,9 +2194,9 @@ } }, "node_modules/remark-lint-unordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-DPveL2hhkcY608Bkn/Hx+C7pxviufpYyRiu0CnfFxkbLBlMgVdvVIOGCCOlhbvKuGtozmH/RCRsdIfzjlkXiew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-oUThfe8/34DpXkGjOghOkSOqk8tGthnDNIMBtNVY+aMIkkuvCSxqFj9D/R37Al7/tqqgZ1D6ezpwxIOsa15JTA==", "dependencies": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -2812,9 +2242,9 @@ } }, "node_modules/remark-preset-lint-node": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.0.1.tgz", - "integrity": "sha512-L7yhho9q9vmpsfMHO2gRKFNj36106iFM4KpodE+3k3rGg5dcmhV+zcsftNh5NGzbKKKYsGQj9C5XxCR/0NwKDg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.1.0.tgz", + "integrity": "sha512-jWEl5ljKYmIiM2cnZbp7dIYmpFND33RWOCcm5cbp8m2GbOLMOaAW2cVBZe47XLAzpQcOIKaT2BjSsi7Y1h/cig==", "dependencies": { "js-yaml": "^4.0.0", "remark-lint-blockquote-indentation": "^3.0.0", @@ -2856,9 +2286,9 @@ } }, "node_modules/remark-preset-lint-recommended": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.0.1.tgz", - "integrity": "sha512-8ZlwP2aDCGf+3UFPP1K8CofWI/WLoq8hPhQiuKotCFNSdTe98/27XYqWXpbMt4feWtX4+tcJY1y0duuLK5lhBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.1.0.tgz", + "integrity": "sha512-1jUbuzRAP5idWu9GZ5x7M96Z1TcTWwJu0C8ziz5RLezWL9rChhw9kV6s0beR0lrY5Kl5E5pjA6SKaP7NyGi2ug==", "dependencies": { "@types/mdast": "^3.0.0", "remark-lint": "^9.0.0", @@ -2912,9 +2342,9 @@ } }, "node_modules/rollup": { - "version": "2.56.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", - "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", + "version": "2.57.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.57.0.tgz", + "integrity": "sha512-bKQIh1rWKofRee6mv8SrF2HdP6pea5QkwBZSMImJysFj39gQuiV8MEPBjXOCpzk3wSYp63M2v2wkWBmFC8O/rg==", "dev": true, "bin": { "rollup": "dist/bin/rollup" @@ -2926,25 +2356,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -2959,39 +2370,6 @@ "node": ">=10" } }, - "node_modules/shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dev": true, - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shx": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", - "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.4" - }, - "bin": { - "shx": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", @@ -3012,22 +2390,14 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.0.tgz", - "integrity": "sha512-zwXcRmLUdiWhMPrHz6EXITuyTgcEnUqDzspTkCLhQovxywWz6NP9VHgqfVg20V/1mUg0B95AKbXxNT+ALRmqCw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.1.tgz", + "integrity": "sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g==", "dependencies": { "emoji-regex": "^9.2.2", "is-fullwidth-code-point": "^4.0.0", - "strip-ansi": "^7.0.0" + "strip-ansi": "^7.0.1" }, "engines": { "node": ">=12" @@ -3050,11 +2420,11 @@ } }, "node_modules/strip-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.0.tgz", - "integrity": "sha512-UhDTSnGF1dc0DRbUqr1aXwNoY3RgVkSWG8BrpnuFIxhP57IqbS7IRta2Gfiavds4yCxc5+fEAVVOgBZWnYkvzg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", "dependencies": { - "ansi-regex": "^6.0.0" + "ansi-regex": "^6.0.1" }, "engines": { "node": ">=12" @@ -3064,30 +2434,17 @@ } }, "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", + "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", "dependencies": { - "has-flag": "^4.0.0" + "has-flag": "^5.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" + "node": ">=12" }, - "engines": { - "node": ">=8.0" + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/to-vfile": { @@ -3112,11 +2469,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, "node_modules/unified": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", @@ -3135,64 +2487,10 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unified-args": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-9.0.2.tgz", - "integrity": "sha512-qSqryjoqfJSII4E4Z2Jx7MhXX2MuUIn6DsrlmL8UnWFdGtrWvEtvm7Rx5fKT5TPUz7q/Fb4oxwIHLCttvAuRLQ==", - "dependencies": { - "@types/text-table": "^0.2.0", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "chokidar": "^3.0.0", - "fault": "^2.0.0", - "json5": "^2.0.0", - "minimist": "^1.0.0", - "text-table": "^0.2.0", - "unified-engine": "^9.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unified-engine": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-9.0.4.tgz", - "integrity": "sha512-NFI+jC3DWZ23eBsWkOW2havz47DPG/DSyJEvBH+qA5cQHF6zlgiJYev7ksb/naOypZZ+cfhaCxCRo2BqrysYEw==", - "dependencies": { - "@types/concat-stream": "^1.0.0", - "@types/debug": "^4.0.0", - "@types/is-empty": "^1.0.0", - "@types/js-yaml": "^4.0.0", - "@types/node": "^16.0.0", - "@types/unist": "^2.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.0.0", - "fault": "^2.0.0", - "glob": "^7.0.0", - "ignore": "^5.0.0", - "is-buffer": "^2.0.0", - "is-empty": "^1.0.0", - "is-plain-obj": "^4.0.0", - "js-yaml": "^4.0.0", - "load-plugin": "^4.0.0", - "parse-json": "^5.0.0", - "to-vfile": "^7.0.0", - "trough": "^2.0.0", - "unist-util-inspect": "^7.0.0", - "vfile-message": "^3.0.0", - "vfile-reporter": "^7.0.0", - "vfile-statistics": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unified-lint-rule": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.1.tgz", - "integrity": "sha512-2RzZuuuWW+ifftM0zd/ZEng0Hb5lah+Zi+ZL/ybj8BrLO/TH2aQAMYvG+iC95aCg2FkWu/pcvVvHqsh2UMmzPg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.1.0.tgz", + "integrity": "sha512-pB2Uht3w+A9ceWXMYI0YWwxCTqC5on6jrApWDWSsYDBjaljSv8s64qdHHMCXFIUAGdd6V/XWrVMxiboHOAXo3Q==", "dependencies": { "@types/unist": "^2.0.0", "trough": "^2.0.0", @@ -3244,18 +2542,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-inspect": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-7.0.0.tgz", - "integrity": "sha512-2Utgv78I7PUu461Y9cdo+IUiiKSKpDV5CE/XD6vTj849a3xlpDAScvSJ6cQmtFBGgAmCn2wR7jLuXhpg1XLlJw==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/unist-util-is": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", @@ -3314,9 +2600,9 @@ } }, "node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", - "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz", + "integrity": "sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==", "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" @@ -3326,11 +2612,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, "node_modules/vfile": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.1.0.tgz", @@ -3389,31 +2670,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-reporter/node_modules/has-flag": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", - "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/vfile-reporter/node_modules/supports-color": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", - "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", - "dependencies": { - "has-flag": "^5.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, "node_modules/vfile-sort": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-3.0.0.tgz", @@ -3459,7 +2715,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "node_modules/yallist": { "version": "4.0.0", @@ -3477,80 +2734,6 @@ } }, "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==" - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "@rollup/plugin-commonjs": { "version": "20.0.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-20.0.0.tgz", @@ -3566,19 +2749,10 @@ "resolve": "^1.17.0" } }, - "@rollup/plugin-json": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@rollup/plugin-json/-/plugin-json-4.1.0.tgz", - "integrity": "sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==", - "dev": true, - "requires": { - "@rollup/pluginutils": "^3.0.8" - } - }, "@rollup/plugin-node-resolve": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.4.tgz", - "integrity": "sha512-eYq4TFy40O8hjeDs+sIxEH/jc9lyuI2k9DM557WN6rO5OpnC2qXMBNj4IKH1oHrnAazL49C5p0tgP0/VpqJ+/w==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-13.0.5.tgz", + "integrity": "sha512-mVaw6uxtvuGx/XCI4qBQXsDZJUfyx5vp39iE0J/7Hd6wDhEbjHr6aES7Nr9yWbuE0BY+oKp6N7Bq6jX5NCGNmQ==", "dev": true, "requires": { "@rollup/pluginutils": "^3.1.0", @@ -3608,14 +2782,6 @@ } } }, - "@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "requires": { - "@types/node": "*" - } - }, "@types/debug": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", @@ -3638,16 +2804,6 @@ "@types/unist": "*" } }, - "@types/is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha512-brJKf2boFhUxTDxlpI7cstwiUtA2ovm38UzFTi9aZI6//ARncaV+Q5ALjCaJqXaMtdZk/oPTJnSutugsZR6h8A==" - }, - "@types/js-yaml": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", - "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" - }, "@types/mdast": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.10.tgz", @@ -3662,9 +2818,10 @@ "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, "@types/node": { - "version": "16.7.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.13.tgz", - "integrity": "sha512-pLUPDn+YG3FYEt/pHI74HmnJOWzeR+tOIQzUx93pi9M7D8OE7PSLr97HboXwk5F+JS+TLtWuzCOW97AHjmOXXA==" + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.6.tgz", + "integrity": "sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==", + "dev": true }, "@types/parse5": { "version": "6.0.1", @@ -3685,11 +2842,6 @@ "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-dPWnWsf+kzIG140B8z2w3fr5D03TLWbOAFQl45xUpI3vcizeXriNR5VYkWZ+WTMsUHqZ9Xlt3hrxGNANFyNQfw==" }, - "@types/text-table": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@types/text-table/-/text-table-0.2.2.tgz", - "integrity": "sha512-dGoI5Af7To0R2XE8wJuc6vwlavWARsCh3UKJPjWs1YEqGUqfgBI/j/4GX0yf19/DsDPPf0YAXWAp8psNeIehLg==" - }, "@types/unist": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", @@ -3700,23 +2852,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -3730,68 +2865,30 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, "builtin-modules": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", "dev": true }, - "builtins": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.0.0.tgz", - "integrity": "sha512-qC0E2Dxgou1IHhvJSLwGDSTvokbRovU5zZFuDY6oY8Y2lF3nGt5Ad8YZK7GMtqzY84Wu7pXTPeHQeHcXSXsRhw==", - "requires": { - "semver": "^7.0.0" - } - }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" - }, "ccount": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.0.tgz", "integrity": "sha512-VOR0NWFYX65n9gELQdcpqsie5L5ihBXuZGAgaPEp/U7IOSjnPMEH6geE+2f6lcekaNEfWzAHS45mPvSo5bqsUA==" }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "character-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.0.tgz", @@ -3812,39 +2909,11 @@ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.0.tgz", "integrity": "sha512-pE3Z15lLRxDzWJy7bBHBopRwfI20sbrMVLQTC7xsPglCHf4Wv1e167OgYAFP78co2XlhojDyAqA+IAJse27//g==" }, - "chokidar": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", - "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, "co": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", "integrity": "sha1-TqVOpaCJOBUxheFSEMaNkJK8G3g=" }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, "comma-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz", @@ -3859,18 +2928,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "debug": { "version": "4.3.2", @@ -3891,73 +2950,33 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, "escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" }, "estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "fault": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.0.tgz", - "integrity": "sha512-JsDj9LFcoC+4ChII1QpXPA7YIaY8zmqPYw7h9j5n7St7a0BBKfNnwEBAUQRBx70o2q4rs+BeSNHk8Exm6xE7fQ==", - "requires": { - "format": "^0.2.0" - } - }, - "figgy-pudding": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", - "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs=" + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "optional": true }, "function-bind": { @@ -3967,9 +2986,10 @@ "dev": true }, "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3979,14 +2999,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -3997,9 +3009,9 @@ } }, "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==" }, "hast-util-from-parse5": { "version": "7.1.0", @@ -4072,23 +3084,11 @@ "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.0.tgz", "integrity": "sha512-4OYzQQsBt0G9bJ/nM9/DDsjm4+fVdzAaPJJcWk5QwA3GIAPxQEeOR0rsI8HbDHQz5Gta8pVvGnnTNSbZVEVvkQ==" }, - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" - }, - "import-meta-resolve": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-1.1.1.tgz", - "integrity": "sha512-JiTuIvVyPaUg11eTrNDx5bgQ/yMKMZffc7YSjvQeSMXy58DO2SQ8BtAf3xteZvmzvjYh14wnqNjL8XVeDy2o9A==", - "requires": { - "builtins": "^4.0.0" - } - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4097,17 +3097,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "is-alphabetical": { @@ -4124,19 +3114,6 @@ "is-decimal": "^2.0.0" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" - } - }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -4156,29 +3133,11 @@ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.0.tgz", "integrity": "sha512-QfrfjQV0LjoWQ1K1XSoEZkTAzSa14RKVMa5zg3SdAfzEmQzRM4+tbSFWb78creCeA9rNBzaZal92opi1TwPWZw==" }, - "is-empty": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", - "integrity": "sha1-3pu1snhzigWgsJpX4ftNSjQan2s=" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" - }, "is-fullwidth-code-point": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==" }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, "is-hexadecimal": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.0.tgz", @@ -4190,11 +3149,6 @@ "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", "dev": true }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, "is-plain-obj": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", @@ -4209,11 +3163,6 @@ "@types/estree": "*" } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -4222,52 +3171,6 @@ "argparse": "^2.0.1" } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "requires": { - "minimist": "^1.2.5" - } - }, - "libnpmconfig": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", - "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", - "requires": { - "figgy-pudding": "^3.5.1", - "find-up": "^3.0.0", - "ini": "^1.3.5" - } - }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" - }, - "load-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-4.0.1.tgz", - "integrity": "sha512-4kMi+mOSn/TR51pDo4tgxROHfBHXsrcyEYSGHcJ1o6TtRaP2PsRM5EwmYbj1uiLDvbfA/ohwuSWZJzqGiai8Dw==", - "requires": { - "import-meta-resolve": "^1.0.0", - "libnpmconfig": "^1.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, "longest-streak": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.0.tgz", @@ -4290,11 +3193,6 @@ "sourcemap-codec": "^1.4.4" } }, - "markdown-extensions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==" - }, "markdown-table": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.1.tgz", @@ -4316,15 +3214,16 @@ } }, "mdast-util-from-markdown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.0.tgz", - "integrity": "sha512-uj2G60sb7z1PNOeElFwCC9b/Se/lFXuLhVKFOAY2EHz/VvgbupTQRNXPoZl7rGpXYL6BNZgcgaybrlSWbo7n/g==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.0.1.tgz", + "integrity": "sha512-KGPH5sDqbov0PWOEtElsLqLYC9tGGaOzznl6ss+rjDJP4bPe1t7T/K3oYwXPKTn+YzPUdorYirbz9pXEkapyYQ==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", - "mdast-util-to-string": "^3.0.0", + "mdast-util-to-string": "^3.1.0", "micromark": "^3.0.0", "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", "micromark-util-normalize-identifier": "^1.0.0", "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0", @@ -4344,9 +3243,9 @@ } }, "mdast-util-gfm-autolink-literal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.1.tgz", - "integrity": "sha512-dCUDNYXCytIonTHIUOZXp5S3FWd1XAt6IVH1fBfH6BbUF9U+9m1T9XllfHPvKJCccKNI+0RlYmQJ0rfMTDxEtA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.2.tgz", + "integrity": "sha512-FzopkOd4xTTBeGXhXSBU0OCDDh5lUj2rd+HQqG92Ld+jL4lpUfgX2AT2OHAVP9aEeDKp7G92fuooSZcYJA3cRg==", "requires": { "@types/mdast": "^3.0.0", "ccount": "^2.0.0", @@ -4390,15 +3289,15 @@ } }, "mdast-util-to-markdown": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.1.tgz", - "integrity": "sha512-yj0UexEfdH0Zqw9CztzC5+J6OZKgCY6K0ommn56SBlPKIV3NGqk1Wo/zw1Q0e/kHb50wmQ8O9cwbOl7vmaJjxg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.2.3.tgz", + "integrity": "sha512-040jJYtjOUdbvYAXCfPrpLJRdvMOmR33KRqlhT4r+fEbVM+jao1RMbA8RmGeRmw8RAj3vQ+HvhIaJPijvnOwCg==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", "longest-streak": "^3.0.0", "mdast-util-to-string": "^3.0.0", - "parse-entities": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", "unist-util-visit": "^4.0.0", "zwitch": "^2.0.0" } @@ -4615,6 +3514,16 @@ "micromark-util-symbol": "^1.0.0" } }, + "micromark-util-decode-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.0.0.tgz", + "integrity": "sha512-4g5UJ8P/J8wuRKUXCcB7udQuOBXpLyvBQSLSuznfBLCG+thKG6UTwFnXfHkrr/1wddprkUbPatCzxDjrJ+5zDg==", + "requires": { + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "parse-entities": "^3.0.0" + } + }, "micromark-util-encode": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.0.0.tgz", @@ -4675,54 +3584,25 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, "parse-entities": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-3.0.0.tgz", @@ -4736,31 +3616,16 @@ "is-hexadecimal": "^2.0.0" } }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-parse": { "version": "1.0.7", @@ -4771,7 +3636,8 @@ "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true }, "pluralize": { "version": "8.0.0", @@ -4783,33 +3649,6 @@ "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.0.1.tgz", "integrity": "sha512-F4WUUAF7fMeF4/JUFHNBWDaKDXi2jbvqBW/y6o5wsf3j19wTZ7S60TmtB5HoBhtgw7NKQRMWuz5vk2PR0CygUg==" }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, "rehype": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.0.tgz", @@ -4842,17 +3681,6 @@ "unified": "^10.0.0" } }, - "remark": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-14.0.1.tgz", - "integrity": "sha512-7zLG3u8EUjOGuaAS9gUNJPD2j+SqDqAFHv2g6WMpE5CU9rZ6e3IKDM12KHZ3x+YNje+NMAuN55yx8S5msGSx7Q==", - "requires": { - "@types/mdast": "^3.0.0", - "remark-parse": "^10.0.0", - "remark-stringify": "^10.0.0", - "unified": "^10.0.0" - } - }, "remark-gfm": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-2.0.0.tgz", @@ -4865,9 +3693,9 @@ } }, "remark-lint": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.0.1.tgz", - "integrity": "sha512-q4VFsA7LEG4REJhR2P4A6CU9b4cCQL53845CX74Z4N/W0EgB9mm/GXpYzjbEqgkMPl5ctP8yp/vBYTNmjfUCtw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-9.1.0.tgz", + "integrity": "sha512-47ZaPj1HSs17nqsu3CPg4nIhaj+XTEXJM9cpFybhyA4lzVRZiRXy43BokbEjBt0f1fhY3coQoOh16jJeGBvrJg==", "requires": { "@types/mdast": "^3.0.0", "remark-message-control": "^7.0.0", @@ -4875,9 +3703,9 @@ } }, "remark-lint-blockquote-indentation": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.0.1.tgz", - "integrity": "sha512-CfjXeaomk3bxt1Y0Z4T/cKVoE+8lm5jw5C+jz8EieWNIziGNUlDxIAbMk1F1sO8EXc4LjkbTSq4zz8h1vOHkew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-blockquote-indentation/-/remark-lint-blockquote-indentation-3.1.0.tgz", + "integrity": "sha512-BX9XhW7yjnEp7kEMasBIQnIGOeQJYLrrQSMFoBNURLjPMBslSUrABFXUZI6hwFo5fd0dF9Wv1xt9zvSbrU9B7g==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -4889,9 +3717,9 @@ } }, "remark-lint-checkbox-character-style": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.0.1.tgz", - "integrity": "sha512-f/Dvcw4tsWWv0vx4POVZXZmiytsyGMCKmPiMefz4zfy9hTwTGngp9EZhbDivHXiqd5YTUhvjYXFITEfVdxH4qA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-character-style/-/remark-lint-checkbox-character-style-4.1.0.tgz", + "integrity": "sha512-wV3NN4j21XoC3l76mmbU/kSl4Yx0SK91lHTEpimx9PBbRtb0cb/YZiyE3bkNSXGoj6iWDcB2asF4U4rRcT5t5A==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4901,9 +3729,9 @@ } }, "remark-lint-checkbox-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.0.1.tgz", - "integrity": "sha512-uv4qIBdIxGshQ1a84a2RClbX39lYfWgPm3Wg35EJbSWPpe+KWt4rYi9nxB51dIEUXw3KAujlOVougPwhAZROuA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-checkbox-content-indent/-/remark-lint-checkbox-content-indent-4.1.0.tgz", + "integrity": "sha512-K2R9V1C/ezs2SfLsh5SdXlOuJVWaUwA2LsbjIp+jcd+Dt8otJ4Rul741ypL4Sji/vaxrQi5f4+iLYpfrUtjfDQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4914,9 +3742,9 @@ } }, "remark-lint-code-block-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.0.1.tgz", - "integrity": "sha512-B6338x1UggrAMe4gdmk1No2L/OkK1d1uCelekj6cnl+Pi5/HLlSw3lXIaOTRNIXOccT1zMmNApA4sDZ5qsQWtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-code-block-style/-/remark-lint-code-block-style-3.1.0.tgz", + "integrity": "sha512-Hv4YQ8ueLGpjItla4CkcOkcfGj+nlquqylDgCm1/xKnW+Ke2a4qVTMVJrP9Krp4FWmXgktJLDHjhRH+pzhDXLg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4927,9 +3755,9 @@ } }, "remark-lint-definition-spacing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.0.1.tgz", - "integrity": "sha512-jtCUaZ+6KP4nNutBoiWoqBfa2sMsD4uvvFbuU5MOlzI0wlMmaeAq1pxWuNtkK+w8AEk/8CzfCUrLct5w65KSLQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-definition-spacing/-/remark-lint-definition-spacing-3.1.0.tgz", + "integrity": "sha512-cJlT3+tjTTA3mv3k2ogdOELSdbkpGKDNZ1qwba0ReSCdNCVbxcejZ/rrU96n/guv34XgqFyDrzoc7kcxU8oyEg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4939,9 +3767,9 @@ } }, "remark-lint-fenced-code-flag": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.0.1.tgz", - "integrity": "sha512-HsEhvalGxCauZO6OAnaVzIBycfaHLuyZxy1KlniWXQJKZ6EjRAsWwkZHYx9qfPl/ZW7zDG+xAoWTqdHjZW/BTg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-flag/-/remark-lint-fenced-code-flag-3.1.0.tgz", + "integrity": "sha512-s96DWERWUeDi3kcDbW6TQo4vRUsGJUNhT1XEsmUzYlwJJ+2uGit9O5dAxvEnwF3gZxp/09hPsQ+QSxilC1sxLg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4952,9 +3780,9 @@ } }, "remark-lint-fenced-code-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.0.1.tgz", - "integrity": "sha512-vFRjlzyxtG3zdvmlTn6cV1YiZAivQwOzYRNnH5KavC39EZHDxqjQl84QTXshgfCzFupvYCi6ykATIa7obgx9jg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-fenced-code-marker/-/remark-lint-fenced-code-marker-3.1.0.tgz", + "integrity": "sha512-klvbiQBINePA51Icprq7biFCyZzbtsASwOa6WCzW/KpAFz2V9a57PTuZkO9MtdDhW0vLoHgsQ4b0P1MD7JHMEw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4964,9 +3792,9 @@ } }, "remark-lint-file-extension": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.0.1.tgz", - "integrity": "sha512-A2N6XoLPbYyRhgXyTI7WlW9Nb9QvXQNXG514hjHdNNd0cL+5P4JU6vivgZiYfViCzOLgsys6hwhXBSC9ZQ45tw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-file-extension/-/remark-lint-file-extension-2.1.0.tgz", + "integrity": "sha512-3T2n5/FsQ2CcDDubO5F8h7a/GyzTCy+R9XF8L9L9dVuZoxl4AWr1J6AmxE02bTy4g/TMH90juLELT08WGR6D9Q==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4974,9 +3802,9 @@ } }, "remark-lint-final-definition": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.0.1.tgz", - "integrity": "sha512-bzha13GTKFnQ0h4ZvaHadK6HxM2eRJj/yj59aXyvJkHFNx7i0sQn1884t3yYM4ppdDmO+cCMMgsVo8DxE8ifFA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-definition/-/remark-lint-final-definition-3.1.0.tgz", + "integrity": "sha512-XUbCNX7EFc/f8PvdQeXl2d5eu2Nksb2dCxIri+QvL/ykQ0MluXTNUfVsasDfNp9OYFBbTuBf27WiffOTOwOHRw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4987,9 +3815,9 @@ } }, "remark-lint-final-newline": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.0.1.tgz", - "integrity": "sha512-vv1LT36frgc0FVc7V52CdOxqh1TqGcNvAVD89935sb9wpEELiUfbGG1Xb9PVZoIaVQcFo8qEDWCvfhsKTKk8Nw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-final-newline/-/remark-lint-final-newline-2.1.0.tgz", + "integrity": "sha512-jD9zIfk+DYAhho7mGkNtT4+3Bn6eiOVYzEJUUqNZp1GMtCY69gyVCK7Oef3S2Z6xLJUlZvC2vZmezhn0URUl7w==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -4997,9 +3825,9 @@ } }, "remark-lint-first-heading-level": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.0.1.tgz", - "integrity": "sha512-3ym0v/aMFpHTGv2/DPln6NHB2DFnx6Nbd+3Z9kf6wfnJCzXNA3zXyCKt11i5MPzUV5wlwButcW+JkPDtDJsfog==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-first-heading-level/-/remark-lint-first-heading-level-3.1.0.tgz", + "integrity": "sha512-8OV6BEjB5JSUCQRNk+z8MFyqu5Cdtk7TCR6Y6slC4b8vYlj26VecG5Fo4nLXdSj9/Tx01z59Od2FzBRV+6A1Xg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5009,9 +3837,9 @@ } }, "remark-lint-hard-break-spaces": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.0.1.tgz", - "integrity": "sha512-CPjbfc9DcV4Qy3d8jyhh/QXsLD5uRtweb0d04p2MyzMDrqwXAq5X4MW3rId3JbVVl7o1AKXq1FdvqIMrh9Rpuw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-hard-break-spaces/-/remark-lint-hard-break-spaces-3.1.0.tgz", + "integrity": "sha512-0nUJpsH0ibYtsxv3QS29C3axzyVZBz6RD28XWmelcuCfApWluDlW4pM8r0qa1lE1UrLVd3MocKpa4i1AKbkcsg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5022,9 +3850,9 @@ } }, "remark-lint-heading-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.0.1.tgz", - "integrity": "sha512-/9rsTE+coYdUgT/spxg4ioorG2W5XdabLHajKjTOOQ4ME8Wa5fXHMJ3WpK3Vnz8ZKP7WQwTTPsKWIHcy5d6C+w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-heading-style/-/remark-lint-heading-style-3.1.0.tgz", + "integrity": "sha512-wQliHPDoK+YwMcuD3kxw6wudlXhYW5OUz0+z5sFIpg06vx7OfJEASo6d6G1zYG+KkEesZx1SP0SoyHV4urKYmg==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -5035,9 +3863,9 @@ } }, "remark-lint-list-item-bullet-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.0.1.tgz", - "integrity": "sha512-7XjtSLUwvxHi28/q9XMzYy7A+agpArvLlTksD0r1jj5MpGYTSUW9b54rRRV3JxHJMoX+ZJ9juId6GmVaUZwsTg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-bullet-indent/-/remark-lint-list-item-bullet-indent-4.1.0.tgz", + "integrity": "sha512-KmVTNeaTXkAzm21wLv0GKYXMDU5EwlBncGNb9z4fyQx/mAsX+KWVw71b6+zdeai+hAF8ErENaN48DgLxQ/Z3Ug==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -5047,9 +3875,9 @@ } }, "remark-lint-list-item-indent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.0.1.tgz", - "integrity": "sha512-5/H5B2g6TTpJZiwMmBa/Drexwq5Dw50QoypTUgXwFETz91s7zvjy+IGGVoVv0L0LM0rCwblmgtLomqeWIyo9sA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-list-item-indent/-/remark-lint-list-item-indent-3.1.0.tgz", + "integrity": "sha512-+dTStrxiMz9beP+oe48ItMUHzIpMOivBs1+FU44o1AT6mExDGvDdt4jMtLCpPrZVFbzzIS00kf5FEDLqjNiaHg==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -5061,9 +3889,9 @@ } }, "remark-lint-maximum-line-length": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.0.1.tgz", - "integrity": "sha512-R4hiRRx46xa3NE/AY8IKzPTRVyq1ZWrtWVd2KfWwNHmj7a6ASjb75DPzGyckZ46UAQq9mSBPsgL5Rfhq5XmggA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-maximum-line-length/-/remark-lint-maximum-line-length-3.1.0.tgz", + "integrity": "sha512-EfXXQsrmdyoMdzlZ0yDjSPeEHv+os444SsTvrwPwrJWxj39fudakweM3xAk2NgDJc7UrcCZzKH+4yNDmL0NcvQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5074,9 +3902,9 @@ } }, "remark-lint-no-auto-link-without-protocol": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.0.1.tgz", - "integrity": "sha512-FdbB9O4SegELBreglpOXhMyusKORPS0X7KrBY/V+tDo4+2sJHMEEdiN4RbK2ofWwRP7V+muZ5WrscLliuAExQg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-auto-link-without-protocol/-/remark-lint-no-auto-link-without-protocol-3.1.0.tgz", + "integrity": "sha512-GqZXDu/xfajWCEPhS8UjO9dYMTlY5lD8ShoYIaouUgz3nNQvLwX33pTKqfRpd/R9EmV1uQw0PCJ6TYwhBrnOXQ==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -5088,9 +3916,9 @@ } }, "remark-lint-no-blockquote-without-marker": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.0.1.tgz", - "integrity": "sha512-3aUFCV1BSqO15MuJ6fQept36An/vLo9VgAj1TRWk4Gsnaewbq7haT/m6eiYn5Ia8t2sSBbv4LKz1lwnj5nOVPQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-blockquote-without-marker/-/remark-lint-no-blockquote-without-marker-5.1.0.tgz", + "integrity": "sha512-t9ohZSpHIZdlCp+h2nemFD/sM3Am6ZZEczaBpmTQn+OoKrZjpDRrMTb/60OBGXJXHNazfqRwm96unvM4qDs4+Q==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5102,9 +3930,9 @@ } }, "remark-lint-no-consecutive-blank-lines": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.0.1.tgz", - "integrity": "sha512-nvwglXFdR8ubTjSduK3cVdgBaKCH/DqV0kVkCKSQmLEl8NyozFH03VB/bhQDCrmSeNt6rYClBF0ppaHT27OmpA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-consecutive-blank-lines/-/remark-lint-no-consecutive-blank-lines-4.1.0.tgz", + "integrity": "sha512-4gn7lPXAw9hw08apENVNvWjdtuNtgtHPA0mjqgjTszXC92IY1YW8zGfxChCLvCJ1bG4/isI6Ctx+ZmmQoZEW1Q==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -5117,9 +3945,9 @@ } }, "remark-lint-no-duplicate-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.0.1.tgz", - "integrity": "sha512-gwQe65dW2fkMQR02hwlHtc0OOvshst+gXMOEwd1/fpIb6OORpMiK6ueoNBxCnKSsKqftjWV0JXVdZ7MfKKxQQw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-duplicate-definitions/-/remark-lint-no-duplicate-definitions-3.1.0.tgz", + "integrity": "sha512-kBBKK/btn6p0yOiVhB6mnasem7+RUCRjifoe58y/Um56qQsh1GtX6YHVNnboO7fp9aq46MKC2Yc93pEj5yEbDg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5131,9 +3959,9 @@ } }, "remark-lint-no-file-name-articles": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.0.1.tgz", - "integrity": "sha512-9kZ/ydzJlntswJjsQEbPPx0tc6uAPuowmG/3aOCSE+6CjJ+bCQZiVLL3VhjktNyzFxDGTDN6LlbVwiyIHEUMwA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-articles/-/remark-lint-no-file-name-articles-2.1.0.tgz", + "integrity": "sha512-+4gembcykiLnrsTxk4ld2fg3n3TgvHGBO6qMsRmjh5k2m2riwnewM80xfCGXrEVi5cciGIhmv4iU7uicp+WEVQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5141,9 +3969,9 @@ } }, "remark-lint-no-file-name-consecutive-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.0.1.tgz", - "integrity": "sha512-e9ei9KwQSRzUQeYHEhCKUMDeavFOIj46NtuyZxYtrklOcblvaZLAV133UcFHk5CimdUj3dzTtFZebHdpvu5omw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-consecutive-dashes/-/remark-lint-no-file-name-consecutive-dashes-2.1.0.tgz", + "integrity": "sha512-jnQcsYaV8OkUMmFcXr/RWkJFKw30lqEtYTfmb9n/AUsBFeQt53cYYZjA+6AgvKSUW3be7CY2XptReTuM4jSHpQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5151,9 +3979,9 @@ } }, "remark-lint-no-file-name-outer-dashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.0.1.tgz", - "integrity": "sha512-INp+0gW5T2j6+sHglmDmCLL7/goVKCryXyf+ZApB5oWYBpVr2fLnHEHTUmkbQkksxe7me+VsB+WW/KN1PXGrtw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-file-name-outer-dashes/-/remark-lint-no-file-name-outer-dashes-2.1.0.tgz", + "integrity": "sha512-R0eXcFpsfjXI4djN/AF734kydS+p5frZW6NsUzpEfLt5Eu/MhOuii2LvV/G1ujyclZAELpvZlV+sW4083SHi3g==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5161,9 +3989,9 @@ } }, "remark-lint-no-heading-content-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.0.1.tgz", - "integrity": "sha512-IRYlydfT0Xt4AEs5OKSBGP9hLNDckd1mKcV8crnNu91HhcmFVJznzsLV1QrUTTI94cwkSmSWqpjNzsDrKGPbIw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-content-indent/-/remark-lint-no-heading-content-indent-4.1.0.tgz", + "integrity": "sha512-+V92BV7r4Ajc8/oe5DhHeMrn3pZHIoLyqLYM6YgkW2hPMn+eCLVAcrfdOiiVrBpgUNpZMIM9x7UwOq0O4hAr8A==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-heading-style": "^2.0.0", @@ -5176,9 +4004,9 @@ } }, "remark-lint-no-heading-indent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.0.1.tgz", - "integrity": "sha512-LjRsRJOPT1M5MwvGxGEPIHzB713chWgJF5v/FNaHnniLgBrwIbpmsqEhAAam/+i593B5tx84ZyaCf8ujXTP0gg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-heading-indent/-/remark-lint-no-heading-indent-4.1.0.tgz", + "integrity": "sha512-hy9W3YoHWR1AbsOAbhZDwzJAKmdLekmKhc5iC9VfEWVfXsSNHwjAoct4mrBNMEUcfFYhcOTKfyrIXwy1D7fXaw==", "requires": { "@types/mdast": "^3.0.0", "pluralize": "^8.0.0", @@ -5190,9 +4018,9 @@ } }, "remark-lint-no-inline-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.0.1.tgz", - "integrity": "sha512-UcjJ2XTf7kOmQo5mU/5AV+Gth1YYGcp+gYU4gS/CzdOLYstqsS/W+IN6ALJjEbdbtSyfWCElpxI4p/mW16Z90A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-inline-padding/-/remark-lint-no-inline-padding-4.1.0.tgz", + "integrity": "sha512-0dbIgBUhVIkIn8xji2b/j1tG+ETbzE+ZEYNtCRTsNCjFwvyvgzElWKMLHoLzTpXYAN8I5dQhyFcy8Qa/RXg3AA==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -5203,9 +4031,9 @@ } }, "remark-lint-no-literal-urls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.0.1.tgz", - "integrity": "sha512-3OAFcaZawfrFgZGrpuZlNPyuvfIURtUzDN7/Bl2X42ivqx4ih1OH9LtiBgz+J0g1DEWnC5ebOmDr7x6XLM76Fw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-literal-urls/-/remark-lint-no-literal-urls-3.1.0.tgz", + "integrity": "sha512-FvSE16bvwMLh89kZzvyXnWh8MZ2WU+msSqfbF3pU/0YpnpxfRev9ShFRS1k8wVm5BdzSqhwplv4chLnAWg53yw==", "requires": { "@types/mdast": "^3.0.0", "mdast-util-to-string": "^3.0.0", @@ -5217,9 +4045,9 @@ } }, "remark-lint-no-multiple-toplevel-headings": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.0.1.tgz", - "integrity": "sha512-K62PKOOanFiFM4R0oHlo1PKWJa0dPPasQl28yzk6G2xZzqc5eJm5S3d0grU479jqEUbDQMaDQw282hO6WR/MbA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-multiple-toplevel-headings/-/remark-lint-no-multiple-toplevel-headings-3.1.0.tgz", + "integrity": "sha512-F4z867UaYjWdWFzR4ZpPi+EIzoUcU/QtdEVftdVKNdBEy1pq2A/vdTUa/PGtc+LLeQn04mJ/SGPC2s7eMWAZfg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5231,9 +4059,9 @@ } }, "remark-lint-no-shell-dollars": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.0.1.tgz", - "integrity": "sha512-QvnA8Ltj3FPaAqUu0DebKYv66LFndTk0fXVZ9rQWOjTEVIKImy9Dy59kVqwYMpCwZbJkpigu2bMl/7UG/BA0XA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shell-dollars/-/remark-lint-no-shell-dollars-3.1.0.tgz", + "integrity": "sha512-f4+NPey3yzd9TpDka5Bs3W+MMJBPz6bQ7zK3M9Qc133lqZ81hKMGVRrOBafS1RNqD5htLZbbGyCoJa476QtW1w==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5243,9 +4071,9 @@ } }, "remark-lint-no-shortcut-reference-image": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.0.1.tgz", - "integrity": "sha512-0o0YO88Atib0eWloy5ZbL2IZ1axMNysbJI5j58sxMjEwLq1JORtGOR9Z6aHsOccS5yseeenw5w3DoMLB9PtJtw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-image/-/remark-lint-no-shortcut-reference-image-3.1.0.tgz", + "integrity": "sha512-uTXysJw749c42QnFt+DfG5NJTjfcQdM5gYGLugb/vgUwN8dzPu6DiGM3ih1Erwha6qEseV00FpFvDexHbQvJNw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5255,9 +4083,9 @@ } }, "remark-lint-no-shortcut-reference-link": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.0.1.tgz", - "integrity": "sha512-uXujnVm5LXLtGyJkTIbn/uxDRu507B9vC8TieiX6HX8OjVeDWUjtcVJOaqeyLJGjV0Ri1Y+AegMNWx5eDBHTDQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-shortcut-reference-link/-/remark-lint-no-shortcut-reference-link-3.1.0.tgz", + "integrity": "sha512-SmM/sICFnlMx4PcuXIMJmyqTyI1+FQMOGh51GmLDWoyjbblP2hXD4UqrYLhAeV0aPQSNKwMXNNW0aysjdoWL0A==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5267,9 +4095,9 @@ } }, "remark-lint-no-table-indentation": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.0.1.tgz", - "integrity": "sha512-GYBX5P1Vj0gO7S7JLU2tpYR5rg9xbeccPQ0ZgHYK4d7T9FjDwfE1hrdvlha3k8s3CFKqQ7MC0OgQw/2IN413MA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-table-indentation/-/remark-lint-no-table-indentation-4.1.0.tgz", + "integrity": "sha512-OJg95FHBZKyEUlnmHyMQ2j9qs5dnxk3oX1TQuREpFDgzQMh/Bcyc+CegmsDMDiyNyrs1QgDwubCWmAYWgdy4Gw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5280,9 +4108,9 @@ } }, "remark-lint-no-tabs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.0.1.tgz", - "integrity": "sha512-B2q1I+fyRDvWTQxCC91NoEvz0KzI9e6Yhu1TdOLkwc02hMWj869G165Rh+EcBKGW/CLKuMPhIn2XtL86emqZRw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-tabs/-/remark-lint-no-tabs-3.1.0.tgz", + "integrity": "sha512-QjMDKdwoKtZyvqHvRQS6Wwy/sy2KwLGbjGJumGXhzYS6fU7r/EimYcCbNb0NgxJhs3sLhWKZB9m/W0hH6LYbnA==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5309,9 +4137,9 @@ } }, "remark-lint-no-undefined-references": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.0.1.tgz", - "integrity": "sha512-mmNJO30TYMxwfFJPHkwKNRaW63sU9ffhpb4xkyhyHDmnsplQ96RVYR4WGOXw0/wR+gZECmFtBU+OIWz0cbaiEw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-undefined-references/-/remark-lint-no-undefined-references-4.1.0.tgz", + "integrity": "sha512-xnBd6ZLWv9Lnf1dH6bC/IYywbzxloUNJwiJY2OzhtZUMsqH8Xw5ZAidhxIW3k+3K8Fs2WSwp7HjIzjp7ZSiuDA==", "requires": { "@types/mdast": "^3.0.0", "micromark-util-normalize-identifier": "^1.0.0", @@ -5324,9 +4152,9 @@ } }, "remark-lint-no-unused-definitions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.0.1.tgz", - "integrity": "sha512-bcbboInyb8vAPtYakZdaxRQsDIdQnV5WvUdc03PWFlG8YtGOhRQ57SPc+4uVH+VwHoq+lsEsRszr4sOXuuopxw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-no-unused-definitions/-/remark-lint-no-unused-definitions-3.1.0.tgz", + "integrity": "sha512-poSmPeY5wZYLXhiUV+rbrkWNNENjoUq2lUb/Ho34zorMeV70FNBEV+zv1A6Ri8+jplUDeLi1lqC0uBTlTAUuLQ==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5336,9 +4164,9 @@ } }, "remark-lint-ordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-CGXvolLwfZIxG9hm4o7OXQXEEpu3r5oyTpYGteJDtOSrpVrBSqFKNq7lfhKYFQkcg2AMJYrH9XEexrYvAoUQOQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-ordered-list-marker-style/-/remark-lint-ordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-/sYOjCK+FkAhwheIHjL65TxQKJ8infTVsDi5Dbl6XHaXiAzKjvZhwW4uJqgduufozlriI63DF68YMv5y6tyXsw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5361,9 +4189,9 @@ } }, "remark-lint-rule-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.0.1.tgz", - "integrity": "sha512-j1e60nfZJk0C6mvDZkiFwVu0b58f219ATlMNaZ9h8QdQhdxD/0kUnizJ7xW3wS4sHtCgkKGctAp04Ma0c+Dkhg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-rule-style/-/remark-lint-rule-style-3.1.0.tgz", + "integrity": "sha512-Z2tW9kBNCdD8l+kG7bTKanfciqGGJt8HnBmV9eE3oIqVDzqWJoIQ8kVBDGh6efeOAlWDDDHGIp/jb4i/CJ/kvg==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5373,9 +4201,9 @@ } }, "remark-lint-strong-marker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.0.1.tgz", - "integrity": "sha512-J5dJviBd747vXBkFuA2j/Ni7RjTg+Mg2GgXlPHtbgDnal51CdN2WXDmbVG/A98+3P18MlysvQ7KnBrSiiuGBpQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-strong-marker/-/remark-lint-strong-marker-3.1.0.tgz", + "integrity": "sha512-YkGZ2J1vayVa/uSWUOuqKzB3ot1RgtsAd/Kz7L2ve8lDDIjnxn+bUufaS6cN9K5/ADprryd1hdE29YRVj6Vs3g==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5385,9 +4213,9 @@ } }, "remark-lint-table-cell-padding": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.0.1.tgz", - "integrity": "sha512-NdF0WHFOaMjeumRIrGHXVadwWkgnfJuMb96FGbf1HvSEv9l41PHkS1KTsL6Zoe1Cva57niAuarMv6xzcJqVjrA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-cell-padding/-/remark-lint-table-cell-padding-4.1.0.tgz", + "integrity": "sha512-2FqYGR6IsO5HdmvBe15iwD8XI9xjyMBegKuJWK50bWAsIVdR1b80nfXxKDQ6lRDK6LZ7+iATxzTo0Fl3+TLmgw==", "requires": { "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", @@ -5398,9 +4226,9 @@ } }, "remark-lint-table-pipes": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.0.1.tgz", - "integrity": "sha512-om6i8SMSjMsR/mYlx5cMSoxXK+EFI8/n73qCVx/RAhFCIsW4TFR+gYmgFTyLr5Mp4vqjV3uYBIR9Ucv6Johauw==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-table-pipes/-/remark-lint-table-pipes-4.1.0.tgz", + "integrity": "sha512-kI50VXlEW9zUdMh8Y9T7vornqpnMr+Ywy+sUzEuhhmWeFIYcIsBbZTHA1253FgjA/iMkLPzByYWj1xGlUGL1jw==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5410,9 +4238,9 @@ } }, "remark-lint-unordered-list-marker-style": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.0.1.tgz", - "integrity": "sha512-DPveL2hhkcY608Bkn/Hx+C7pxviufpYyRiu0CnfFxkbLBlMgVdvVIOGCCOlhbvKuGtozmH/RCRsdIfzjlkXiew==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-lint-unordered-list-marker-style/-/remark-lint-unordered-list-marker-style-3.1.0.tgz", + "integrity": "sha512-oUThfe8/34DpXkGjOghOkSOqk8tGthnDNIMBtNVY+aMIkkuvCSxqFj9D/R37Al7/tqqgZ1D6ezpwxIOsa15JTA==", "requires": { "@types/mdast": "^3.0.0", "unified": "^10.0.0", @@ -5446,9 +4274,9 @@ } }, "remark-preset-lint-node": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.0.1.tgz", - "integrity": "sha512-L7yhho9q9vmpsfMHO2gRKFNj36106iFM4KpodE+3k3rGg5dcmhV+zcsftNh5NGzbKKKYsGQj9C5XxCR/0NwKDg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-node/-/remark-preset-lint-node-3.1.0.tgz", + "integrity": "sha512-jWEl5ljKYmIiM2cnZbp7dIYmpFND33RWOCcm5cbp8m2GbOLMOaAW2cVBZe47XLAzpQcOIKaT2BjSsi7Y1h/cig==", "requires": { "js-yaml": "^4.0.0", "remark-lint-blockquote-indentation": "^3.0.0", @@ -5487,9 +4315,9 @@ } }, "remark-preset-lint-recommended": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.0.1.tgz", - "integrity": "sha512-8ZlwP2aDCGf+3UFPP1K8CofWI/WLoq8hPhQiuKotCFNSdTe98/27XYqWXpbMt4feWtX4+tcJY1y0duuLK5lhBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/remark-preset-lint-recommended/-/remark-preset-lint-recommended-6.1.0.tgz", + "integrity": "sha512-1jUbuzRAP5idWu9GZ5x7M96Z1TcTWwJu0C8ziz5RLezWL9rChhw9kV6s0beR0lrY5Kl5E5pjA6SKaP7NyGi2ug==", "requires": { "@types/mdast": "^3.0.0", "remark-lint": "^9.0.0", @@ -5532,19 +4360,14 @@ } }, "rollup": { - "version": "2.56.3", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.56.3.tgz", - "integrity": "sha512-Au92NuznFklgQCUcV96iXlxUbHuB1vQMaH76DHl5M11TotjOHwqk9CwcrT78+Tnv4FN9uTBxq6p4EJoYkpyekg==", + "version": "2.57.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.57.0.tgz", + "integrity": "sha512-bKQIh1rWKofRee6mv8SrF2HdP6pea5QkwBZSMImJysFj39gQuiV8MEPBjXOCpzk3wSYp63M2v2wkWBmFC8O/rg==", "dev": true, "requires": { "fsevents": "~2.3.2" } }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -5553,27 +4376,6 @@ "lru-cache": "^6.0.0" } }, - "shelljs": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", - "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dev": true, - "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - } - }, - "shx": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.3.tgz", - "integrity": "sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==", - "dev": true, - "requires": { - "minimist": "^1.2.3", - "shelljs": "^0.8.4" - } - }, "sliced": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz", @@ -5590,22 +4392,14 @@ "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz", "integrity": "sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw==" }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, "string-width": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.0.tgz", - "integrity": "sha512-zwXcRmLUdiWhMPrHz6EXITuyTgcEnUqDzspTkCLhQovxywWz6NP9VHgqfVg20V/1mUg0B95AKbXxNT+ALRmqCw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.0.1.tgz", + "integrity": "sha512-5ohWO/M4//8lErlUUtrFy3b11GtNOuMOU0ysKCDXFcfXuuvUXu95akgj/i8ofmaGdN0hCqyl6uu9i8dS/mQp5g==", "requires": { "emoji-regex": "^9.2.2", "is-fullwidth-code-point": "^4.0.0", - "strip-ansi": "^7.0.0" + "strip-ansi": "^7.0.1" } }, "stringify-entities": { @@ -5618,32 +4412,19 @@ } }, "strip-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.0.tgz", - "integrity": "sha512-UhDTSnGF1dc0DRbUqr1aXwNoY3RgVkSWG8BrpnuFIxhP57IqbS7IRta2Gfiavds4yCxc5+fEAVVOgBZWnYkvzg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", "requires": { - "ansi-regex": "^6.0.0" + "ansi-regex": "^6.0.1" } }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", + "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", "requires": { - "is-number": "^7.0.0" + "has-flag": "^5.0.0" } }, "to-vfile": { @@ -5660,11 +4441,6 @@ "resolved": "https://registry.npmjs.org/trough/-/trough-2.0.2.tgz", "integrity": "sha512-FnHq5sTMxC0sk957wHDzRnemFnNBvt/gSY99HzK8F7UP5WAbvP70yX5bd7CjEQkN+TjdxwI7g7lJ6podqrG2/w==" }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" - }, "unified": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.0.tgz", @@ -5679,56 +4455,10 @@ "vfile": "^5.0.0" } }, - "unified-args": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/unified-args/-/unified-args-9.0.2.tgz", - "integrity": "sha512-qSqryjoqfJSII4E4Z2Jx7MhXX2MuUIn6DsrlmL8UnWFdGtrWvEtvm7Rx5fKT5TPUz7q/Fb4oxwIHLCttvAuRLQ==", - "requires": { - "@types/text-table": "^0.2.0", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "chokidar": "^3.0.0", - "fault": "^2.0.0", - "json5": "^2.0.0", - "minimist": "^1.0.0", - "text-table": "^0.2.0", - "unified-engine": "^9.0.0" - } - }, - "unified-engine": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-9.0.4.tgz", - "integrity": "sha512-NFI+jC3DWZ23eBsWkOW2havz47DPG/DSyJEvBH+qA5cQHF6zlgiJYev7ksb/naOypZZ+cfhaCxCRo2BqrysYEw==", - "requires": { - "@types/concat-stream": "^1.0.0", - "@types/debug": "^4.0.0", - "@types/is-empty": "^1.0.0", - "@types/js-yaml": "^4.0.0", - "@types/node": "^16.0.0", - "@types/unist": "^2.0.0", - "concat-stream": "^2.0.0", - "debug": "^4.0.0", - "fault": "^2.0.0", - "glob": "^7.0.0", - "ignore": "^5.0.0", - "is-buffer": "^2.0.0", - "is-empty": "^1.0.0", - "is-plain-obj": "^4.0.0", - "js-yaml": "^4.0.0", - "load-plugin": "^4.0.0", - "parse-json": "^5.0.0", - "to-vfile": "^7.0.0", - "trough": "^2.0.0", - "unist-util-inspect": "^7.0.0", - "vfile-message": "^3.0.0", - "vfile-reporter": "^7.0.0", - "vfile-statistics": "^2.0.0" - } - }, "unified-lint-rule": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.0.1.tgz", - "integrity": "sha512-2RzZuuuWW+ifftM0zd/ZEng0Hb5lah+Zi+ZL/ybj8BrLO/TH2aQAMYvG+iC95aCg2FkWu/pcvVvHqsh2UMmzPg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unified-lint-rule/-/unified-lint-rule-2.1.0.tgz", + "integrity": "sha512-pB2Uht3w+A9ceWXMYI0YWwxCTqC5on6jrApWDWSsYDBjaljSv8s64qdHHMCXFIUAGdd6V/XWrVMxiboHOAXo3Q==", "requires": { "@types/unist": "^2.0.0", "trough": "^2.0.0", @@ -5766,14 +4496,6 @@ "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.0.tgz", "integrity": "sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==" }, - "unist-util-inspect": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-7.0.0.tgz", - "integrity": "sha512-2Utgv78I7PUu461Y9cdo+IUiiKSKpDV5CE/XD6vTj849a3xlpDAScvSJ6cQmtFBGgAmCn2wR7jLuXhpg1XLlJw==", - "requires": { - "@types/unist": "^2.0.0" - } - }, "unist-util-is": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.1.1.tgz", @@ -5803,9 +4525,9 @@ }, "dependencies": { "unist-util-visit-parents": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.0.0.tgz", - "integrity": "sha512-CVaLOYPM/EaFTYMytbaju3Tw4QI3DHnHFnL358FkEu0hZOzSm/hqBdVwOQDR60jF5ZzhB1tlZlRH0ll/yekZIQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.0.tgz", + "integrity": "sha512-y+QVLcY5eR/YVpqDsLf/xh9R3Q2Y4HxkZTp7ViLDU6WtJCEcPmRzW1gpdWDCDIqIlhuPDXOgttqPlykrHYDekg==", "requires": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" @@ -5822,11 +4544,6 @@ "unist-util-is": "^5.0.0" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, "vfile": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.1.0.tgz", @@ -5867,21 +4584,6 @@ "unist-util-stringify-position": "^3.0.0", "vfile-sort": "^3.0.0", "vfile-statistics": "^2.0.0" - }, - "dependencies": { - "has-flag": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", - "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==" - }, - "supports-color": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.0.2.tgz", - "integrity": "sha512-ii6tc8ImGFrgMPYq7RVAMKkhPo9vk8uA+D3oKbJq/3Pk2YSMv1+9dUAesa9UxMbxBTvxwKTQffBahNVNxEvM8Q==", - "requires": { - "has-flag": "^5.0.0" - } - } } }, "vfile-sort": { @@ -5917,7 +4619,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "yallist": { "version": "4.0.0", diff --git a/tools/lint-md/package.json b/tools/lint-md/package.json new file mode 100644 index 00000000000000..31b740744d186e --- /dev/null +++ b/tools/lint-md/package.json @@ -0,0 +1,22 @@ +{ + "name": "lint-md", + "description": "markdown linting", + "version": "1.0.0", + "scripts": { + "build": "rollup -f es -p '@rollup/plugin-node-resolve={exportConditions: [\"node\"]}' -p @rollup/plugin-commonjs lint-md.src.mjs --file lint-md.mjs" + }, + "dependencies": { + "remark-gfm": "^2.0.0", + "remark-parse": "^10.0.0", + "remark-preset-lint-node": "^3.0.1", + "remark-stringify": "^10.0.0", + "to-vfile": "^7.2.2", + "unified": "^10.1.0", + "vfile-reporter": "^7.0.2" + }, + "devDependencies": { + "@rollup/plugin-commonjs": "^20.0.0", + "@rollup/plugin-node-resolve": "^13.0.5", + "rollup": "^2.57.0" + } +} diff --git a/tools/node-lint-md-cli-rollup/.gitignore b/tools/node-lint-md-cli-rollup/.gitignore deleted file mode 100644 index ab9ffa17b3a6dd..00000000000000 --- a/tools/node-lint-md-cli-rollup/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/node_modules/ -/remark-preset-lint-node/node_modules/ -/dist/ diff --git a/tools/node-lint-md-cli-rollup/LICENSE b/tools/node-lint-md-cli-rollup/LICENSE deleted file mode 100644 index 3ffee7a3be6993..00000000000000 --- a/tools/node-lint-md-cli-rollup/LICENSE +++ /dev/null @@ -1,32 +0,0 @@ -Copyright (c) 2018 Refael Ackermann - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ---- - -(The MIT License for `remark` https://github.com/remarkjs/remark/blob/master/LICENSE) - -Copyright (c) 2014-2016 Titus Wormer -Copyright (c) 2011-2014, Christopher Jeffrey (https://github.com/chjj/) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/tools/node-lint-md-cli-rollup/package.json b/tools/node-lint-md-cli-rollup/package.json deleted file mode 100644 index 0b4e23ab09eed6..00000000000000 --- a/tools/node-lint-md-cli-rollup/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "node-lint-md-cli-rollup", - "description": "remark packaged for Node.js Markdown linting", - "version": "2.0.2", - "devDependencies": { - "@rollup/plugin-commonjs": "^20.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.4", - "rollup": "^2.56.3", - "shx": "^0.3.3" - }, - "dependencies": { - "markdown-extensions": "^1.1.1", - "remark": "^14.0.1", - "remark-gfm": "^2.0.0", - "remark-preset-lint-node": "^3.0.1", - "unified-args": "^9.0.2" - }, - "main": "dist/index.js", - "scripts": { - "build": "npx rollup -c", - "build-node": "npm run build && npx shx cp dist/index.mjs ../lint-md.mjs" - } -} diff --git a/tools/node-lint-md-cli-rollup/rollup.config.js b/tools/node-lint-md-cli-rollup/rollup.config.js deleted file mode 100644 index 0a2b2098e69dd6..00000000000000 --- a/tools/node-lint-md-cli-rollup/rollup.config.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict'; - -const { nodeResolve } = require('@rollup/plugin-node-resolve'); -const commonjs = require('@rollup/plugin-commonjs'); -const json = require('@rollup/plugin-json'); - -module.exports = { - input: 'src/cli-entry.mjs', - output: { - file: 'dist/index.mjs', - format: 'es', - sourcemap: false, - exports: 'none', - }, - external: [ - 'node:events', - 'node:fs', - 'node:path', - 'node:process', - 'node:stream', - 'node:url', - ], - plugins: [ - { - name: 'brute-replace', - transform(code, id) { - const normID = id.replace(__dirname, '').replace(/\\+/g, '/'); - if (normID === '/node_modules/concat-stream/index.js') { - return code.replace('\'readable-stream\'', '\'stream\''); - } - if (normID === '/node_modules/unified-args/lib/options.js') { - return code.replace('\'./schema\'', '\'./schema.json\''); - } - if (normID === '/node_modules/chokidar/lib/fsevents-handler.js') { - return code.replace( - 'fsevents = require(\'fsevents\');', 'fsevents = undefined;' - ); - } - // Remove circular dependency in glob that messes up rollup - return code.replace("var Glob = require('./glob.js').Glob", ''); - } - }, - json({ - preferConst: true - }), - nodeResolve({ exportConditions: ['node'] }), - commonjs(), - { - name: 'banner', - renderChunk(code) { - const banner = '// Don\'t change this file manually,\n' + - '// it is generated from tools/node-lint-md-cli-rollup'; - return code.replace('\'use strict\';', '\'use strict\';\n\n' + banner); - } - }, - ] -}; diff --git a/tools/node-lint-md-cli-rollup/src/cli-entry.mjs b/tools/node-lint-md-cli-rollup/src/cli-entry.mjs deleted file mode 100644 index 71e2563926b26c..00000000000000 --- a/tools/node-lint-md-cli-rollup/src/cli-entry.mjs +++ /dev/null @@ -1,27 +0,0 @@ -// To aid in future maintenance, this layout closely matches remark-cli/cli.js. -// https://github.com/remarkjs/remark/blob/HEAD/packages/remark-cli/cli.js - -import { args } from 'unified-args'; -import extensions from 'markdown-extensions'; -import { remark } from 'remark'; -import proc from 'remark/package.json'; -import cli from '../package.json'; -import lintNode from 'remark-preset-lint-node'; -import gfm from 'remark-gfm'; - -args({ - processor: remark().use(gfm).use(lintNode), - name: proc.name, - description: cli.description, - version: [ - proc.name + ': ' + proc.version, - cli.name + ': ' + cli.version, - ].join(', '), - pluginPrefix: proc.name, - presetPrefix: proc.name + '-preset', - packageField: proc.name + 'Config', - rcName: '.' + proc.name + 'rc', - ignoreName: '.' + proc.name + 'ignore', - extensions: extensions, - detectConfig: false, -}); diff --git a/tsconfig.json b/tsconfig.json index df191a36f7cb13..d1d6469f494f97 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,9 +4,11 @@ "files": [ "./typings/internalBinding/fs.d.ts", "./typings/internalBinding/http_parser.d.ts", + "./typings/internalBinding/messaging.d.ts", "./typings/internalBinding/options.d.ts", "./typings/internalBinding/serdes.d.ts", "./typings/internalBinding/util.d.ts", + "./typings/internalBinding/worker.d.ts", "./typings/internalBinding.d.ts", "./typings/primordials.d.ts" ], diff --git a/typings/internalBinding.d.ts b/typings/internalBinding.d.ts index 598322d581ceac..ffb6423e3e5d87 100644 --- a/typings/internalBinding.d.ts +++ b/typings/internalBinding.d.ts @@ -439,3 +439,6 @@ declare function InternalBinding(binding: 'config'): { bits: number, hasDtrace: boolean } +declare function InternalBinding(binding: 'symbols'): { + [name: string]: symbol; +} diff --git a/typings/internalBinding/messaging.d.ts b/typings/internalBinding/messaging.d.ts new file mode 100644 index 00000000000000..ca5be84848408d --- /dev/null +++ b/typings/internalBinding/messaging.d.ts @@ -0,0 +1,32 @@ +declare namespace InternalMessagingBinding { + class MessageChannel { + port1: MessagePort; + port2: MessagePort; + } + + class MessagePort { + private constructor(); + postMessage(message: any, transfer?: any[] | null): void; + start(): void; + close(): void; + ref(): void; + unref(): void; + } + + class JSTransferable {} +} + + +declare function InternalBinding(binding: 'messaging'): { + DOMException: typeof import('internal/per_context/domexception').DOMException; + MessageChannel: typeof InternalMessagingBinding.MessageChannel; + MessagePort: typeof InternalMessagingBinding.MessagePort; + JSTransferable: typeof InternalMessagingBinding.JSTransferable; + stopMessagePort(port: typeof InternalMessagingBinding.MessagePort): void; + checkMessagePort(port: unknown): boolean; + drainMessagePort(port: typeof InternalMessagingBinding.MessagePort): void; + receiveMessageOnPort(port: typeof InternalMessagingBinding.MessagePort): any; + moveMessagePortToContext(port: typeof InternalMessagingBinding.MessagePort, context: any): typeof InternalMessagingBinding.MessagePort; + setDeserializerCreateObjectFunction(func: (deserializeInfo: string) => any): void; + broadcastChannel(name: string): typeof InternalMessagingBinding.MessagePort; +}; diff --git a/typings/internalBinding/worker.d.ts b/typings/internalBinding/worker.d.ts new file mode 100644 index 00000000000000..2fc7f9272d9f64 --- /dev/null +++ b/typings/internalBinding/worker.d.ts @@ -0,0 +1,32 @@ +declare namespace InternalWorkerBinding { + class Worker { + constructor( + url: string | URL | null, + env: object | null | undefined, + execArgv: string[] | null | undefined, + resourceLimits: Float64Array, + trackUnmanagedFds: boolean); + startThread(): void; + stopThread(): void; + ref(): void; + unref(): void; + getResourceLimits(): Float64Array; + takeHeapSnapshot(): object; + loopIdleTime(): number; + loopStartTime(): number; + } +} + +declare function InternalBinding(binding: 'worker'): { + Worker: typeof InternalWorkerBinding.Worker; + getEnvMessagePort(): InternalMessagingBinding.MessagePort; + threadId: number; + isMainThread: boolean; + ownsProcessState: boolean; + resourceLimits?: Float64Array; + kMaxYoungGenerationSizeMb: number; + kMaxOldGenerationSizeMb: number; + kCodeRangeSizeMb: number; + kStackSizeMb: number; + kTotalResourceLimitCount: number; +}; diff --git a/vcbuild.bat b/vcbuild.bat index a91ee9b64c20f0..604843027cb1e5 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -722,7 +722,21 @@ for /D %%D IN (doc\*) do ( set "lint_md_files="%%F" !lint_md_files!" ) ) -%node_exe% tools\lint-md.mjs -q -f %lint_md_files% +%node_exe% tools\lint-md\lint-md.mjs %lint_md_files% +ENDLOCAL +goto exit + +:format-md +if not defined lint_md goto exit +echo Running Markdown formatter on docs... +SETLOCAL ENABLEDELAYEDEXPANSION +set lint_md_files= +for /D %%D IN (doc\*) do ( + for %%F IN (%%D\*.md) do ( + set "lint_md_files="%%F" !lint_md_files!" + ) +) +%node_exe% tools\lint-md\lint-md.mjs --format %lint_md_files% ENDLOCAL goto exit
+14.18.0
14.17.6
14.17.5
14.17.4
@@ -67,6 +66,497 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + +## 2021-09-28, Version 14.18.0 'Fermium' (LTS), @targos + +### Notable Changes + +* [[`3a60de0135`](https://github.com/nodejs/node/commit/3a60de0135)] - **assert**: change status of legacy asserts (James M Snell) [#38113](https://github.com/nodejs/node/pull/38113) +* [[`df37c106a7`](https://github.com/nodejs/node/commit/df37c106a7)] - **(SEMVER-MINOR)** **buffer**: introduce Blob (James M Snell) [#36811](https://github.com/nodejs/node/pull/36811) +* [[`223494c548`](https://github.com/nodejs/node/commit/223494c548)] - **(SEMVER-MINOR)** **buffer**: add base64url encoding option (Filip Skokan) [#36952](https://github.com/nodejs/node/pull/36952) +* [[`14fc4ddabc`](https://github.com/nodejs/node/commit/14fc4ddabc)] - **(SEMVER-MINOR)** **child_process**: allow `options.cwd` receive a URL (Khaidi Chu) [#38862](https://github.com/nodejs/node/pull/38862) +* [[`b68b13acb3`](https://github.com/nodejs/node/commit/b68b13acb3)] - **(SEMVER-MINOR)** **child_process**: add timeout to spawn and fork (Nitzan Uziely) [#37256](https://github.com/nodejs/node/pull/37256) +* [[`da98c9f99b`](https://github.com/nodejs/node/commit/da98c9f99b)] - **(SEMVER-MINOR)** **child_process**: allow promisified exec to be cancel (Carlos Fuentes) [#34249](https://github.com/nodejs/node/pull/34249) +* [[`779310ac87`](https://github.com/nodejs/node/commit/779310ac87)] - **(SEMVER-MINOR)** **child_process**: add 'overlapped' stdio flag (Thiago Padilha) [#29412](https://github.com/nodejs/node/pull/29412) +* [[`40eb3b79f1`](https://github.com/nodejs/node/commit/40eb3b79f1)] - **(SEMVER-MINOR)** **cli**: add -C alias for --conditions flag (Guy Bedford) [#38755](https://github.com/nodejs/node/pull/38755) +* [[`39eba0a2e1`](https://github.com/nodejs/node/commit/39eba0a2e1)] - **(SEMVER-MINOR)** **cli**: add --node-memory-debug option (Anna Henningsen) [#35537](https://github.com/nodejs/node/pull/35537) +* [[`d8d9a9628a`](https://github.com/nodejs/node/commit/d8d9a9628a)] - **(SEMVER-MINOR)** **dns**: add "tries" option to Resolve options (Luan Devecchi) [#39610](https://github.com/nodejs/node/pull/39610) +* [[`15ba19b020`](https://github.com/nodejs/node/commit/15ba19b020)] - **(SEMVER-MINOR)** **dns**: allow `--dns-result-order` to change default dns verbatim (Ouyang Yadong) [#38099](https://github.com/nodejs/node/pull/38099) +* [[`307c1d817f`](https://github.com/nodejs/node/commit/307c1d817f)] - **doc**: refactor fs docs structure (James M Snell) [#37170](https://github.com/nodejs/node/pull/37170) +* [[`9ee3f77e32`](https://github.com/nodejs/node/commit/9ee3f77e32)] - **(SEMVER-MINOR)** **errors**: remove experimental from --enable-source-maps (Benjamin Coe) [#37362](https://github.com/nodejs/node/pull/37362) +* [[`e73bfed2f4`](https://github.com/nodejs/node/commit/e73bfed2f4)] - **esm**: deprecate legacy main lookup for modules (Guy Bedford) [#36918](https://github.com/nodejs/node/pull/36918) +* [[`989c204a58`](https://github.com/nodejs/node/commit/989c204a58)] - **(SEMVER-MINOR)** **fs**: allow empty string for temp directory prefix (Voltrex) [#39028](https://github.com/nodejs/node/pull/39028) +* [[`ef72490cde`](https://github.com/nodejs/node/commit/ef72490cde)] - **(SEMVER-MINOR)** **fs**: allow no-params fsPromises fileHandle read (Nitzan Uziely) [#38287](https://github.com/nodejs/node/pull/38287) +* [[`cad9d20f64`](https://github.com/nodejs/node/commit/cad9d20f64)] - **(SEMVER-MINOR)** **fs**: add support for async iterators to `fsPromises.writeFile` (HiroyukiYagihashi) [#37490](https://github.com/nodejs/node/pull/37490) +* [[`2b0e2706c0`](https://github.com/nodejs/node/commit/2b0e2706c0)] - **fs**: improve fsPromises readFile performance (Nitzan Uziely) [#37608](https://github.com/nodejs/node/pull/37608) +* [[`fe12cc07b3`](https://github.com/nodejs/node/commit/fe12cc07b3)] - **(SEMVER-MINOR)** **fs**: add fsPromises.watch() (James M Snell) [#37179](https://github.com/nodejs/node/pull/37179) +* [[`2459c115a8`](https://github.com/nodejs/node/commit/2459c115a8)] - **(SEMVER-MINOR)** **fs**: allow `position` parameter to be a `BigInt` in read and readSync (Darshan Sen) [#36190](https://github.com/nodejs/node/pull/36190) +* [[`6544cfb4b9`](https://github.com/nodejs/node/commit/6544cfb4b9)] - **(SEMVER-MINOR)** **http2**: add support for sensitive headers (Anna Henningsen) [#34145](https://github.com/nodejs/node/pull/34145) +* [[`a6c6cbb4e6`](https://github.com/nodejs/node/commit/a6c6cbb4e6)] - **(SEMVER-MINOR)** **http2**: allow setting the local window size of a session (Yongsheng Zhang) [#35978](https://github.com/nodejs/node/pull/35978) +* [[`1e5aca550c`](https://github.com/nodejs/node/commit/1e5aca550c)] - **inspector**: mark as stable (Gireesh Punathil) [#37748](https://github.com/nodejs/node/pull/37748) +* [[`93af04afbb`](https://github.com/nodejs/node/commit/93af04afbb)] - **(SEMVER-MINOR)** **module**: add support for `URL` to `import.meta.resolve` (Antoine du Hamel) [#38587](https://github.com/nodejs/node/pull/38587) +* [[`f9f9389d83`](https://github.com/nodejs/node/commit/f9f9389d83)] - **(SEMVER-MINOR)** **module**: add support for `node:`‑prefixed `require(…)` calls (ExE Boss) [#37246](https://github.com/nodejs/node/pull/37246) +* [[`87c71065eb`](https://github.com/nodejs/node/commit/87c71065eb)] - **(SEMVER-MINOR)** **net**: introduce net.BlockList (James M Snell) [#34625](https://github.com/nodejs/node/pull/34625) +* [[`b421d99a48`](https://github.com/nodejs/node/commit/b421d99a48)] - **(SEMVER-MINOR)** **node-api**: allow retrieval of add-on file name (Gabriel Schulhof) [#37195](https://github.com/nodejs/node/pull/37195) +* [[`6a4811df8a`](https://github.com/nodejs/node/commit/6a4811df8a)] - **(SEMVER-MINOR)** **os**: add os.devNull (Luigi Pinca) [#38569](https://github.com/nodejs/node/pull/38569) +* [[`4a88ddeeca`](https://github.com/nodejs/node/commit/4a88ddeeca)] - **(SEMVER-MINOR)** **perf_hooks**: introduce createHistogram (James M Snell) [#37155](https://github.com/nodejs/node/pull/37155) +* [[`1a6bf1c4a3`](https://github.com/nodejs/node/commit/1a6bf1c4a3)] - **(SEMVER-MINOR)** **process**: add api to enable source-maps programmatically (legendecas) [#39085](https://github.com/nodejs/node/pull/39085) +* [[`99735a6fe8`](https://github.com/nodejs/node/commit/99735a6fe8)] - **(SEMVER-MINOR)** **process**: add `'worker'` event (James M Snell) [#38659](https://github.com/nodejs/node/pull/38659) +* [[`3982919317`](https://github.com/nodejs/node/commit/3982919317)] - **(SEMVER-MINOR)** **process**: add direct access to rss without iterating pages (Adrien Maret) [#34291](https://github.com/nodejs/node/pull/34291) +* [[`526e6c7bde`](https://github.com/nodejs/node/commit/526e6c7bde)] - **(SEMVER-MINOR)** **readline**: add AbortSignal support to interface (Nitzan Uziely) [#37932](https://github.com/nodejs/node/pull/37932) +* [[`e6eee08692`](https://github.com/nodejs/node/commit/e6eee08692)] - **(SEMVER-MINOR)** **readline**: add support for the AbortController to the question method (Mattias Runge-Broberg) [#33676](https://github.com/nodejs/node/pull/33676) +* [[`32de361d70`](https://github.com/nodejs/node/commit/32de361d70)] - **(SEMVER-MINOR)** **readline**: add history event and option to set initial history (Mattias Runge-Broberg) [#33662](https://github.com/nodejs/node/pull/33662) +* [[`797f7f8a38`](https://github.com/nodejs/node/commit/797f7f8a38)] - **(SEMVER-MINOR)** **repl**: add auto‑completion for `node:`‑prefixed `require(…)` calls (ExE Boss) [#37246](https://github.com/nodejs/node/pull/37246) +* [[`abfd71b64c`](https://github.com/nodejs/node/commit/abfd71b64c)] - **(SEMVER-MINOR)** **src**: call overload ctor from the original ctor (Darshan Sen) [#39768](https://github.com/nodejs/node/pull/39768) +* [[`1efae01b18`](https://github.com/nodejs/node/commit/1efae01b18)] - **(SEMVER-MINOR)** **src**: add a constructor overload for CallbackScope (Darshan Sen) [#39768](https://github.com/nodejs/node/pull/39768) +* [[`f7933804ba`](https://github.com/nodejs/node/commit/f7933804ba)] - **(SEMVER-MINOR)** **src**: allow to negate boolean CLI flags (Michaël Zasso) [#39023](https://github.com/nodejs/node/pull/39023) +* [[`6d06ac2202`](https://github.com/nodejs/node/commit/6d06ac2202)] - **(SEMVER-MINOR)** **src**: add --heapsnapshot-near-heap-limit option (Joyee Cheung) [#33010](https://github.com/nodejs/node/pull/33010) +* [[`577d228ca0`](https://github.com/nodejs/node/commit/577d228ca0)] - **(SEMVER-MINOR)** **src**: add way to get IsolateData and allocator from Environment (Anna Henningsen) [#36441](https://github.com/nodejs/node/pull/36441) +* [[`658a266cd4`](https://github.com/nodejs/node/commit/658a266cd4)] - **(SEMVER-MINOR)** **src**: allow preventing SetPrepareStackTraceCallback (Shelley Vohr) [#36447](https://github.com/nodejs/node/pull/36447) +* [[`f421422ea4`](https://github.com/nodejs/node/commit/f421422ea4)] - **(SEMVER-MINOR)** **src**: add maybe versions of EmitExit and EmitBeforeExit (Anna Henningsen) [#35486](https://github.com/nodejs/node/pull/35486) +* [[`a62d4d60f4`](https://github.com/nodejs/node/commit/a62d4d60f4)] - **(SEMVER-MINOR)** **stream**: add readableDidRead if has been read from (Robert Nagy) [#39589](https://github.com/nodejs/node/pull/39589) +* [[`63502131a3`](https://github.com/nodejs/node/commit/63502131a3)] - **(SEMVER-MINOR)** **stream**: pipeline accept Buffer as a valid first argument (Nitzan Uziely) [#37739](https://github.com/nodejs/node/pull/37739) +* [[`68bbebd42c`](https://github.com/nodejs/node/commit/68bbebd42c)] - **(SEMVER-MINOR)** **tls**: allow reading data into a static buffer (Andrey Pechkurov) [#35753](https://github.com/nodejs/node/pull/35753) +* [[`1cbb74d63d`](https://github.com/nodejs/node/commit/1cbb74d63d)] - **(SEMVER-MINOR)** **url**: expose urlToHttpOptions utility (Yongsheng Zhang) [#35960](https://github.com/nodejs/node/pull/35960) +* [[`8eb11356dd`](https://github.com/nodejs/node/commit/8eb11356dd)] - **(SEMVER-MINOR)** **util**: expose toUSVString (Robert Nagy) [#39814](https://github.com/nodejs/node/pull/39814) +* [[`84fcdc3074`](https://github.com/nodejs/node/commit/84fcdc3074)] - **(SEMVER-MINOR)** **v8**: implement v8.stopCoverage() (Joyee Cheung) [#33807](https://github.com/nodejs/node/pull/33807) +* [[`b238b6bf17`](https://github.com/nodejs/node/commit/b238b6bf17)] - **(SEMVER-MINOR)** **v8**: implement v8.takeCoverage() (Joyee Cheung) [#33807](https://github.com/nodejs/node/pull/33807) +* [[`9f6bc58da8`](https://github.com/nodejs/node/commit/9f6bc58da8)] - **(SEMVER-MINOR)** **worker**: add setEnvironmentData/getEnvironmentData (James M Snell) [#37486](https://github.com/nodejs/node/pull/37486) + +### Commits + +#### Semver-minor commits + +* [[`f3563d3197`](https://github.com/nodejs/node/commit/f3563d3197)] - **(SEMVER-MINOR)** **async_hooks**: use new v8::Context PromiseHook API (Stephen Belanger) [#36394](https://github.com/nodejs/node/pull/36394) +* [[`df37c106a7`](https://github.com/nodejs/node/commit/df37c106a7)] - **(SEMVER-MINOR)** **buffer**: introduce Blob (James M Snell) [#36811](https://github.com/nodejs/node/pull/36811) +* [[`223494c548`](https://github.com/nodejs/node/commit/223494c548)] - **(SEMVER-MINOR)** **buffer**: add base64url encoding option (Filip Skokan) [#36952](https://github.com/nodejs/node/pull/36952) +* [[`14fc4ddabc`](https://github.com/nodejs/node/commit/14fc4ddabc)] - **(SEMVER-MINOR)** **child_process**: allow `options.cwd` receive a URL (Khaidi Chu) [#38862](https://github.com/nodejs/node/pull/38862) +* [[`b68b13acb3`](https://github.com/nodejs/node/commit/b68b13acb3)] - **(SEMVER-MINOR)** **child_process**: add timeout to spawn and fork (Nitzan Uziely) [#37256](https://github.com/nodejs/node/pull/37256) +* [[`da98c9f99b`](https://github.com/nodejs/node/commit/da98c9f99b)] - **(SEMVER-MINOR)** **child_process**: allow promisified exec to be cancel (Carlos Fuentes) [#34249](https://github.com/nodejs/node/pull/34249) +* [[`779310ac87`](https://github.com/nodejs/node/commit/779310ac87)] - **(SEMVER-MINOR)** **child_process**: add 'overlapped' stdio flag (Thiago Padilha) [#29412](https://github.com/nodejs/node/pull/29412) +* [[`40eb3b79f1`](https://github.com/nodejs/node/commit/40eb3b79f1)] - **(SEMVER-MINOR)** **cli**: add -C alias for --conditions flag (Guy Bedford) [#38755](https://github.com/nodejs/node/pull/38755) +* [[`39eba0a2e1`](https://github.com/nodejs/node/commit/39eba0a2e1)] - **(SEMVER-MINOR)** **cli**: add --node-memory-debug option (Anna Henningsen) [#35537](https://github.com/nodejs/node/pull/35537) +* [[`d9b58a0262`](https://github.com/nodejs/node/commit/d9b58a0262)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick fa4cb172cde2 (Stephen Belanger) [#38577](https://github.com/nodejs/node/pull/38577) +* [[`9d7177c152`](https://github.com/nodejs/node/commit/9d7177c152)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 4c074516397b (Stephen Belanger) [#36394](https://github.com/nodejs/node/pull/36394) +* [[`ec0f0ef8ef`](https://github.com/nodejs/node/commit/ec0f0ef8ef)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 5f4413194480 (Stephen Belanger) [#36394](https://github.com/nodejs/node/pull/36394) +* [[`3e7238e45a`](https://github.com/nodejs/node/commit/3e7238e45a)] - **(SEMVER-MINOR)** **deps**: V8: cherry-pick 272445f10927 (Stephen Belanger) [#36394](https://github.com/nodejs/node/pull/36394) +* [[`214e568597`](https://github.com/nodejs/node/commit/214e568597)] - **(SEMVER-MINOR)** **deps**: V8: backport c0fceaa0669b (Stephen Belanger) [#36394](https://github.com/nodejs/node/pull/36394) +* [[`d8d9a9628a`](https://github.com/nodejs/node/commit/d8d9a9628a)] - **(SEMVER-MINOR)** **dns**: add "tries" option to Resolve options (Luan Devecchi) [#39610](https://github.com/nodejs/node/pull/39610) +* [[`15ba19b020`](https://github.com/nodejs/node/commit/15ba19b020)] - **(SEMVER-MINOR)** **dns**: allow `--dns-result-order` to change default dns verbatim (Ouyang Yadong) [#38099](https://github.com/nodejs/node/pull/38099) +* [[`defb77cac9`](https://github.com/nodejs/node/commit/defb77cac9)] - **(SEMVER-MINOR)** **doc**: add missing change to resolver ctor (Luan Devecchi) [#39610](https://github.com/nodejs/node/pull/39610) +* [[`9ee3f77e32`](https://github.com/nodejs/node/commit/9ee3f77e32)] - **(SEMVER-MINOR)** **errors**: remove experimental from --enable-source-maps (Benjamin Coe) [#37362](https://github.com/nodejs/node/pull/37362) +* [[`989c204a58`](https://github.com/nodejs/node/commit/989c204a58)] - **(SEMVER-MINOR)** **fs**: allow empty string for temp directory prefix (Voltrex) [#39028](https://github.com/nodejs/node/pull/39028) +* [[`ef72490cde`](https://github.com/nodejs/node/commit/ef72490cde)] - **(SEMVER-MINOR)** **fs**: allow no-params fsPromises fileHandle read (Nitzan Uziely) [#38287](https://github.com/nodejs/node/pull/38287) +* [[`cad9d20f64`](https://github.com/nodejs/node/commit/cad9d20f64)] - **(SEMVER-MINOR)** **fs**: add support for async iterators to `fsPromises.writeFile` (HiroyukiYagihashi) [#37490](https://github.com/nodejs/node/pull/37490) +* [[`fe12cc07b3`](https://github.com/nodejs/node/commit/fe12cc07b3)] - **(SEMVER-MINOR)** **fs**: add fsPromises.watch() (James M Snell) [#37179](https://github.com/nodejs/node/pull/37179) +* [[`2459c115a8`](https://github.com/nodejs/node/commit/2459c115a8)] - **(SEMVER-MINOR)** **fs**: allow `position` parameter to be a `BigInt` in read and readSync (Darshan Sen) [#36190](https://github.com/nodejs/node/pull/36190) +* [[`6544cfb4b9`](https://github.com/nodejs/node/commit/6544cfb4b9)] - **(SEMVER-MINOR)** **http2**: add support for sensitive headers (Anna Henningsen) [#34145](https://github.com/nodejs/node/pull/34145) +* [[`a6c6cbb4e6`](https://github.com/nodejs/node/commit/a6c6cbb4e6)] - **(SEMVER-MINOR)** **http2**: allow setting the local window size of a session (Yongsheng Zhang) [#35978](https://github.com/nodejs/node/pull/35978) +* [[`93af04afbb`](https://github.com/nodejs/node/commit/93af04afbb)] - **(SEMVER-MINOR)** **module**: add support for `URL` to `import.meta.resolve` (Antoine du Hamel) [#38587](https://github.com/nodejs/node/pull/38587) +* [[`f9f9389d83`](https://github.com/nodejs/node/commit/f9f9389d83)] - **(SEMVER-MINOR)** **module**: add support for `node:`‑prefixed `require(…)` calls (ExE Boss) [#37246](https://github.com/nodejs/node/pull/37246) +* [[`76d4f22bab`](https://github.com/nodejs/node/commit/76d4f22bab)] - **(SEMVER-MINOR)** **net**: allow net.BlockList to use net.SocketAddress objects (James M Snell) [#37917](https://github.com/nodejs/node/pull/37917) +* [[`82363d864d`](https://github.com/nodejs/node/commit/82363d864d)] - **(SEMVER-MINOR)** **net**: add SocketAddress class (James M Snell) [#37917](https://github.com/nodejs/node/pull/37917) +* [[`0202ba46b8`](https://github.com/nodejs/node/commit/0202ba46b8)] - **(SEMVER-MINOR)** **net**: make net.BlockList cloneable (James M Snell) [#37917](https://github.com/nodejs/node/pull/37917) +* [[`a41a3e3b3f`](https://github.com/nodejs/node/commit/a41a3e3b3f)] - **(SEMVER-MINOR)** **net**: make blocklist family case insensitive (James M Snell) [#34864](https://github.com/nodejs/node/pull/34864) +* [[`87c71065eb`](https://github.com/nodejs/node/commit/87c71065eb)] - **(SEMVER-MINOR)** **net**: introduce net.BlockList (James M Snell) [#34625](https://github.com/nodejs/node/pull/34625) +* [[`b421d99a48`](https://github.com/nodejs/node/commit/b421d99a48)] - **(SEMVER-MINOR)** **node-api**: allow retrieval of add-on file name (Gabriel Schulhof) [#37195](https://github.com/nodejs/node/pull/37195) +* [[`6a4811df8a`](https://github.com/nodejs/node/commit/6a4811df8a)] - **(SEMVER-MINOR)** **os**: add os.devNull (Luigi Pinca) [#38569](https://github.com/nodejs/node/pull/38569) +* [[`4a88ddeeca`](https://github.com/nodejs/node/commit/4a88ddeeca)] - **(SEMVER-MINOR)** **perf_hooks**: introduce createHistogram (James M Snell) [#37155](https://github.com/nodejs/node/pull/37155) +* [[`1a6bf1c4a3`](https://github.com/nodejs/node/commit/1a6bf1c4a3)] - **(SEMVER-MINOR)** **process**: add api to enable source-maps programmatically (legendecas) [#39085](https://github.com/nodejs/node/pull/39085) +* [[`99735a6fe8`](https://github.com/nodejs/node/commit/99735a6fe8)] - **(SEMVER-MINOR)** **process**: add `'worker'` event (James M Snell) [#38659](https://github.com/nodejs/node/pull/38659) +* [[`3982919317`](https://github.com/nodejs/node/commit/3982919317)] - **(SEMVER-MINOR)** **process**: add direct access to rss without iterating pages (Adrien Maret) [#34291](https://github.com/nodejs/node/pull/34291) +* [[`526e6c7bde`](https://github.com/nodejs/node/commit/526e6c7bde)] - **(SEMVER-MINOR)** **readline**: add AbortSignal support to interface (Nitzan Uziely) [#37932](https://github.com/nodejs/node/pull/37932) +* [[`e6eee08692`](https://github.com/nodejs/node/commit/e6eee08692)] - **(SEMVER-MINOR)** **readline**: add support for the AbortController to the question method (Mattias Runge-Broberg) [#33676](https://github.com/nodejs/node/pull/33676) +* [[`32de361d70`](https://github.com/nodejs/node/commit/32de361d70)] - **(SEMVER-MINOR)** **readline**: add history event and option to set initial history (Mattias Runge-Broberg) [#33662](https://github.com/nodejs/node/pull/33662) +* [[`797f7f8a38`](https://github.com/nodejs/node/commit/797f7f8a38)] - **(SEMVER-MINOR)** **repl**: add auto‑completion for `node:`‑prefixed `require(…)` calls (ExE Boss) [#37246](https://github.com/nodejs/node/pull/37246) +* [[`abfd71b64c`](https://github.com/nodejs/node/commit/abfd71b64c)] - **(SEMVER-MINOR)** **src**: call overload ctor from the original ctor (Darshan Sen) [#39768](https://github.com/nodejs/node/pull/39768) +* [[`1efae01b18`](https://github.com/nodejs/node/commit/1efae01b18)] - **(SEMVER-MINOR)** **src**: add a constructor overload for CallbackScope (Darshan Sen) [#39768](https://github.com/nodejs/node/pull/39768) +* [[`1aa2080d29`](https://github.com/nodejs/node/commit/1aa2080d29)] - **(SEMVER-MINOR)** **src**: fix align in cares\_wrap.h (Luan) [#39610](https://github.com/nodejs/node/pull/39610) +* [[`f7933804ba`](https://github.com/nodejs/node/commit/f7933804ba)] - **(SEMVER-MINOR)** **src**: allow to negate boolean CLI flags (Michaël Zasso) [#39023](https://github.com/nodejs/node/pull/39023) +* [[`6d06ac2202`](https://github.com/nodejs/node/commit/6d06ac2202)] - **(SEMVER-MINOR)** **src**: add --heapsnapshot-near-heap-limit option (Joyee Cheung) [#33010](https://github.com/nodejs/node/pull/33010) +* [[`4091eb9db7`](https://github.com/nodejs/node/commit/4091eb9db7)] - **(SEMVER-MINOR)** **src**: move node\_binding to modern THROW\_ERR\* (James M Snell) [#35469](https://github.com/nodejs/node/pull/35469) +* [[`577d228ca0`](https://github.com/nodejs/node/commit/577d228ca0)] - **(SEMVER-MINOR)** **src**: add way to get IsolateData and allocator from Environment (Anna Henningsen) [#36441](https://github.com/nodejs/node/pull/36441) +* [[`658a266cd4`](https://github.com/nodejs/node/commit/658a266cd4)] - **(SEMVER-MINOR)** **src**: allow preventing SetPrepareStackTraceCallback (Shelley Vohr) [#36447](https://github.com/nodejs/node/pull/36447) +* [[`f421422ea4`](https://github.com/nodejs/node/commit/f421422ea4)] - **(SEMVER-MINOR)** **src**: add maybe versions of EmitExit and EmitBeforeExit (Anna Henningsen) [#35486](https://github.com/nodejs/node/pull/35486) +* [[`a62d4d60f4`](https://github.com/nodejs/node/commit/a62d4d60f4)] - **(SEMVER-MINOR)** **stream**: add readableDidRead if has been read from (Robert Nagy) [#39589](https://github.com/nodejs/node/pull/39589) +* [[`63502131a3`](https://github.com/nodejs/node/commit/63502131a3)] - **(SEMVER-MINOR)** **stream**: pipeline accept Buffer as a valid first argument (Nitzan Uziely) [#37739](https://github.com/nodejs/node/pull/37739) +* [[`72ef41c72b`](https://github.com/nodejs/node/commit/72ef41c72b)] - **(SEMVER-MINOR)** **test**: add wpt tests for Blob (Michaël Zasso) [#36811](https://github.com/nodejs/node/pull/36811) +* [[`68bbebd42c`](https://github.com/nodejs/node/commit/68bbebd42c)] - **(SEMVER-MINOR)** **tls**: allow reading data into a static buffer (Andrey Pechkurov) [#35753](https://github.com/nodejs/node/pull/35753) +* [[`587deacad9`](https://github.com/nodejs/node/commit/587deacad9)] - **(SEMVER-MINOR)** **tools**: add `Worker` to type-parser (James M Snell) [#38659](https://github.com/nodejs/node/pull/38659) +* [[`1cbb74d63d`](https://github.com/nodejs/node/commit/1cbb74d63d)] - **(SEMVER-MINOR)** **url**: expose urlToHttpOptions utility (Yongsheng Zhang) [#35960](https://github.com/nodejs/node/pull/35960) +* [[`8eb11356dd`](https://github.com/nodejs/node/commit/8eb11356dd)] - **(SEMVER-MINOR)** **util**: expose toUSVString (Robert Nagy) [#39814](https://github.com/nodejs/node/pull/39814) +* [[`84fcdc3074`](https://github.com/nodejs/node/commit/84fcdc3074)] - **(SEMVER-MINOR)** **v8**: implement v8.stopCoverage() (Joyee Cheung) [#33807](https://github.com/nodejs/node/pull/33807) +* [[`b238b6bf17`](https://github.com/nodejs/node/commit/b238b6bf17)] - **(SEMVER-MINOR)** **v8**: implement v8.takeCoverage() (Joyee Cheung) [#33807](https://github.com/nodejs/node/pull/33807) +* [[`9f6bc58da8`](https://github.com/nodejs/node/commit/9f6bc58da8)] - **(SEMVER-MINOR)** **worker**: add setEnvironmentData/getEnvironmentData (James M Snell) [#37486](https://github.com/nodejs/node/pull/37486) + +#### Semver-patch commits + +* [[`3a60de0135`](https://github.com/nodejs/node/commit/3a60de0135)] - **assert**: change status of legacy asserts (James M Snell) [#38113](https://github.com/nodejs/node/pull/38113) +* [[`5a42be9719`](https://github.com/nodejs/node/commit/5a42be9719)] - **async_hooks**: use resource stack for AsyncLocalStorage run (Stephen Belanger) [#39890](https://github.com/nodejs/node/pull/39890) +* [[`fc29ddb38e`](https://github.com/nodejs/node/commit/fc29ddb38e)] - **async_hooks**: emit promise trace events from JS (Stephen Belanger) [#39135](https://github.com/nodejs/node/pull/39135) +* [[`13296d1abf`](https://github.com/nodejs/node/commit/13296d1abf)] - **async_hooks**: eliminate native PromiseHook (Stephen Belanger) [#39135](https://github.com/nodejs/node/pull/39135) +* [[`48e5971e51`](https://github.com/nodejs/node/commit/48e5971e51)] - **async_hooks**: check for empty contexts before removing (Bryan English) [#39095](https://github.com/nodejs/node/pull/39095) +* [[`691c00c48b`](https://github.com/nodejs/node/commit/691c00c48b)] - **async_hooks**: switch between native and context hooks correctly (Stephen Belanger) [#38912](https://github.com/nodejs/node/pull/38912) +* [[`8484ab2a6c`](https://github.com/nodejs/node/commit/8484ab2a6c)] - **buffer**: avoid creating the backing store in the thread (James M Snell) [#37052](https://github.com/nodejs/node/pull/37052) +* [[`c8d039a872`](https://github.com/nodejs/node/commit/c8d039a872)] - **buffer**: make Blob's constructor more spec-compliant (Michaël Zasso) [#37361](https://github.com/nodejs/node/pull/37361) +* [[`05d73ac286`](https://github.com/nodejs/node/commit/05d73ac286)] - **buffer**: make Blob's slice method more spec-compliant (Michaël Zasso) [#37361](https://github.com/nodejs/node/pull/37361) +* [[`e7cf2efc60`](https://github.com/nodejs/node/commit/e7cf2efc60)] - **buffer**: add @@toStringTag to Blob (Colin Ihrig) [#37336](https://github.com/nodejs/node/pull/37336) +* [[`d99deeaf97`](https://github.com/nodejs/node/commit/d99deeaf97)] - **build**: fix update authors commit (Mestery) [#39858](https://github.com/nodejs/node/pull/39858) +* [[`5e1cba81bf`](https://github.com/nodejs/node/commit/5e1cba81bf)] - **build**: add authors.yml (Tierney Cyren) [#35831](https://github.com/nodejs/node/pull/35831) +* [[`ed3c332089`](https://github.com/nodejs/node/commit/ed3c332089)] - **build**: add option to hide console window (Cheng Zhao) [#39712](https://github.com/nodejs/node/pull/39712) +* [[`c696f97c5e`](https://github.com/nodejs/node/commit/c696f97c5e)] - **build**: exclude markdown files from some GitHub Actions (Rich Trott) [#39565](https://github.com/nodejs/node/pull/39565) +* [[`0bd6dd1ee2`](https://github.com/nodejs/node/commit/0bd6dd1ee2)] - **build**: use lts shorthand in GitHub Actions (Rich Trott) [#39538](https://github.com/nodejs/node/pull/39538) +* [[`3482bca643`](https://github.com/nodejs/node/commit/3482bca643)] - **build**: override python executable path on configure (legendecas) [#39465](https://github.com/nodejs/node/pull/39465) +* [[`61261cdb8e`](https://github.com/nodejs/node/commit/61261cdb8e)] - **build**: use Node.js 14 in commit-lint.yml (Rich Trott) [#39506](https://github.com/nodejs/node/pull/39506) +* [[`719f1563c1`](https://github.com/nodejs/node/commit/719f1563c1)] - **build**: fix `host_arch_cc()` for AIX/IBM i (Richard Lau) [#39481](https://github.com/nodejs/node/pull/39481) +* [[`6e06b2ff9d`](https://github.com/nodejs/node/commit/6e06b2ff9d)] - **build**: update coverage Makefile target comments (Richard Lau) [#39365](https://github.com/nodejs/node/pull/39365) +* [[`4e28d2b2c0`](https://github.com/nodejs/node/commit/4e28d2b2c0)] - **build**: run workflows when a PR is ready for review (Michaël Zasso) [#39405](https://github.com/nodejs/node/pull/39405) +* [[`0da5d74da4`](https://github.com/nodejs/node/commit/0da5d74da4)] - **build**: update to setup-node@v2 (Rich Trott) [#39366](https://github.com/nodejs/node/pull/39366) +* [[`f2e1c2267e`](https://github.com/nodejs/node/commit/f2e1c2267e)] - **build**: update gcovr for gcc 8 compatibility (Richard Lau) [#39326](https://github.com/nodejs/node/pull/39326) +* [[`131dd6ec4d`](https://github.com/nodejs/node/commit/131dd6ec4d)] - **build**: remove unused comment in Makefile (LitoMore) [#39171](https://github.com/nodejs/node/pull/39171) +* [[`40e46321b0`](https://github.com/nodejs/node/commit/40e46321b0)] - **build**: uvwasi honours node\_shared\_libuv (Jérémy Lal) [#39260](https://github.com/nodejs/node/pull/39260) +* [[`5c6ab719f2`](https://github.com/nodejs/node/commit/5c6ab719f2)] - **build**: shorten path used in tarball build workflow (Richard Lau) [#39192](https://github.com/nodejs/node/pull/39192) +* [[`870526374c`](https://github.com/nodejs/node/commit/870526374c)] - **build**: add `library_files` to gyp variables (himself65) [#39293](https://github.com/nodejs/node/pull/39293) +* [[`0e221156aa`](https://github.com/nodejs/node/commit/0e221156aa)] - **build**: pass directory instead of list of files to js2c.py (Joyee Cheung) [#39069](https://github.com/nodejs/node/pull/39069) +* [[`8d8415415b`](https://github.com/nodejs/node/commit/8d8415415b)] - **build**: don't pass `--mode` argument to V8 test-runner (Richard Lau) [#39055](https://github.com/nodejs/node/pull/39055) +* [[`2d50217634`](https://github.com/nodejs/node/commit/2d50217634)] - **build**: fix commit linter on unrebased PRs (Mary Marchini) [#39121](https://github.com/nodejs/node/pull/39121) +* [[`c93d5e006e`](https://github.com/nodejs/node/commit/c93d5e006e)] - **build**: use Actions to validate commit message (Mary Marchini) [#32417](https://github.com/nodejs/node/pull/32417) +* [[`0bcaf9c4d1`](https://github.com/nodejs/node/commit/0bcaf9c4d1)] - **child_process**: fix spawn and fork abort behavior (Nitzan Uziely) [#37325](https://github.com/nodejs/node/pull/37325) +* [[`8010c83180`](https://github.com/nodejs/node/commit/8010c83180)] - **child_process**: fix bad abort signal leak (Nitzan Uziely) [#37257](https://github.com/nodejs/node/pull/37257) +* [[`32aff2f5a0`](https://github.com/nodejs/node/commit/32aff2f5a0)] - **console**: refactor to avoid unsafe array iteration (Antoine du Hamel) [#36753](https://github.com/nodejs/node/pull/36753) +* [[`f46e8cdf79`](https://github.com/nodejs/node/commit/f46e8cdf79)] - **debugger**: remove undefined parameter (Rich Trott) [#39570](https://github.com/nodejs/node/pull/39570) +* [[`482459edd4`](https://github.com/nodejs/node/commit/482459edd4)] - **debugger**: validate sec-websocket-accept response header (Chris Opperwall) [#39357](https://github.com/nodejs/node/pull/39357) +* [[`e9c46107d7`](https://github.com/nodejs/node/commit/e9c46107d7)] - **debugger**: rename internal module (Rich Trott) [#39378](https://github.com/nodejs/node/pull/39378) +* [[`49e0883c75`](https://github.com/nodejs/node/commit/49e0883c75)] - **debugger**: indicate server is ending (Rich Trott) [#39334](https://github.com/nodejs/node/pull/39334) +* [[`72a3419510`](https://github.com/nodejs/node/commit/72a3419510)] - **debugger**: rename inspector-cli test module to debugger (Rich Trott) [#38530](https://github.com/nodejs/node/pull/38530) +* [[`b3352cfba4`](https://github.com/nodejs/node/commit/b3352cfba4)] - **debugger**: prevent simultaneous heap snapshots (Rich Trott) [#39638](https://github.com/nodejs/node/pull/39638) +* [[`e5826ab1c2`](https://github.com/nodejs/node/commit/e5826ab1c2)] - **debugger**: remove final lint exceptions in inspect\_repl.js (Rich Trott) [#39078](https://github.com/nodejs/node/pull/39078) +* [[`34c0701952`](https://github.com/nodejs/node/commit/34c0701952)] - **deps**: V8: cherry-pick 00bb1a77c03e (Darshan Sen) [#39829](https://github.com/nodejs/node/pull/39829) +* [[`42359ab582`](https://github.com/nodejs/node/commit/42359ab582)] - **deps**: upgrade to libuv 1.42.0 (Luigi Pinca) [#39525](https://github.com/nodejs/node/pull/39525) +* [[`d863a9db68`](https://github.com/nodejs/node/commit/d863a9db68)] - **deps**: bump HdrHistogram\_C to 0.11.2 (Matteo Collina) [#39462](https://github.com/nodejs/node/pull/39462) +* [[`4c93968a62`](https://github.com/nodejs/node/commit/4c93968a62)] - **deps**: extract gtest source files to deps/googletest (legendecas) [#39386](https://github.com/nodejs/node/pull/39386) +* [[`fcae391fed`](https://github.com/nodejs/node/commit/fcae391fed)] - **deps**: update Acorn to v8.4.1 (Michaël Zasso) [#39166](https://github.com/nodejs/node/pull/39166) +* [[`327838dd96`](https://github.com/nodejs/node/commit/327838dd96)] - **deps**: V8: backport c9224589cf53 (Stephen Belanger) [#39743](https://github.com/nodejs/node/pull/39743) +* [[`89c1bbd7b2`](https://github.com/nodejs/node/commit/89c1bbd7b2)] - **deps**: V8: cherry-pick 81814ed44574 (Stephen Belanger) [#39719](https://github.com/nodejs/node/pull/39719) +* [[`8b9215d07c`](https://github.com/nodejs/node/commit/8b9215d07c)] - **deps**: update to cjs-module-lexer@1.2.2 (Guy Bedford) [#39402](https://github.com/nodejs/node/pull/39402) +* [[`e201293ddb`](https://github.com/nodejs/node/commit/e201293ddb)] - **dgram**: use simplified validator (Voltrex) [#39753](https://github.com/nodejs/node/pull/39753) +* [[`6fdac38f91`](https://github.com/nodejs/node/commit/6fdac38f91)] - **doc,fs**: remove experimental status for WHATWG URL as path (Antoine du Hamel) [#38870](https://github.com/nodejs/node/pull/38870) +* [[`d56e8268f9`](https://github.com/nodejs/node/commit/d56e8268f9)] - **doc,lib**: prepare for stricter multi-line array linting (Rich Trott) [#37088](https://github.com/nodejs/node/pull/37088) +* [[`5500ae9236`](https://github.com/nodejs/node/commit/5500ae9236)] - **domain**: do not add domain to promise from other context (Stephen Belanger) [#39135](https://github.com/nodejs/node/pull/39135) +* [[`dc855af18e`](https://github.com/nodejs/node/commit/dc855af18e)] - **errors**: don't throw TypeError on missing export (Benjamin Coe) [#39017](https://github.com/nodejs/node/pull/39017) +* [[`c13eadc218`](https://github.com/nodejs/node/commit/c13eadc218)] - **errors**: eliminate all overhead for hidden calls (Momtchil Momtchev) [#35644](https://github.com/nodejs/node/pull/35644) +* [[`d42bbe48c5`](https://github.com/nodejs/node/commit/d42bbe48c5)] - **esm**: use correct URL for error decoration (Bradley Farias) [#37854](https://github.com/nodejs/node/pull/37854) +* [[`9db3304368`](https://github.com/nodejs/node/commit/9db3304368)] - **esm**: update to correct deprecation code (Colin Ihrig) [#37147](https://github.com/nodejs/node/pull/37147) +* [[`e73bfed2f4`](https://github.com/nodejs/node/commit/e73bfed2f4)] - **esm**: deprecate legacy main lookup for modules (Guy Bedford) [#36918](https://github.com/nodejs/node/pull/36918) +* [[`c1782ea1f5`](https://github.com/nodejs/node/commit/c1782ea1f5)] - **events**: allow the options argument to be null (Luigi Pinca) [#39486](https://github.com/nodejs/node/pull/39486) +* [[`d2834fb97f`](https://github.com/nodejs/node/commit/d2834fb97f)] - **fs**: improve fsPromises writeFile performance (Nitzan Uziely) [#37610](https://github.com/nodejs/node/pull/37610) +* [[`ee1d13c90d`](https://github.com/nodejs/node/commit/ee1d13c90d)] - **fs**: use byteLength to handle ArrayBuffer views (Michaël Zasso) [#38187](https://github.com/nodejs/node/pull/38187) +* [[`b38d6b475b`](https://github.com/nodejs/node/commit/b38d6b475b)] - **fs**: fixup negative length in fs.truncate (James M Snell) [#37483](https://github.com/nodejs/node/pull/37483) +* [[`fe28128f3c`](https://github.com/nodejs/node/commit/fe28128f3c)] - **fs**: add docs and tests for `AsyncIterable` support in `fh.writeFile` (Antoine du Hamel) [#39836](https://github.com/nodejs/node/pull/39836) +* [[`2b0e2706c0`](https://github.com/nodejs/node/commit/2b0e2706c0)] - **fs**: improve fsPromises readFile performance (Nitzan Uziely) [#37608](https://github.com/nodejs/node/pull/37608) +* [[`a4d6f78619`](https://github.com/nodejs/node/commit/a4d6f78619)] - **fs**: move constants to internal/fs/utils.js (Darshan Sen) [#38061](https://github.com/nodejs/node/pull/38061) +* [[`402f7722ce`](https://github.com/nodejs/node/commit/402f7722ce)] - **fs**: add validatePosition and use in read and readSync (Darshan Sen) [#37051](https://github.com/nodejs/node/pull/37051) +* [[`2bc301dcff`](https://github.com/nodejs/node/commit/2bc301dcff)] - **http**: decodes url.username and url.password for authorization header (Lew Gordon) [#39310](https://github.com/nodejs/node/pull/39310) +* [[`5459f4af33`](https://github.com/nodejs/node/commit/5459f4af33)] - **http**: clean up HttpParser correctly (Tobias Koppers) [#39292](https://github.com/nodejs/node/pull/39292) +* [[`8b3feee148`](https://github.com/nodejs/node/commit/8b3feee148)] - **http,https**: align server option of https with http (Qingyu Deng) [#38992](https://github.com/nodejs/node/pull/38992) +* [[`cf59e87c8b`](https://github.com/nodejs/node/commit/cf59e87c8b)] - **inspector**: update inspector\_protocol to 89c4adf (Rich Trott) [#39650](https://github.com/nodejs/node/pull/39650) +* [[`ea5f2047a2`](https://github.com/nodejs/node/commit/ea5f2047a2)] - **inspector**: update inspector\_protocol to 8ec18cf (Rich Trott) [#39614](https://github.com/nodejs/node/pull/39614) +* [[`1e5aca550c`](https://github.com/nodejs/node/commit/1e5aca550c)] - **inspector**: mark as stable (Gireesh Punathil) [#37748](https://github.com/nodejs/node/pull/37748) +* [[`8a2ce5dae6`](https://github.com/nodejs/node/commit/8a2ce5dae6)] - **inspector**: move inspector async hooks to environment (Joyee Cheung) [#39112](https://github.com/nodejs/node/pull/39112) +* [[`338189ff6f`](https://github.com/nodejs/node/commit/338189ff6f)] - **lib**: simplify validators (Voltrex) [#39753](https://github.com/nodejs/node/pull/39753) +* [[`e1019351e8`](https://github.com/nodejs/node/commit/e1019351e8)] - **lib**: cleanup validation (Voltrex) [#39652](https://github.com/nodejs/node/pull/39652) +* [[`dbaf4988bc`](https://github.com/nodejs/node/commit/dbaf4988bc)] - **lib**: use validators (Voltrex) [#39663](https://github.com/nodejs/node/pull/39663) +* [[`9c33e4bfb2`](https://github.com/nodejs/node/commit/9c33e4bfb2)] - **lib**: use validator (Voltrex) [#39547](https://github.com/nodejs/node/pull/39547) +* [[`5b1104291d`](https://github.com/nodejs/node/commit/5b1104291d)] - **lib**: use `validateObject` (Voltrex) [#39605](https://github.com/nodejs/node/pull/39605) +* [[`1ce81079df`](https://github.com/nodejs/node/commit/1ce81079df)] - **lib**: remove use of array destructuring (Antoine du Hamel) [#36818](https://github.com/nodejs/node/pull/36818) +* [[`b24b34effd`](https://github.com/nodejs/node/commit/b24b34effd)] - **lib**: add `bound apply` variants of varargs `primordials` (ExE Boss) [#37005](https://github.com/nodejs/node/pull/37005) +* [[`7cdff9a6a8`](https://github.com/nodejs/node/commit/7cdff9a6a8)] - **lib**: refactor `primordials.makeSafe` to use more primordials (ExE Boss) [#36865](https://github.com/nodejs/node/pull/36865) +* [[`1737352580`](https://github.com/nodejs/node/commit/1737352580)] - **lib**: comment explaining special-case handling of promises (Stephen Belanger) [#39135](https://github.com/nodejs/node/pull/39135) +* [[`7f54cccb6c`](https://github.com/nodejs/node/commit/7f54cccb6c)] - **lib**: refactor to use validateString (ZiJian Liu) [#37006](https://github.com/nodejs/node/pull/37006) +* [[`98259dc527`](https://github.com/nodejs/node/commit/98259dc527)] - **module**: improve support of data: URLs (Antoine du Hamel) [#37392](https://github.com/nodejs/node/pull/37392) +* [[`9aba2888a1`](https://github.com/nodejs/node/commit/9aba2888a1)] - **net**: throw ERR\_OUT\_OF\_RANGE if blockList.addSubnet prefix is NaN (ZiJian Liu) [#36732](https://github.com/nodejs/node/pull/36732) +* [[`2ca12c83b4`](https://github.com/nodejs/node/commit/2ca12c83b4)] - **node-api**: handle pending exception in cb wrapper (Michael Dawson) [#39476](https://github.com/nodejs/node/pull/39476) +* [[`9e5edf2158`](https://github.com/nodejs/node/commit/9e5edf2158)] - **node-api**: cctest on v8impl::Reference (legendecas) [#38970](https://github.com/nodejs/node/pull/38970) +* [[`a74032a490`](https://github.com/nodejs/node/commit/a74032a490)] - **node-api**: rtn pending excep on napi\_new\_instance (legendecas) [#38798](https://github.com/nodejs/node/pull/38798) +* [[`bcb85adee6`](https://github.com/nodejs/node/commit/bcb85adee6)] - **policy**: canonicalize before resolving specifiers (Bradley Farias) [#37863](https://github.com/nodejs/node/pull/37863) +* [[`0ff520cf02`](https://github.com/nodejs/node/commit/0ff520cf02)] - **policy**: fix integrity when DEFAULT\_ENCODING is set (Tobias Nießen) [#39750](https://github.com/nodejs/node/pull/39750) +* [[`6c87b591d9`](https://github.com/nodejs/node/commit/6c87b591d9)] - **readline**: allow completer to rewrite existing input (Anna Henningsen) [#39178](https://github.com/nodejs/node/pull/39178) +* [[`37b4708b19`](https://github.com/nodejs/node/commit/37b4708b19)] - **repl**: fix tla function hoisting (Don Jayamanne) [#39745](https://github.com/nodejs/node/pull/39745) +* [[`9264caeafe`](https://github.com/nodejs/node/commit/9264caeafe)] - **repl**: do not include legacy getter/setter methods in completion (Anna Henningsen) [#39576](https://github.com/nodejs/node/pull/39576) +* [[`50c5e71e22`](https://github.com/nodejs/node/commit/50c5e71e22)] - **repl**: correctly hoist top level await declarations (ejose19) [#39265](https://github.com/nodejs/node/pull/39265) +* [[`1e065a0a43`](https://github.com/nodejs/node/commit/1e065a0a43)] - **repl**: processTopLevelAwait fallback error handling (ejose19) [#39290](https://github.com/nodejs/node/pull/39290) +* [[`99664494ff`](https://github.com/nodejs/node/commit/99664494ff)] - **repl**: ensure correct syntax err for await parsing (Guy Bedford) [#39154](https://github.com/nodejs/node/pull/39154) +* [[`761dafafde`](https://github.com/nodejs/node/commit/761dafafde)] - **repl**: fix Ctrl+C on top level await (Antoine du Hamel) [#38656](https://github.com/nodejs/node/pull/38656) +* [[`88b02cbb08`](https://github.com/nodejs/node/commit/88b02cbb08)] - **repl**: add auto‑completion for dynamic import calls (ExE Boss) [#37178](https://github.com/nodejs/node/pull/37178) +* [[`8f3a8830ba`](https://github.com/nodejs/node/commit/8f3a8830ba)] - **repl**: refactor to avoid unsafe array iteration (Antoine du Hamel) [#37188](https://github.com/nodejs/node/pull/37188) +* [[`a48e2d6ec7`](https://github.com/nodejs/node/commit/a48e2d6ec7)] - **repl**: refactor to avoid unsafe array iteration (Darshan Sen) [#36663](https://github.com/nodejs/node/pull/36663) +* [[`20ffadf437`](https://github.com/nodejs/node/commit/20ffadf437)] - **repl**: refactor to use more primordials (Antoine du Hamel) [#36264](https://github.com/nodejs/node/pull/36264) +* [[`f69c934ad4`](https://github.com/nodejs/node/commit/f69c934ad4)] - **report**: generates report on threads with no isolates (legendecas) [#38994](https://github.com/nodejs/node/pull/38994) +* [[`c4686fa5a7`](https://github.com/nodejs/node/commit/c4686fa5a7)] - **src**: fix TextDecoder final flush size calculation (James M Snell) [#39737](https://github.com/nodejs/node/pull/39737) +* [[`495cd02c20`](https://github.com/nodejs/node/commit/495cd02c20)] - **src**: add cosmetic space character to `async_wrap.h` file (Juan José Arboleda) [#39459](https://github.com/nodejs/node/pull/39459) +* [[`985ec48975`](https://github.com/nodejs/node/commit/985ec48975)] - **src**: print native module id on native module not found (legendecas) [#39460](https://github.com/nodejs/node/pull/39460) +* [[`e6ff7e648e`](https://github.com/nodejs/node/commit/e6ff7e648e)] - **src**: close HandleWraps instead of deleting them in OnGCCollect() (Anna Henningsen) [#39441](https://github.com/nodejs/node/pull/39441) +* [[`5c473bdc12`](https://github.com/nodejs/node/commit/5c473bdc12)] - **src**: remove unused guards around node-api reference (legendecas) [#38334](https://github.com/nodejs/node/pull/38334) +* [[`41213bd507`](https://github.com/nodejs/node/commit/41213bd507)] - **src**: add JSDoc typings for v8 (Voltrex) [#38944](https://github.com/nodejs/node/pull/38944) +* [[`02b1df9fac`](https://github.com/nodejs/node/commit/02b1df9fac)] - **src**: fix crash in AfterGetAddrInfo (Anna Henningsen) [#39735](https://github.com/nodejs/node/pull/39735) +* [[`99493b07d4`](https://github.com/nodejs/node/commit/99493b07d4)] - **src**: fix fatal errors when a current isolate not exist (legendecas) [#38624](https://github.com/nodejs/node/pull/38624) +* [[`9433c28c14`](https://github.com/nodejs/node/commit/9433c28c14)] - **src**: remove more extra semis from member fns (Shelley Vohr) [#38744](https://github.com/nodejs/node/pull/38744) +* [[`bad990c934`](https://github.com/nodejs/node/commit/bad990c934)] - **src**: use BaseObject::kInteralFieldCount in Blob (Joyee Cheung) [#36991](https://github.com/nodejs/node/pull/36991) +* [[`0a759dff52`](https://github.com/nodejs/node/commit/0a759dff52)] - **src**: compare IPv4 addresses in host byte order (Colin Ihrig) [#39096](https://github.com/nodejs/node/pull/39096) +* [[`d73181f243`](https://github.com/nodejs/node/commit/d73181f243)] - **src**: reduce duplicated boilerplate with new env utility fn (James M Snell) [#36536](https://github.com/nodejs/node/pull/36536) +* [[`85af15a8b6`](https://github.com/nodejs/node/commit/85af15a8b6)] - **src**: allow instances of net.BlockList to be created internally (James M Snell) [#34741](https://github.com/nodejs/node/pull/34741) +* [[`1008c80176`](https://github.com/nodejs/node/commit/1008c80176)] - **src**: add SocketAddressLRU Utility (James M Snell) [#34618](https://github.com/nodejs/node/pull/34618) +* [[`e404841a9c`](https://github.com/nodejs/node/commit/e404841a9c)] - **src**: set PromiseHooks by Environment (Bryan English) [#38821](https://github.com/nodejs/node/pull/38821) +* [[`c8c290ae8f`](https://github.com/nodejs/node/commit/c8c290ae8f)] - **src,zlib**: tighten up Z\_\*\_WINDOWBITS macros (Khaidi Chu) [#39115](https://github.com/nodejs/node/pull/39115) +* [[`de171177b4`](https://github.com/nodejs/node/commit/de171177b4)] - **stream**: clean `endWritableNT` (Mestery) [#39645](https://github.com/nodejs/node/pull/39645) +* [[`32a5b8f59b`](https://github.com/nodejs/node/commit/32a5b8f59b)] - **stream**: move duplicated code to an internal module (Rich Trott) [#37508](https://github.com/nodejs/node/pull/37508) +* [[`f90b22d351`](https://github.com/nodejs/node/commit/f90b22d351)] - **util**: add internal createDeferredPromise() (Colin Ihrig) [#37095](https://github.com/nodejs/node/pull/37095) +* [[`61b4a98480`](https://github.com/nodejs/node/commit/61b4a98480)] - **zlib**: avoid converting `Uint8Array` instances to `Buffer` (Antoine du Hamel) [#39492](https://github.com/nodejs/node/pull/39492) + +#### Documentation commits + +* [[`8efd559347`](https://github.com/nodejs/node/commit/8efd559347)] - **doc**: add duplicate CVE check in sec. release doc (Daniel Bevenius) [#39845](https://github.com/nodejs/node/pull/39845) +* [[`7b123ec78d`](https://github.com/nodejs/node/commit/7b123ec78d)] - **doc**: improve description of the triagers team (Michaël Zasso) [#39833](https://github.com/nodejs/node/pull/39833) +* [[`615477f67b`](https://github.com/nodejs/node/commit/615477f67b)] - **doc**: update instructions for cc (Michael Dawson) [#39674](https://github.com/nodejs/node/pull/39674) +* [[`1a8a26d92e`](https://github.com/nodejs/node/commit/1a8a26d92e)] - **doc**: fix malformed changelog entries (Rich Trott) [#39791](https://github.com/nodejs/node/pull/39791) +* [[`9e772ca9a1`](https://github.com/nodejs/node/commit/9e772ca9a1)] - **doc**: fix lint errors in packages.md (Rich Trott) [#39792](https://github.com/nodejs/node/pull/39792) +* [[`2624c98207`](https://github.com/nodejs/node/commit/2624c98207)] - **doc**: add example of self-reference in scoped packages (Jesús Leganés-Combarro 'piranna) [#37630](https://github.com/nodejs/node/pull/37630) +* [[`00f2cee26c`](https://github.com/nodejs/node/commit/00f2cee26c)] - **doc**: add himadriganguly as a triager (Himadri Ganguly) [#39757](https://github.com/nodejs/node/pull/39757) +* [[`95b9cc78d2`](https://github.com/nodejs/node/commit/95b9cc78d2)] - **doc**: fix YAML comment opening tags (Jayden Seric) [#38324](https://github.com/nodejs/node/pull/38324) +* [[`49a7962d58`](https://github.com/nodejs/node/commit/49a7962d58)] - **doc**: fix `fs.rmdir` `recursive` option deprecation history (Antoine du Hamel) [#39728](https://github.com/nodejs/node/pull/39728) +* [[`53300d33c7`](https://github.com/nodejs/node/commit/53300d33c7)] - **doc**: fixed variable names in queueMicrotask example (ashish maurya) [#39634](https://github.com/nodejs/node/pull/39634) +* [[`df1e20aaf1`](https://github.com/nodejs/node/commit/df1e20aaf1)] - **doc**: update debugger.md description and examples (Rich Trott) [#39661](https://github.com/nodejs/node/pull/39661) +* [[`9672bbf01c`](https://github.com/nodejs/node/commit/9672bbf01c)] - **doc**: fix color contrast issue in light mode (Rich Trott) [#39660](https://github.com/nodejs/node/pull/39660) +* [[`48281ecfcd`](https://github.com/nodejs/node/commit/48281ecfcd)] - **doc**: add code examples to `Writable.destroy()` and `Writable.destroyed` (Juan José Arboleda) [#39491](https://github.com/nodejs/node/pull/39491) +* [[`8799a134e4`](https://github.com/nodejs/node/commit/8799a134e4)] - **doc**: move `NODE_MODULE_VERSION` in release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`89c8afcf48`](https://github.com/nodejs/node/commit/89c8afcf48)] - **doc**: remove outdated ARM information from release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`a718b26f28`](https://github.com/nodejs/node/commit/a718b26f28)] - **doc**: fence command examples in release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`42669bb049`](https://github.com/nodejs/node/commit/42669bb049)] - **doc**: update backport labels in release guide (Richard Lau) [#39544](https://github.com/nodejs/node/pull/39544) +* [[`a437de3c5f`](https://github.com/nodejs/node/commit/a437de3c5f)] - **doc**: add code example to `http.createServer` method (Juan José Arboleda) [#39455](https://github.com/nodejs/node/pull/39455) +* [[`695569fc17`](https://github.com/nodejs/node/commit/695569fc17)] - **doc**: move lball@redhat.com to emeritus (Lance Ball) [#39501](https://github.com/nodejs/node/pull/39501) +* [[`c7523da86c`](https://github.com/nodejs/node/commit/c7523da86c)] - **doc**: update AUTHORS (Rich Trott) [#39488](https://github.com/nodejs/node/pull/39488) +* [[`e826109d5c`](https://github.com/nodejs/node/commit/e826109d5c)] - **doc**: update strategic initiative champion (Rich Trott) [#39487](https://github.com/nodejs/node/pull/39487) +* [[`39da842051`](https://github.com/nodejs/node/commit/39da842051)] - **doc**: simplify unnecessarily specific .mailmap entries (Rich Trott) [#39430](https://github.com/nodejs/node/pull/39430) +* [[`6a4c6ce4d7`](https://github.com/nodejs/node/commit/6a4c6ce4d7)] - **doc**: update checkbox label in backporting guide (Darshan Sen) [#39420](https://github.com/nodejs/node/pull/39420) +* [[`d17afa08bd`](https://github.com/nodejs/node/commit/d17afa08bd)] - **doc**: remove \_Addenda\_ from headers (Rich Trott) [#39427](https://github.com/nodejs/node/pull/39427) +* [[`ae97a96d9e`](https://github.com/nodejs/node/commit/ae97a96d9e)] - **doc**: simplify .mailmap file (Rich Trott) [#39418](https://github.com/nodejs/node/pull/39418) +* [[`a3dee70f66`](https://github.com/nodejs/node/commit/a3dee70f66)] - **doc**: fix broken internal link in http.md (Rich Trott) [#39425](https://github.com/nodejs/node/pull/39425) +* [[`ca947ac524`](https://github.com/nodejs/node/commit/ca947ac524)] - **doc**: remove outdated step in onboarding exercise (Rich Trott) [#39410](https://github.com/nodejs/node/pull/39410) +* [[`86e12607f0`](https://github.com/nodejs/node/commit/86e12607f0)] - **doc**: revise strategic initiatives text (Rich Trott) [#39417](https://github.com/nodejs/node/pull/39417) +* [[`cd8e773d28`](https://github.com/nodejs/node/commit/cd8e773d28)] - **doc**: update mailmap and AUTHORS (Rich Trott) [#39393](https://github.com/nodejs/node/pull/39393) +* [[`8376b07ae8`](https://github.com/nodejs/node/commit/8376b07ae8)] - **doc**: use a details tag for completed initiatves (Rich Trott) [#39416](https://github.com/nodejs/node/pull/39416) +* [[`43d28f5f00`](https://github.com/nodejs/node/commit/43d28f5f00)] - **doc**: update commit-queue.md to indicate GitHub Actions are checked (Rich Trott) [#39411](https://github.com/nodejs/node/pull/39411) +* [[`63b0603e95`](https://github.com/nodejs/node/commit/63b0603e95)] - **doc**: use \_pull request\_ instead of \_PR\_ in onboarding doc (Rich Trott) [#39409](https://github.com/nodejs/node/pull/39409) +* [[`73f784f764`](https://github.com/nodejs/node/commit/73f784f764)] - **doc**: add strategic initiatives from TSC repo (Rich Trott) [#39394](https://github.com/nodejs/node/pull/39394) +* [[`1a494d51dc`](https://github.com/nodejs/node/commit/1a494d51dc)] - **doc**: standardize on \_pull request\_ (Rich Trott) [#39384](https://github.com/nodejs/node/pull/39384) +* [[`eb12e4ccfb`](https://github.com/nodejs/node/commit/eb12e4ccfb)] - **doc**: make minor edits to pull request text (Rich Trott) [#39383](https://github.com/nodejs/node/pull/39383) +* [[`ab0bf4fa1a`](https://github.com/nodejs/node/commit/ab0bf4fa1a)] - **doc**: add docker-node and build-wg issue contents (Daniel Bevenius) [#39215](https://github.com/nodejs/node/pull/39215) +* [[`8438e8bf33`](https://github.com/nodejs/node/commit/8438e8bf33)] - **doc**: add instructions for core vuln files (Daniel Bevenius) [#39220](https://github.com/nodejs/node/pull/39220) +* [[`c3cfefc2d3`](https://github.com/nodejs/node/commit/c3cfefc2d3)] - **doc**: standardize on not capitalizing \_collaborator\_ (Rich Trott) [#39379](https://github.com/nodejs/node/pull/39379) +* [[`672023f9f2`](https://github.com/nodejs/node/commit/672023f9f2)] - **doc**: update mailmap and deduplicate AUTHORS entry (Rich Trott) [#39391](https://github.com/nodejs/node/pull/39391) +* [[`baaa397e39`](https://github.com/nodejs/node/commit/baaa397e39)] - **doc**: update AUTHORS (Rich Trott) [#39367](https://github.com/nodejs/node/pull/39367) +* [[`f39d93a428`](https://github.com/nodejs/node/commit/f39d93a428)] - **doc**: move jdalton to emeritus (Rich Trott) [#39380](https://github.com/nodejs/node/pull/39380) +* [[`0b1ce72d64`](https://github.com/nodejs/node/commit/0b1ce72d64)] - **doc**: edit guide on pull requests (Rich Trott) [#39359](https://github.com/nodejs/node/pull/39359) +* [[`6f0b3a20d1`](https://github.com/nodejs/node/commit/6f0b3a20d1)] - **doc**: add text about moving long commit lists out of PR description (Danielle Adams) [#39186](https://github.com/nodejs/node/pull/39186) +* [[`9d43ce3b80`](https://github.com/nodejs/node/commit/9d43ce3b80)] - **doc**: do not use & for "and" in text (Rich Trott) [#39345](https://github.com/nodejs/node/pull/39345) +* [[`25c104f21f`](https://github.com/nodejs/node/commit/25c104f21f)] - **doc**: update AUTHORS (Rich Trott) [#39277](https://github.com/nodejs/node/pull/39277) +* [[`b47b47930c`](https://github.com/nodejs/node/commit/b47b47930c)] - **doc**: put information about the past in details tags (Rich Trott) [#39321](https://github.com/nodejs/node/pull/39321) +* [[`5eafc3afa8`](https://github.com/nodejs/node/commit/5eafc3afa8)] - **doc**: move AndreasMadsen to emeritus (Rich Trott) [#39315](https://github.com/nodejs/node/pull/39315) +* [[`fbf658f1d5`](https://github.com/nodejs/node/commit/fbf658f1d5)] - **doc**: move ofrobots to collaborator emeritus (Rich Trott) [#39307](https://github.com/nodejs/node/pull/39307) +* [[`fc7d714149`](https://github.com/nodejs/node/commit/fc7d714149)] - **doc**: simplify CRAN mirror text in benchmark guide (Rich Trott) [#39287](https://github.com/nodejs/node/pull/39287) +* [[`22f0b7e0d0`](https://github.com/nodejs/node/commit/22f0b7e0d0)] - **doc**: use "repository" instead of "repo" in onboarding.md (Rich Trott) [#39286](https://github.com/nodejs/node/pull/39286) +* [[`f46ae3ffb6`](https://github.com/nodejs/node/commit/f46ae3ffb6)] - **doc**: update collaborator email address (Rich Trott) [#39263](https://github.com/nodejs/node/pull/39263) +* [[`8c569cef88`](https://github.com/nodejs/node/commit/8c569cef88)] - **doc**: remove GitHub mark (Rich Trott) [#39251](https://github.com/nodejs/node/pull/39251) +* [[`b4a0c5a384`](https://github.com/nodejs/node/commit/b4a0c5a384)] - **doc**: remove emailing the TSC from offboarding doc (Rich Trott) [#39280](https://github.com/nodejs/node/pull/39280) +* [[`a4d70ff0cc`](https://github.com/nodejs/node/commit/a4d70ff0cc)] - **doc**: use "repository" in guides versus repo (Michael Dawson) [#39198](https://github.com/nodejs/node/pull/39198) +* [[`31163ed9ee`](https://github.com/nodejs/node/commit/31163ed9ee)] - **doc**: update Node-api version matrix (Michael Dawson) [#39197](https://github.com/nodejs/node/pull/39197) +* [[`9357547519`](https://github.com/nodejs/node/commit/9357547519)] - **doc**: update node-api support matrix (Michael Dawson) [#38424](https://github.com/nodejs/node/pull/38424) +* [[`f08e9d5230`](https://github.com/nodejs/node/commit/f08e9d5230)] - **doc**: remove onboarding-extras (Rich Trott) [#39252](https://github.com/nodejs/node/pull/39252) +* [[`6466faf26d`](https://github.com/nodejs/node/commit/6466faf26d)] - **doc**: move Sam Ruby to emeritus (Rich Trott) [#39264](https://github.com/nodejs/node/pull/39264) +* [[`06acbf6453`](https://github.com/nodejs/node/commit/06acbf6453)] - **doc**: update AUTHORS file (Rich Trott) [#39250](https://github.com/nodejs/node/pull/39250) +* [[`9178805653`](https://github.com/nodejs/node/commit/9178805653)] - **doc**: fix color contrast for anchor marks in dark mode (Rich Trott) [#39168](https://github.com/nodejs/node/pull/39168) +* [[`c6118b23f7`](https://github.com/nodejs/node/commit/c6118b23f7)] - **doc**: rename datatypes to data types (FrankEntriken) [#39209](https://github.com/nodejs/node/pull/39209) +* [[`fdd315918f`](https://github.com/nodejs/node/commit/fdd315918f)] - **doc**: normalize CSS variable names and indentation (Rich Trott) [#39199](https://github.com/nodejs/node/pull/39199) +* [[`9c7c44781c`](https://github.com/nodejs/node/commit/9c7c44781c)] - **doc**: use more consistent formatting for deprecations (Rich Trott) [#39218](https://github.com/nodejs/node/pull/39218) +* [[`c97ebd7905`](https://github.com/nodejs/node/commit/c97ebd7905)] - **doc**: update AUTHORS (Rich Trott) [#39217](https://github.com/nodejs/node/pull/39217) +* [[`c4a3a24848`](https://github.com/nodejs/node/commit/c4a3a24848)] - **doc**: use "pull request" instead of "PR" in packages.md (Rich Trott) [#39213](https://github.com/nodejs/node/pull/39213) +* [[`0d098bfaf0`](https://github.com/nodejs/node/commit/0d098bfaf0)] - **doc**: move v8.stopCoverage() to expected location in doc (Rich Trott) [#39212](https://github.com/nodejs/node/pull/39212) +* [[`bd6af78749`](https://github.com/nodejs/node/commit/bd6af78749)] - **doc**: move vm.measureMemory() to expected location in doc (Rich Trott) [#39211](https://github.com/nodejs/node/pull/39211) +* [[`7378b84bb8`](https://github.com/nodejs/node/commit/7378b84bb8)] - **doc**: add missing deprecation code (Colin Ihrig) [#37147](https://github.com/nodejs/node/pull/37147) +* [[`2f6861ca51`](https://github.com/nodejs/node/commit/2f6861ca51)] - **doc**: use ASCII order for md refs (Antoine du Hamel) [#39170](https://github.com/nodejs/node/pull/39170) +* [[`fa3909504f`](https://github.com/nodejs/node/commit/fa3909504f)] - **doc**: add cc oss-security@lists.openwall.com (Daniel Bevenius) [#39191](https://github.com/nodejs/node/pull/39191) +* [[`52105acd5f`](https://github.com/nodejs/node/commit/52105acd5f)] - **doc**: remove instructions for unsupported Node.js versions (Rich Trott) [#39185](https://github.com/nodejs/node/pull/39185) +* [[`eb2d75da16`](https://github.com/nodejs/node/commit/eb2d75da16)] - **doc**: remove obsolete cc recommendations (Rich Trott) [#39181](https://github.com/nodejs/node/pull/39181) +* [[`4cf17edd03`](https://github.com/nodejs/node/commit/4cf17edd03)] - **doc**: use "repository" in maintaining-V8 doc (Rich Trott) [#39179](https://github.com/nodejs/node/pull/39179) +* [[`d6a4f8aac9`](https://github.com/nodejs/node/commit/d6a4f8aac9)] - **doc**: fix broken link in errors.md (Rich Trott) [#39200](https://github.com/nodejs/node/pull/39200) +* [[`82458b30fe`](https://github.com/nodejs/node/commit/82458b30fe)] - **doc**: correct JavaScript primitive value names in n-api.md (legendecas) [#39129](https://github.com/nodejs/node/pull/39129) +* [[`2629979fd0`](https://github.com/nodejs/node/commit/2629979fd0)] - **doc**: apply logical ordering to CSS variables (Rich Trott) [#39169](https://github.com/nodejs/node/pull/39169) +* [[`1996580b06`](https://github.com/nodejs/node/commit/1996580b06)] - **doc**: use repository instead of repo (Rich Trott) [#39157](https://github.com/nodejs/node/pull/39157) +* [[`74ba115ab6`](https://github.com/nodejs/node/commit/74ba115ab6)] - **doc**: fix `EventTarget.dispatchEvent` docs (Rohan Sharma) [#39127](https://github.com/nodejs/node/pull/39127) +* [[`2884d9094d`](https://github.com/nodejs/node/commit/2884d9094d)] - **doc**: update AUTHORS file (Rich Trott) [#39082](https://github.com/nodejs/node/pull/39082) +* [[`d069c725b1`](https://github.com/nodejs/node/commit/d069c725b1)] - **doc**: fix napi\_default\_property name (Davidson Francis) [#39104](https://github.com/nodejs/node/pull/39104) +* [[`1b74d3f775`](https://github.com/nodejs/node/commit/1b74d3f775)] - **doc**: fix dead links in packages.md (Michaël Zasso) [#39113](https://github.com/nodejs/node/pull/39113) +* [[`0c2b5a048d`](https://github.com/nodejs/node/commit/0c2b5a048d)] - **doc**: clearify that http does chunked encoding itself (Mao Wtm) [#28379](https://github.com/nodejs/node/pull/28379) +* [[`d0d731e271`](https://github.com/nodejs/node/commit/d0d731e271)] - **doc**: add descriptions about when `options.mode` is ignored (Ray) [#39881](https://github.com/nodejs/node/pull/39881) +* [[`898db5a570`](https://github.com/nodejs/node/commit/898db5a570)] - **doc**: add code example to `fs.truncate` method (Juan José Arboleda) [#39454](https://github.com/nodejs/node/pull/39454) +* [[`05d7460747`](https://github.com/nodejs/node/commit/05d7460747)] - **doc**: add annotation to writeFile `data` as `Object` (Jacob) [#39167](https://github.com/nodejs/node/pull/39167) +* [[`2ef61b987d`](https://github.com/nodejs/node/commit/2ef61b987d)] - **doc**: fix constants usage in fs.access example (Cyrille Bourgois) [#39289](https://github.com/nodejs/node/pull/39289) +* [[`b2c533ea1d`](https://github.com/nodejs/node/commit/b2c533ea1d)] - **doc**: remove unnecessary module format comments (Rich Trott) [#39219](https://github.com/nodejs/node/pull/39219) +* [[`e8355c47d2`](https://github.com/nodejs/node/commit/e8355c47d2)] - **doc**: remove file name from self-reference links (Antoine du Hamel) [#39165](https://github.com/nodejs/node/pull/39165) +* [[`f799c4617e`](https://github.com/nodejs/node/commit/f799c4617e)] - **doc**: use `await` in filehandle.truncate() snippet (RA80533) [#38939](https://github.com/nodejs/node/pull/38939) +* [[`e7f3f0d778`](https://github.com/nodejs/node/commit/e7f3f0d778)] - **doc**: update abort signal in fs promise api example (Moritz Kneilmann) [#38669](https://github.com/nodejs/node/pull/38669) +* [[`a44219d979`](https://github.com/nodejs/node/commit/a44219d979)] - **doc**: add documentation for fs.WriteStream.close() (Hitesh Sharma) [#38610](https://github.com/nodejs/node/pull/38610) +* [[`c3ae1cfbab`](https://github.com/nodejs/node/commit/c3ae1cfbab)] - **doc**: fix fs.openSync() signature (Luigi Pinca) [#38591](https://github.com/nodejs/node/pull/38591) +* [[`23a8aed3f9`](https://github.com/nodejs/node/commit/23a8aed3f9)] - **doc**: typo stats() should be stat(); clarity (Bryan Field) [#38541](https://github.com/nodejs/node/pull/38541) +* [[`9fe46ea0fd`](https://github.com/nodejs/node/commit/9fe46ea0fd)] - **doc**: fix broken AHAFS link in fs doc (Rich Trott) [#38534](https://github.com/nodejs/node/pull/38534) +* [[`7a92c3cfd4`](https://github.com/nodejs/node/commit/7a92c3cfd4)] - **doc**: clarify that fs.Dir async iterator closes automatically (James M Snell) [#38438](https://github.com/nodejs/node/pull/38438) +* [[`b819848487`](https://github.com/nodejs/node/commit/b819848487)] - **doc**: remove superfluous await from fsPromises.readdir example (Michael Rommel) [#38293](https://github.com/nodejs/node/pull/38293) +* [[`9fa7dcf9df`](https://github.com/nodejs/node/commit/9fa7dcf9df)] - **doc**: fix missing backtick in fs.md (Siddharth) [#38260](https://github.com/nodejs/node/pull/38260) +* [[`4cf4ee99dc`](https://github.com/nodejs/node/commit/4cf4ee99dc)] - **doc**: fix typo in fs.md (Antoine du Hamel) [#38100](https://github.com/nodejs/node/pull/38100) +* [[`f9d36cbf42`](https://github.com/nodejs/node/commit/f9d36cbf42)] - **doc**: fix typos in /doc/api/fs.md (Merlin Luntke) [#37557](https://github.com/nodejs/node/pull/37557) +* [[`bbcc2171c5`](https://github.com/nodejs/node/commit/bbcc2171c5)] - **doc**: fix typo "director" instead of "directory" (humanwebpl) [#37523](https://github.com/nodejs/node/pull/37523) +* [[`67ac6b3b66`](https://github.com/nodejs/node/commit/67ac6b3b66)] - **doc**: fix "referred to" in fs docs (Tobias Nießen) [#37388](https://github.com/nodejs/node/pull/37388) +* [[`3b9fa2412f`](https://github.com/nodejs/node/commit/3b9fa2412f)] - **doc**: change "Version 4 UUID" to "version 4 UUID" (Tobias Nießen) [#39682](https://github.com/nodejs/node/pull/39682) +* [[`3d26572773`](https://github.com/nodejs/node/commit/3d26572773)] - **doc**: add point to ask H1 reporter about credit (Daniel Bevenius) [#39585](https://github.com/nodejs/node/pull/39585) +* [[`469190d13c`](https://github.com/nodejs/node/commit/469190d13c)] - **doc**: move util.toUSVString() outside of deprecated group (Luigi Pinca) [#39840](https://github.com/nodejs/node/pull/39840) +* [[`f509788850`](https://github.com/nodejs/node/commit/f509788850)] - **doc**: fix lint error in modules.md (Rich Trott) [#37811](https://github.com/nodejs/node/pull/37811) +* [[`a7833c7ce6`](https://github.com/nodejs/node/commit/a7833c7ce6)] - **doc**: refactor signal info in child\_process.md (Darshan Sen) [#37528](https://github.com/nodejs/node/pull/37528) +* [[`f5b2fe1204`](https://github.com/nodejs/node/commit/f5b2fe1204)] - **doc**: change lang info string in fs JS snippets (Antoine du Hamel) [#37605](https://github.com/nodejs/node/pull/37605) +* [[`307c1d817f`](https://github.com/nodejs/node/commit/307c1d817f)] - **doc**: refactor fs docs structure (Michaël Zasso) [#37170](https://github.com/nodejs/node/pull/37170) +* [[`298a16a2e7`](https://github.com/nodejs/node/commit/298a16a2e7)] - **doc**: update emitClose default for fs streams (Kevin Locke) [#36653](https://github.com/nodejs/node/pull/36653) +* [[`0c469b3f77`](https://github.com/nodejs/node/commit/0c469b3f77)] - **doc**: revise process.memoryUsage() text (Rich Trott) [#36757](https://github.com/nodejs/node/pull/36757) +* [[`1ebe7d70ea`](https://github.com/nodejs/node/commit/1ebe7d70ea)] - **doc**: fix punctuation in v8.md (Rich Trott) [#36192](https://github.com/nodejs/node/pull/36192) +* [[`591a05b637`](https://github.com/nodejs/node/commit/591a05b637)] - **doc**: add link for v8.takeCoverage() (Rich Trott) [#36135](https://github.com/nodejs/node/pull/36135) +* [[`e5fe3164f3`](https://github.com/nodejs/node/commit/e5fe3164f3)] - **doc**: add YAML metadata for process.memoryUsage.rss (Gerhard Stoebich) [#36781](https://github.com/nodejs/node/pull/36781) + +#### Other commits + +* [[`ab66dabbf2`](https://github.com/nodejs/node/commit/ab66dabbf2)] - **doc,meta**: update email addresses for misterdjules (Rich Trott) [#39433](https://github.com/nodejs/node/pull/39433) +* [[`c6ccd97fe2`](https://github.com/nodejs/node/commit/c6ccd97fe2)] - **doc,tools**: remove `checkLinks.mjs` (Antoine du Hamel) [#39206](https://github.com/nodejs/node/pull/39206) +* [[`8f8f528f08`](https://github.com/nodejs/node/commit/8f8f528f08)] - **meta**: add gyp as owner of gyp files and tools/gyp (Mary Marchini) [#34847](https://github.com/nodejs/node/pull/34847) +* [[`4b2eee5232`](https://github.com/nodejs/node/commit/4b2eee5232)] - **meta**: consolidate AUTHORS entries for ooHmartY (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`6916a6c2b0`](https://github.com/nodejs/node/commit/6916a6c2b0)] - **meta**: consolidate AUTHORS entries for homosaur (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`b65a635c8a`](https://github.com/nodejs/node/commit/b65a635c8a)] - **meta**: consolidate AUTHORS entries for Ayase-252 (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`e86b59cf4c`](https://github.com/nodejs/node/commit/e86b59cf4c)] - **meta**: consolidate AUTHORS entries for robin-drexler (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`1eda8442bd`](https://github.com/nodejs/node/commit/1eda8442bd)] - **meta**: consolidate AUTHORS entries for samshull (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`cd67d86572`](https://github.com/nodejs/node/commit/cd67d86572)] - **meta**: update AUTHORS (Rich Trott) [#39705](https://github.com/nodejs/node/pull/39705) +* [[`bb06282a9e`](https://github.com/nodejs/node/commit/bb06282a9e)] - **meta**: consolidate email addresses for MarshallOfSound (Rich Trott) [#39651](https://github.com/nodejs/node/pull/39651) +* [[`12fe34eae4`](https://github.com/nodejs/node/commit/12fe34eae4)] - **meta**: consolidate email addresses for tadjik1 (Rich Trott) [#39651](https://github.com/nodejs/node/pull/39651) +* [[`4301e252b4`](https://github.com/nodejs/node/commit/4301e252b4)] - **meta**: consolidate email addresses for szmarczak (Rich Trott) [#39651](https://github.com/nodejs/node/pull/39651) +* [[`3e8fc49730`](https://github.com/nodejs/node/commit/3e8fc49730)] - **meta**: update AUTHORS (Rich Trott) [#39636](https://github.com/nodejs/node/pull/39636) +* [[`60f41c34dd`](https://github.com/nodejs/node/commit/60f41c34dd)] - **meta**: simplify mailmap (Rich Trott) [#39612](https://github.com/nodejs/node/pull/39612) +* [[`fc9c680260`](https://github.com/nodejs/node/commit/fc9c680260)] - **meta**: consolidate emails for tadhgcreedon (Rich Trott) [#39611](https://github.com/nodejs/node/pull/39611) +* [[`d87fcf9959`](https://github.com/nodejs/node/commit/d87fcf9959)] - **meta**: consolidate emails for timcosta (Rich Trott) [#39611](https://github.com/nodejs/node/pull/39611) +* [[`fdbe97849b`](https://github.com/nodejs/node/commit/fdbe97849b)] - **meta**: consolidate emails for timruffles (Rich Trott) [#39611](https://github.com/nodejs/node/pull/39611) +* [[`b9f2ea92e9`](https://github.com/nodejs/node/commit/b9f2ea92e9)] - **meta**: update AUTHORS (Rich Trott) [#39629](https://github.com/nodejs/node/pull/39629) +* [[`472cf1520e`](https://github.com/nodejs/node/commit/472cf1520e)] - **meta**: add mailmap entry for ryzokuken (Rich Trott) [#39596](https://github.com/nodejs/node/pull/39596) +* [[`ae3f8b1eda`](https://github.com/nodejs/node/commit/ae3f8b1eda)] - **meta**: add mailmap entry for uttampawar (Rich Trott) [#39596](https://github.com/nodejs/node/pull/39596) +* [[`2a2d8ebd90`](https://github.com/nodejs/node/commit/2a2d8ebd90)] - **meta**: add mailmap entry for dmabupt (Rich Trott) [#39596](https://github.com/nodejs/node/pull/39596) +* [[`030036ec92`](https://github.com/nodejs/node/commit/030036ec92)] - **meta**: align README/.mailmap/AUTHORS email entries (Rich Trott) [#39505](https://github.com/nodejs/node/pull/39505) +* [[`fd2146be91`](https://github.com/nodejs/node/commit/fd2146be91)] - **meta**: add mailmap entry for garygsc (Rich Trott) [#39588](https://github.com/nodejs/node/pull/39588) +* [[`0833e2d9cb`](https://github.com/nodejs/node/commit/0833e2d9cb)] - **meta**: add mailmap entry for ttzztztz (Rich Trott) [#39588](https://github.com/nodejs/node/pull/39588) +* [[`1fbc19ee32`](https://github.com/nodejs/node/commit/1fbc19ee32)] - **meta**: update AUTHORS (Rich Trott) [#39587](https://github.com/nodejs/node/pull/39587) +* [[`2d6428665d`](https://github.com/nodejs/node/commit/2d6428665d)] - **meta**: update .mailmap to remove duplication in AUTHORS (Rich Trott) [#39561](https://github.com/nodejs/node/pull/39561) +* [[`6c4febd701`](https://github.com/nodejs/node/commit/6c4febd701)] - **meta**: add .mailmap entries to remove AUTHORS duplicates (Rich Trott) [#39560](https://github.com/nodejs/node/pull/39560) +* [[`1755f49a20`](https://github.com/nodejs/node/commit/1755f49a20)] - **meta**: add .mailmap entry to remove duplication in AUTHORS (Rich Trott) [#39559](https://github.com/nodejs/node/pull/39559) +* [[`fdcc5729d9`](https://github.com/nodejs/node/commit/fdcc5729d9)] - **meta**: update collaborator email in AUTHORS/.mailmap (Rich Trott) [#39521](https://github.com/nodejs/node/pull/39521) +* [[`27e9a44852`](https://github.com/nodejs/node/commit/27e9a44852)] - **meta**: update collaborator email in README (Rich Trott) [#39521](https://github.com/nodejs/node/pull/39521) +* [[`5e1c49ff0f`](https://github.com/nodejs/node/commit/5e1c49ff0f)] - **meta**: update collaborator email in AUTHORS/.mailmap (Rich Trott) [#39521](https://github.com/nodejs/node/pull/39521) +* [[`fbecae169e`](https://github.com/nodejs/node/commit/fbecae169e)] - **meta**: move gdams to emeritus (Rich Trott) [#39539](https://github.com/nodejs/node/pull/39539) +* [[`48ec33f1b8`](https://github.com/nodejs/node/commit/48ec33f1b8)] - **meta**: update collaborator email in README (Rich Trott) [#39510](https://github.com/nodejs/node/pull/39510) +* [[`f269df31ea`](https://github.com/nodejs/node/commit/f269df31ea)] - **meta**: remove unneeded .mailmap entry (Rich Trott) [#39512](https://github.com/nodejs/node/pull/39512) +* [[`b0c1aab28d`](https://github.com/nodejs/node/commit/b0c1aab28d)] - **meta**: update email address for collaborator (Rich Trott) [#39511](https://github.com/nodejs/node/pull/39511) +* [[`5f4935292a`](https://github.com/nodejs/node/commit/5f4935292a)] - **meta**: align collaborator name in .mailmap/AUTHORS with README (Rich Trott) [#39489](https://github.com/nodejs/node/pull/39489) +* [[`1b2078c912`](https://github.com/nodejs/node/commit/1b2078c912)] - **meta**: align email address in README/.mailmap/AUTHORS (Rich Trott) [#39503](https://github.com/nodejs/node/pull/39503) +* [[`2f816bf24b`](https://github.com/nodejs/node/commit/2f816bf24b)] - **meta**: revise .mailmap for README consistency (Rich Trott) [#39457](https://github.com/nodejs/node/pull/39457) +* [[`1302a911f5`](https://github.com/nodejs/node/commit/1302a911f5)] - **meta**: alphabetize .mailmap file (Rich Trott) [#39434](https://github.com/nodejs/node/pull/39434) +* [[`55322c0260`](https://github.com/nodejs/node/commit/55322c0260)] - **meta**: align collaborator email in .mailmap/AUTHORS with README (Rich Trott) [#39478](https://github.com/nodejs/node/pull/39478) +* [[`83f5cc0bd4`](https://github.com/nodejs/node/commit/83f5cc0bd4)] - **meta**: update AUTHORS (Rich Trott) [#39461](https://github.com/nodejs/node/pull/39461) +* [[`69b56a3fe9`](https://github.com/nodejs/node/commit/69b56a3fe9)] - **meta**: add .mailmap entry for new email for existing contributor (Rich Trott) [#39431](https://github.com/nodejs/node/pull/39431) +* [[`2f325c946f`](https://github.com/nodejs/node/commit/2f325c946f)] - **meta**: use form schema for bug report template (Michaël Zasso) [#39194](https://github.com/nodejs/node/pull/39194) +* [[`9766a99dd2`](https://github.com/nodejs/node/commit/9766a99dd2)] - **meta**: add @nodejs/actions as CODEOWNERS (Mary Marchini) [#39119](https://github.com/nodejs/node/pull/39119) +* [[`007f9a0e36`](https://github.com/nodejs/node/commit/007f9a0e36)] - **test**: fix test-vm-memleak for high baseline platforms (Rich Trott) [#38062](https://github.com/nodejs/node/pull/38062) +* [[`0fabd8e755`](https://github.com/nodejs/node/commit/0fabd8e755)] - **test**: fix flaky test-vm-memleak (Rich Trott) [#38054](https://github.com/nodejs/node/pull/38054) +* [[`64fb928ec7`](https://github.com/nodejs/node/commit/64fb928ec7)] - **test**: fix flaky test-child-process-exec-abortcontroller-promisified (Antoine du Hamel) [#37572](https://github.com/nodejs/node/pull/37572) +* [[`e660892f1a`](https://github.com/nodejs/node/commit/e660892f1a)] - **test**: use simplfied validator (voltrexmaster) [#39753](https://github.com/nodejs/node/pull/39753) +* [[`779417f97e`](https://github.com/nodejs/node/commit/779417f97e)] - **test**: use template to concatenate string (Himadri Ganguly) [#39621](https://github.com/nodejs/node/pull/39621) +* [[`a61076042d`](https://github.com/nodejs/node/commit/a61076042d)] - **test**: deflake test-http2-buffersize (Luigi Pinca) [#39591](https://github.com/nodejs/node/pull/39591) +* [[`68ef265c39`](https://github.com/nodejs/node/commit/68ef265c39)] - **test**: convert anonymous function to arrow function (Himadri Ganguly) [#39604](https://github.com/nodejs/node/pull/39604) +* [[`78db43c9e7`](https://github.com/nodejs/node/commit/78db43c9e7)] - **test**: add test-debugger-breakpoint-exists (Rich Trott) [#39570](https://github.com/nodejs/node/pull/39570) +* [[`5696bcf715`](https://github.com/nodejs/node/commit/5696bcf715)] - **test**: fix WASI link test (Richard Lau) [#39485](https://github.com/nodejs/node/pull/39485) +* [[`0b564a6d40`](https://github.com/nodejs/node/commit/0b564a6d40)] - **test**: add test for WebSocket secret verification in debugger (Rich Trott) [#39357](https://github.com/nodejs/node/pull/39357) +* [[`831f266d6f`](https://github.com/nodejs/node/commit/831f266d6f)] - **test**: put common lint exceptions into config file (Rich Trott) [#39358](https://github.com/nodejs/node/pull/39358) +* [[`d8066f5325`](https://github.com/nodejs/node/commit/d8066f5325)] - **test**: mark test-domain-error-types flaky (James M Snell) [#39369](https://github.com/nodejs/node/pull/39369) +* [[`c915a1bd04`](https://github.com/nodejs/node/commit/c915a1bd04)] - **test**: remove eslint-disable comment from fixture file (Rich Trott) [#39320](https://github.com/nodejs/node/pull/39320) +* [[`1eb8307cc5`](https://github.com/nodejs/node/commit/1eb8307cc5)] - **test**: move debugger test case to parallel (Rich Trott) [#39300](https://github.com/nodejs/node/pull/39300) +* [[`546202364c`](https://github.com/nodejs/node/commit/546202364c)] - **test**: remove debugger workaround for AIX (Rich Trott) [#39296](https://github.com/nodejs/node/pull/39296) +* [[`e12164e88d`](https://github.com/nodejs/node/commit/e12164e88d)] - **test**: fix test-debugger-heap-profiler for workers (Richard Lau) [#39687](https://github.com/nodejs/node/pull/39687) +* [[`a45bf2f1a0`](https://github.com/nodejs/node/commit/a45bf2f1a0)] - **test**: use common.PORT instead of hardcoded port number (Rich Trott) [#39298](https://github.com/nodejs/node/pull/39298) +* [[`9b737ebd4b`](https://github.com/nodejs/node/commit/9b737ebd4b)] - **test**: add test for debugger restart message issue (Rich Trott) [#39273](https://github.com/nodejs/node/pull/39273) +* [[`68523894ab`](https://github.com/nodejs/node/commit/68523894ab)] - **test**: remove workaround code in debugger test (Rich Trott) [#39238](https://github.com/nodejs/node/pull/39238) +* [[`2cd414147b`](https://github.com/nodejs/node/commit/2cd414147b)] - **test**: move test-debugger-address to parallel (Rich Trott) [#39236](https://github.com/nodejs/node/pull/39236) +* [[`a2e4020e4b`](https://github.com/nodejs/node/commit/a2e4020e4b)] - **test**: prepare for consistent comma-dangle lint rule (Rich Trott) [#37930](https://github.com/nodejs/node/pull/37930) +* [[`62b439e04d`](https://github.com/nodejs/node/commit/62b439e04d)] - **test**: replace "inspector-cli" with "debugger" (Rich Trott) [#39156](https://github.com/nodejs/node/pull/39156) +* [[`f13a302d23`](https://github.com/nodejs/node/commit/f13a302d23)] - **test**: improve coverage of stream.Readable (Rongjian Zhang) [#38702](https://github.com/nodejs/node/pull/38702) +* [[`f3d2e6ac29`](https://github.com/nodejs/node/commit/f3d2e6ac29)] - **test**: add tests for `bound apply` variants of varargs `primordials` (ExE Boss) [#37005](https://github.com/nodejs/node/pull/37005) +* [[`f70fd00fb3`](https://github.com/nodejs/node/commit/f70fd00fb3)] - **test**: use localhost test instead of connecting to remote (Adam Majer) [#39011](https://github.com/nodejs/node/pull/39011) +* [[`c4ff5e4a7e`](https://github.com/nodejs/node/commit/c4ff5e4a7e)] - **test**: update error message keywords (leeight) [#39826](https://github.com/nodejs/node/pull/39826) +* [[`922dacebfb`](https://github.com/nodejs/node/commit/922dacebfb)] - **test**: increase coverage for Blob (ZiJian Liu) [#38515](https://github.com/nodejs/node/pull/38515) +* [[`c6ab19895d`](https://github.com/nodejs/node/commit/c6ab19895d)] - **test**: account for OOM risks in heapsnapshot-near-heap-limit tests (Joyee Cheung) [#37761](https://github.com/nodejs/node/pull/37761) +* [[`971d5be57c`](https://github.com/nodejs/node/commit/971d5be57c)] - **test**: split heap snapshot limit tests (Rich Trott) [#37189](https://github.com/nodejs/node/pull/37189) +* [[`815d59a7b3`](https://github.com/nodejs/node/commit/815d59a7b3)] - **test**: fix test-memory-usage.js for IBMi (Rich Trott) [#36758](https://github.com/nodejs/node/pull/36758) +* [[`aa5309c33f`](https://github.com/nodejs/node/commit/aa5309c33f)] - **test**: increase coverage for net/blocklist (Zijian Liu) [#36405](https://github.com/nodejs/node/pull/36405) +* [[`f3be3ec417`](https://github.com/nodejs/node/commit/f3be3ec417)] - **test**: check mustCall errors in test-fs-read-type (Tobias Nießen) [#36914](https://github.com/nodejs/node/pull/36914) +* [[`b643fe7edf`](https://github.com/nodejs/node/commit/b643fe7edf)] - **test**: use faster variant for rss (Pooja D P) [#36839](https://github.com/nodejs/node/pull/36839) +* [[`d4362db111`](https://github.com/nodejs/node/commit/d4362db111)] - **test**: use faster variant for rss in test-crypto-dh-leak (Pooja D P) [#36766](https://github.com/nodejs/node/pull/36766) +* [[`3094ef967a`](https://github.com/nodejs/node/commit/3094ef967a)] - **test**: use faster variant for rss in test-vm-memleak.js (Pooja D P) [#36769](https://github.com/nodejs/node/pull/36769) +* [[`ff7879b41e`](https://github.com/nodejs/node/commit/ff7879b41e)] - **test**: use faster variant for rss test-memoryusage-emfile (Pooja D P) [#36768](https://github.com/nodejs/node/pull/36768) +* [[`d39200c7f4`](https://github.com/nodejs/node/commit/d39200c7f4)] - **tools**: make utils.SearchFiles Python2-compatible (Michaël Zasso) [#40020](https://github.com/nodejs/node/pull/40020) +* [[`55493f2011`](https://github.com/nodejs/node/commit/55493f2011)] - **tools**: update workflow to open a pull request (Rich Trott) [#39825](https://github.com/nodejs/node/pull/39825) +* [[`417a3ac474`](https://github.com/nodejs/node/commit/417a3ac474)] - **tools**: use find-inactive-collaborators to modify README.md (Rich Trott) [#39825](https://github.com/nodejs/node/pull/39825) +* [[`e9b1a006a1`](https://github.com/nodejs/node/commit/e9b1a006a1)] - **tools**: fix markdown linting (Rich Trott) [#39832](https://github.com/nodejs/node/pull/39832) +* [[`67f1bff657`](https://github.com/nodejs/node/commit/67f1bff657)] - **tools**: update markdown linter dependencies and move to ESM (Antoine du Hamel) [#39801](https://github.com/nodejs/node/pull/39801) +* [[`67c5921e8a`](https://github.com/nodejs/node/commit/67c5921e8a)] - **tools**: update rollup to latest version in markdown linter (Rich Trott) [#39797](https://github.com/nodejs/node/pull/39797) +* [[`64714b429a`](https://github.com/nodejs/node/commit/64714b429a)] - **tools**: update markdown lint dependencies (Rich Trott) [#39770](https://github.com/nodejs/node/pull/39770) +* [[`de9461168a`](https://github.com/nodejs/node/commit/de9461168a)] - **tools**: bump remark-preset-lint-node to 3.0.0 (Rich Trott) [#39755](https://github.com/nodejs/node/pull/39755) +* [[`dfdf6c7317`](https://github.com/nodejs/node/commit/dfdf6c7317)] - **tools**: update markdown linter rules (Rich Trott) [#38384](https://github.com/nodejs/node/pull/38384) +* [[`f8fee449f7`](https://github.com/nodejs/node/commit/f8fee449f7)] - **tools**: update path-parse in markdown linter package-lock file (Rich Trott) [#39729](https://github.com/nodejs/node/pull/39729) +* [[`a338c0e07b`](https://github.com/nodejs/node/commit/a338c0e07b)] - **tools**: fix more build warnings in inspector\_protocol (Richard Lau) [#39725](https://github.com/nodejs/node/pull/39725) +* [[`09630cf199`](https://github.com/nodejs/node/commit/09630cf199)] - **tools**: cherry-pick ffb34b6d5dbf0 (Darshan Sen) [#39725](https://github.com/nodejs/node/pull/39725) +* [[`26a067e33e`](https://github.com/nodejs/node/commit/26a067e33e)] - **tools**: update inspector\_protocol to e8ba1a7 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`9847d58feb`](https://github.com/nodejs/node/commit/9847d58feb)] - **tools**: update inspector\_protocol to 39ca567 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`6870bb7505`](https://github.com/nodejs/node/commit/6870bb7505)] - **tools**: update inspector\_protocol to 97d3146 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`383fa01e97`](https://github.com/nodejs/node/commit/383fa01e97)] - ***Revert*** "**tools**: fix compiler warning in inspector\_protocol" (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`b95a759c86`](https://github.com/nodejs/node/commit/b95a759c86)] - **tools**: update inspector\_protocol to a53e96d31a2755eb16ca37 (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`ad39687422`](https://github.com/nodejs/node/commit/ad39687422)] - **tools**: update inspector\_protocol to fe0467fd105a (Rich Trott) [#39694](https://github.com/nodejs/node/pull/39694) +* [[`78de83cc74`](https://github.com/nodejs/node/commit/78de83cc74)] - **tools**: improve error detection in find-inactive-collaborators (Rich Trott) [#39617](https://github.com/nodejs/node/pull/39617) +* [[`a5152a0875`](https://github.com/nodejs/node/commit/a5152a0875)] - **tools**: flag README/mailmap mismatches in find-inactive-collaborators (Rich Trott) [#39477](https://github.com/nodejs/node/pull/39477) +* [[`87c5332f89`](https://github.com/nodejs/node/commit/87c5332f89)] - **tools**: use mailmap for find-inactive-collaborators (Rich Trott) [#39432](https://github.com/nodejs/node/pull/39432) +* [[`f75224f1ce`](https://github.com/nodejs/node/commit/f75224f1ce)] - **tools**: email matchin is case insensitive for .mailmap (Rich Trott) [#39430](https://github.com/nodejs/node/pull/39430) +* [[`dfb77a581f`](https://github.com/nodejs/node/commit/dfb77a581f)] - **tools**: make internal link checker more robust (Rich Trott) [#39429](https://github.com/nodejs/node/pull/39429) +* [[`d2c0da20a0`](https://github.com/nodejs/node/commit/d2c0da20a0)] - **tools**: added remark-frontmatter (Ben Halverson) [#38717](https://github.com/nodejs/node/pull/38717) +* [[`cec04821aa`](https://github.com/nodejs/node/commit/cec04821aa)] - **tools**: change commit fetch limiting in find-inactive-collaborators (Rich Trott) [#39362](https://github.com/nodejs/node/pull/39362) +* [[`d948148498`](https://github.com/nodejs/node/commit/d948148498)] - **tools**: use Node.js 16.x for GitHub workflow (Rich Trott) [#39362](https://github.com/nodejs/node/pull/39362) +* [[`edc5791b5a`](https://github.com/nodejs/node/commit/edc5791b5a)] - **tools**: add GitHub Action to run find-inactive-collaborators.mjs (Rich Trott) [#39335](https://github.com/nodejs/node/pull/39335) +* [[`d86d37bc9e`](https://github.com/nodejs/node/commit/d86d37bc9e)] - **tools**: relax max-len lint rule for template strings (Rich Trott) [#38097](https://github.com/nodejs/node/pull/38097) +* [[`f467e2a0c5`](https://github.com/nodejs/node/commit/f467e2a0c5)] - **tools**: pass bot token to node-pr-labeler (Michaël Zasso) [#39271](https://github.com/nodejs/node/pull/39271) +* [[`61ec594609`](https://github.com/nodejs/node/commit/61ec594609)] - **tools**: add find-inactive-collaborators.js (Rich Trott) [#39262](https://github.com/nodejs/node/pull/39262) +* [[`ff0ca11521`](https://github.com/nodejs/node/commit/ff0ca11521)] - **tools**: update path-parse to 1.0.7 (Rich Trott) [#39232](https://github.com/nodejs/node/pull/39232) +* [[`b8fb75121b`](https://github.com/nodejs/node/commit/b8fb75121b)] - **tools**: remove unused `lint-pr-commit-message.sh` (Richard Lau) [#39120](https://github.com/nodejs/node/pull/39120) +* [[`e7761b627f`](https://github.com/nodejs/node/commit/e7761b627f)] - **tools**: apply consistent comma-dangle lint rule (Rich Trott) [#37930](https://github.com/nodejs/node/pull/37930) +* [[`315eba7789`](https://github.com/nodejs/node/commit/315eba7789)] - **tools**: make comma-dangle ESLint rule more stringent … (Rich Trott) [#37088](https://github.com/nodejs/node/pull/37088) +* [[`3ecfe9d7ee`](https://github.com/nodejs/node/commit/3ecfe9d7ee)] - **tools**: update remark-preset-lint-node to 2.4.1 (Rich Trott) [#39201](https://github.com/nodejs/node/pull/39201) +* [[`70e527c0c7`](https://github.com/nodejs/node/commit/70e527c0c7)] - **tools**: upgrade `highlight.js` to version 11.0.1 (Antoine du Hamel) [#39032](https://github.com/nodejs/node/pull/39032) +* [[`7b2bebba7a`](https://github.com/nodejs/node/commit/7b2bebba7a)] - **tools**: add support for import assertions in linter (Antoine du Hamel) [#39924](https://github.com/nodejs/node/pull/39924) +* [[`1353a6e22f`](https://github.com/nodejs/node/commit/1353a6e22f)] - **tools**: update ESLint to 7.32.0 (Luigi Pinca) [#39602](https://github.com/nodejs/node/pull/39602) +* [[`509f26549c`](https://github.com/nodejs/node/commit/509f26549c)] - **tools**: update ESLint to 7.31.0 (Colin Ihrig) [#39424](https://github.com/nodejs/node/pull/39424) +* [[`f0e0c8f720`](https://github.com/nodejs/node/commit/f0e0c8f720)] - **tools**: update ESLint to 7.30.0 (Colin Ihrig) [#39242](https://github.com/nodejs/node/pull/39242) +* [[`6540c271e4`](https://github.com/nodejs/node/commit/6540c271e4)] - **tools**: update @babel/eslint-parser to 7.14.7 (Rich Trott) [#39160](https://github.com/nodejs/node/pull/39160) +* [[`d7e2318e74`](https://github.com/nodejs/node/commit/d7e2318e74)] - **tools**: add ESLint rule no-array-destructuring (Antoine du Hamel) [#36818](https://github.com/nodejs/node/pull/36818) +* [[`87e5429334`](https://github.com/nodejs/node/commit/87e5429334)] - **tools,doc**: fix error message for unrecognized type (Antoine du Hamel) [#39221](https://github.com/nodejs/node/pull/39221) +* [[`f206af679c`](https://github.com/nodejs/node/commit/f206af679c)] - **typings**: add a few JSDoc typings for the net lib module (nerdthatnoonelikes) [#38953](https://github.com/nodejs/node/pull/38953) +* [[`d458cd7e2b`](https://github.com/nodejs/node/commit/d458cd7e2b)] - **typings**: add JSDoc typings for timers (Voltrex) [#38834](https://github.com/nodejs/node/pull/38834) + ## 2021-08-31, Version 14.17.6 'Fermium' (LTS), @MylesBorins diff --git a/doc/changelogs/CHANGELOG_V15.md b/doc/changelogs/CHANGELOG_V15.md index 1855da132b18f6..d394bf08fc0a30 100644 --- a/doc/changelogs/CHANGELOG_V15.md +++ b/doc/changelogs/CHANGELOG_V15.md @@ -1,8 +1,6 @@ # Node.js 15 ChangeLog - - - + diff --git a/doc/changelogs/CHANGELOG_V16.md b/doc/changelogs/CHANGELOG_V16.md index 128467175d01df..266f4893b3bd2a 100644 --- a/doc/changelogs/CHANGELOG_V16.md +++ b/doc/changelogs/CHANGELOG_V16.md @@ -1,8 +1,6 @@ # Node.js 16 ChangeLog - - - +
@@ -10,6 +8,7 @@ '); - }, - - tableData() { - /** @type {number} */ - // @ts-expect-error Custom. - const column = this.getData('tableColumn'); // @ts-expect-error Custom. - - if (column in this.getData('tableAlign')) { - this.tag(''); - this.setData('tableColumn', column + 1); - } else { - // Stop capturing. - this.resume(); - } - }, - - tableHead() { - this.lineEndingIfNeeded(); - this.tag(''); - this.setData('slurpOneLineEnding', true); // Slurp the line ending from the delimiter row. - }, - - tableHeader() { - this.tag(''); // @ts-expect-error Custom. - - this.setData('tableColumn', this.getData('tableColumn') + 1); - }, - - tableRow() { - /** @type {Align[]} */ - // @ts-expect-error Custom. - const align = this.getData('tableAlign'); - /** @type {number} */ - // @ts-expect-error Custom. - - let column = this.getData('tableColumn'); - - while (column < align.length) { - this.lineEndingIfNeeded(); // @ts-expect-error `null` is fine as an index. - - this.tag(''); - column++; - } - - this.setData('tableColumn', column); - this.lineEndingIfNeeded(); - this.tag(''); - } - } -}; -/** - * @param {string} $0 - * @param {string} $1 - * @returns {string} - */ - -function replace$1($0, $1) { - // Pipes work, backslashes don’t (but can’t escape pipes). - return $1 === '|' ? $1 : $0 -} - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Token} Token - */ - -/** @type {Extension} */ -const gfmTable = { - flow: { - null: { - tokenize: tokenizeTable, - resolve: resolveTable - } - } -}; -const setextUnderlineMini = { - tokenize: tokenizeSetextUnderlineMini, - partial: true -}; -const nextPrefixedOrBlank = { - tokenize: tokenizeNextPrefixedOrBlank, - partial: true -}; -/** @type {Resolver} */ - -function resolveTable(events, context) { - let index = -1; - /** @type {Token} */ - - let token; - /** @type {boolean|undefined} */ - - let inHead; - /** @type {boolean|undefined} */ - - let inDelimiterRow; - /** @type {boolean|undefined} */ - - let inRow; - /** @type {Token} */ - - let cell; - /** @type {Token} */ - - let content; - /** @type {Token} */ - - let text; - /** @type {number|undefined} */ - - let contentStart; - /** @type {number|undefined} */ - - let contentEnd; - /** @type {number|undefined} */ - - let cellStart; - - while (++index < events.length) { - token = events[index][1]; - - if (inRow) { - if (token.type === 'temporaryTableCellContent') { - contentStart = contentStart || index; - contentEnd = index; - } - - if ( - // Combine separate content parts into one. - (token.type === 'tableCellDivider' || token.type === 'tableRow') && - contentEnd - ) { - content = { - type: 'tableContent', - // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - start: events[contentStart][1].start, - end: events[contentEnd][1].end - }; - text = { - type: 'chunkText', - start: content.start, - end: content.end, - // @ts-expect-error It’s fine. - contentType: 'text' - }; - events.splice( - // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - contentStart, // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - contentEnd - contentStart + 1, - ['enter', content, context], - ['enter', text, context], - ['exit', text, context], - ['exit', content, context] - ); // @ts-expect-error `contentStart` is defined if `contentEnd` is too. - - index -= contentEnd - contentStart - 3; - contentStart = undefined; - contentEnd = undefined; - } - } - - if ( - events[index][0] === 'exit' && - cellStart && - cellStart + 1 < index && - (token.type === 'tableCellDivider' || - (token.type === 'tableRow' && - (cellStart + 3 < index || - events[cellStart][1].type !== 'whitespace'))) - ) { - cell = { - type: inDelimiterRow - ? 'tableDelimiter' - : inHead - ? 'tableHeader' - : 'tableData', - start: events[cellStart][1].start, - end: events[index][1].end - }; - events.splice(index + (token.type === 'tableCellDivider' ? 1 : 0), 0, [ - 'exit', - cell, - context - ]); - events.splice(cellStart, 0, ['enter', cell, context]); - index += 2; - cellStart = index + 1; - } - - if (token.type === 'tableRow') { - inRow = events[index][0] === 'enter'; - - if (inRow) { - cellStart = index + 1; - } - } - - if (token.type === 'tableDelimiterRow') { - inDelimiterRow = events[index][0] === 'enter'; - - if (inDelimiterRow) { - cellStart = index + 1; - } - } - - if (token.type === 'tableHead') { - inHead = events[index][0] === 'enter'; - } - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeTable(effects, ok, nok) { - const self = this; - /** @type {Align[]} */ - - const align = []; - let tableHeaderCount = 0; - /** @type {boolean|undefined} */ - - let seenDelimiter; - /** @type {boolean|undefined} */ - - let hasDash; - return start - /** @type {State} */ - - function start(code) { - // @ts-expect-error Custom. - effects.enter('table')._align = align; - effects.enter('tableHead'); - effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. - - if (code === 124) { - return cellDividerHead(code) - } - - tableHeaderCount++; - effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. - - return inCellContentHead(code) - } - /** @type {State} */ - - function cellDividerHead(code) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - seenDelimiter = true; - return cellBreakHead - } - /** @type {State} */ - - function cellBreakHead(code) { - if (code === null || markdownLineEnding(code)) { - return atRowEndHead(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceHead - } - - if (seenDelimiter) { - seenDelimiter = undefined; - tableHeaderCount++; - } - - if (code === 124) { - return cellDividerHead(code) - } // Anything else is cell content. - - effects.enter('temporaryTableCellContent'); - return inCellContentHead(code) - } - /** @type {State} */ - - function inWhitespaceHead(code) { - if (markdownSpace(code)) { - effects.consume(code); - return inWhitespaceHead - } - - effects.exit('whitespace'); - return cellBreakHead(code) - } - /** @type {State} */ - - function inCellContentHead(code) { - // EOF, whitespace, pipe - if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { - effects.exit('temporaryTableCellContent'); - return cellBreakHead(code) - } - - effects.consume(code); - return code === 92 ? inCellContentEscapeHead : inCellContentHead - } - /** @type {State} */ - - function inCellContentEscapeHead(code) { - if (code === 92 || code === 124) { - effects.consume(code); - return inCellContentHead - } // Anything else. - - return inCellContentHead(code) - } - /** @type {State} */ - - function atRowEndHead(code) { - if (code === null) { - return nok(code) - } - - effects.exit('tableRow'); - effects.exit('tableHead'); - return effects.attempt( - { - tokenize: tokenizeRowEnd, - partial: true - }, - atDelimiterLineStart, - nok - )(code) - } - /** @type {State} */ - - function atDelimiterLineStart(code) { - // To do: is the lazy setext thing still needed? - return effects.check( - setextUnderlineMini, - nok, // Support an indent before the delimiter row. - factorySpace(effects, rowStartDelimiter, 'linePrefix', 4) - )(code) - } - /** @type {State} */ - - function rowStartDelimiter(code) { - // If there’s another space, or we’re at the EOL/EOF, exit. - if (code === null || markdownLineEndingOrSpace(code)) { - return nok(code) - } - - effects.enter('tableDelimiterRow'); - return atDelimiterRowBreak(code) - } - /** @type {State} */ - - function atDelimiterRowBreak(code) { - if (code === null || markdownLineEnding(code)) { - return rowEndDelimiter(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceDelimiter - } - - if (code === 45) { - effects.enter('tableDelimiterFiller'); - effects.consume(code); - hasDash = true; - align.push(null); - return inFillerDelimiter - } - - if (code === 58) { - effects.enter('tableDelimiterAlignment'); - effects.consume(code); - effects.exit('tableDelimiterAlignment'); - align.push('left'); - return afterLeftAlignment - } // If we start with a pipe, we open a cell marker. - - if (code === 124) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return atDelimiterRowBreak - } - - return nok(code) - } - /** @type {State} */ - - function inWhitespaceDelimiter(code) { - if (markdownSpace(code)) { - effects.consume(code); - return inWhitespaceDelimiter - } - - effects.exit('whitespace'); - return atDelimiterRowBreak(code) - } - /** @type {State} */ - - function inFillerDelimiter(code) { - if (code === 45) { - effects.consume(code); - return inFillerDelimiter - } - - effects.exit('tableDelimiterFiller'); - - if (code === 58) { - effects.enter('tableDelimiterAlignment'); - effects.consume(code); - effects.exit('tableDelimiterAlignment'); - align[align.length - 1] = - align[align.length - 1] === 'left' ? 'center' : 'right'; - return afterRightAlignment - } - - return atDelimiterRowBreak(code) - } - /** @type {State} */ - - function afterLeftAlignment(code) { - if (code === 45) { - effects.enter('tableDelimiterFiller'); - effects.consume(code); - hasDash = true; - return inFillerDelimiter - } // Anything else is not ok. - - return nok(code) - } - /** @type {State} */ - - function afterRightAlignment(code) { - if (code === null || markdownLineEnding(code)) { - return rowEndDelimiter(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceDelimiter - } // `|` - - if (code === 124) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return atDelimiterRowBreak - } - - return nok(code) - } - /** @type {State} */ - - function rowEndDelimiter(code) { - effects.exit('tableDelimiterRow'); // Exit if there was no dash at all, or if the header cell count is not the - // delimiter cell count. - - if (!hasDash || tableHeaderCount !== align.length) { - return nok(code) - } - - if (code === null) { - return tableClose(code) - } - - return effects.check( - nextPrefixedOrBlank, - tableClose, - effects.attempt( - { - tokenize: tokenizeRowEnd, - partial: true - }, - factorySpace(effects, bodyStart, 'linePrefix', 4), - tableClose - ) - )(code) - } - /** @type {State} */ - - function tableClose(code) { - effects.exit('table'); - return ok(code) - } - /** @type {State} */ - - function bodyStart(code) { - effects.enter('tableBody'); - return rowStartBody(code) - } - /** @type {State} */ - - function rowStartBody(code) { - effects.enter('tableRow'); // If we start with a pipe, we open a cell marker. - - if (code === 124) { - return cellDividerBody(code) - } - - effects.enter('temporaryTableCellContent'); // Can’t be space or eols at the start of a construct, so we’re in a cell. - - return inCellContentBody(code) - } - /** @type {State} */ - - function cellDividerBody(code) { - effects.enter('tableCellDivider'); - effects.consume(code); - effects.exit('tableCellDivider'); - return cellBreakBody - } - /** @type {State} */ - - function cellBreakBody(code) { - if (code === null || markdownLineEnding(code)) { - return atRowEndBody(code) - } - - if (markdownSpace(code)) { - effects.enter('whitespace'); - effects.consume(code); - return inWhitespaceBody - } // `|` - - if (code === 124) { - return cellDividerBody(code) - } // Anything else is cell content. - - effects.enter('temporaryTableCellContent'); - return inCellContentBody(code) - } - /** @type {State} */ - - function inWhitespaceBody(code) { - if (markdownSpace(code)) { - effects.consume(code); - return inWhitespaceBody - } - - effects.exit('whitespace'); - return cellBreakBody(code) - } - /** @type {State} */ - - function inCellContentBody(code) { - // EOF, whitespace, pipe - if (code === null || code === 124 || markdownLineEndingOrSpace(code)) { - effects.exit('temporaryTableCellContent'); - return cellBreakBody(code) - } - - effects.consume(code); - return code === 92 ? inCellContentEscapeBody : inCellContentBody - } - /** @type {State} */ - - function inCellContentEscapeBody(code) { - if (code === 92 || code === 124) { - effects.consume(code); - return inCellContentBody - } // Anything else. - - return inCellContentBody(code) - } - /** @type {State} */ - - function atRowEndBody(code) { - effects.exit('tableRow'); - - if (code === null) { - return tableBodyClose(code) - } - - return effects.check( - nextPrefixedOrBlank, - tableBodyClose, - effects.attempt( - { - tokenize: tokenizeRowEnd, - partial: true - }, - factorySpace(effects, rowStartBody, 'linePrefix', 4), - tableBodyClose - ) - )(code) - } - /** @type {State} */ - - function tableBodyClose(code) { - effects.exit('tableBody'); - return tableClose(code) - } - /** @type {Tokenizer} */ - - function tokenizeRowEnd(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return lineStart - } - /** @type {State} */ - - function lineStart(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) - } - } -} // Based on micromark, but that won’t work as we’re in a table, and that expects -// content. -// - -/** @type {Tokenizer} */ - -function tokenizeSetextUnderlineMini(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - if (code !== 45) { - return nok(code) - } - - effects.enter('setextUnderline'); - return sequence(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === 45) { - effects.consume(code); - return sequence - } - - return whitespace(code) - } - /** @type {State} */ - - function whitespace(code) { - if (code === null || markdownLineEnding(code)) { - return ok(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return whitespace - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeNextPrefixedOrBlank(effects, ok, nok) { - let size = 0; - return start - /** @type {State} */ - - function start(code) { - // This is a check, so we don’t care about tokens, but we open a bogus one - // so we’re valid. - effects.enter('check'); // EOL. - - effects.consume(code); - return whitespace - } - /** @type {State} */ - - function whitespace(code) { - if (code === -1 || code === 32) { - effects.consume(code); - size++; - return size === 4 ? ok : whitespace - } // EOF or whitespace - - if (code === null || markdownLineEndingOrSpace(code)) { - return ok(code) - } // Anything else. - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').CompileContext} CompileContext - */ - -/** - * An opening or closing tag, followed by a case-insensitive specific tag name, - * followed by HTML whitespace, a greater than, or a slash. - */ -const reFlow = - /<(\/?)(iframe|noembed|noframes|plaintext|script|style|title|textarea|xmp)(?=[\t\n\f\r />])/gi; - -/** - * As HTML (text) parses tags separately (and v. strictly), we don’t need to be - * global. - */ -const reText = new RegExp('^' + reFlow.source, 'i'); - -/** @type {HtmlExtension} */ -const gfmTagfilterHtml = { - exit: { - htmlFlowData(token) { - exitHtmlData.call(this, token, reFlow); - }, - htmlTextData(token) { - exitHtmlData.call(this, token, reText); - } - } -}; - -/** - * @this {CompileContext} - * @param {Token} token - * @param {RegExp} filter - */ -function exitHtmlData(token, filter) { - let value = this.sliceSerialize(token); - - if (this.options.allowDangerousHtml) { - value = value.replace(filter, '<$1$2'); - } - - this.raw(this.encode(value)); -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -/** @type {HtmlExtension} */ -const gfmTaskListItemHtml = { - enter: { - taskListCheck() { - this.tag(''); - }, - - taskListCheckValueChecked() { - this.tag('checked="" '); - } - } -}; - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Previous} Previous - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Code} Code - */ -const tasklistCheck = { - tokenize: tokenizeTasklistCheck -}; -const gfmTaskListItem = { - text: { - [91]: tasklistCheck - } -}; -/** @type {Tokenizer} */ - -function tokenizeTasklistCheck(effects, ok, nok) { - const self = this; - return open - /** @type {State} */ - - function open(code) { - if ( - // Exit if there’s stuff before. - self.previous !== null || // Exit if not in the first content that is the first child of a list - // item. - !self._gfmTasklistFirstContentOfListItem - ) { - return nok(code) - } - - effects.enter('taskListCheck'); - effects.enter('taskListCheckMarker'); - effects.consume(code); - effects.exit('taskListCheckMarker'); - return inside - } - /** @type {State} */ - - function inside(code) { - if (markdownSpace(code)) { - effects.enter('taskListCheckValueUnchecked'); - effects.consume(code); - effects.exit('taskListCheckValueUnchecked'); - return close - } - - if (code === 88 || code === 120) { - effects.enter('taskListCheckValueChecked'); - effects.consume(code); - effects.exit('taskListCheckValueChecked'); - return close - } - - return nok(code) - } - /** @type {State} */ - - function close(code) { - if (code === 93) { - effects.enter('taskListCheckMarker'); - effects.consume(code); - effects.exit('taskListCheckMarker'); - effects.exit('taskListCheck'); - return effects.check( - { - tokenize: spaceThenNonSpace - }, - ok, - nok - ) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function spaceThenNonSpace(effects, ok, nok) { - const self = this; - return factorySpace(effects, after, 'whitespace') - /** @type {State} */ - - function after(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'whitespace' && - code !== null && - !markdownLineEndingOrSpace(code) - ? ok(code) - : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - * @typedef {import('micromark-extension-gfm-strikethrough').Options} Options - */ - -/** - * Support GFM or markdown on github.com. - * - * @param {Options} [options] - * @returns {Extension} - */ -function gfm(options) { - return combineExtensions([ - gfmAutolinkLiteral, - gfmStrikethrough(options), - gfmTable, - gfmTaskListItem - ]) -} - -/** @type {HtmlExtension} */ -combineHtmlExtensions([ - gfmAutolinkLiteralHtml, - gfmStrikethroughHtml, - gfmTableHtml, - gfmTagfilterHtml, - gfmTaskListItemHtml -]); - -/** - * Get the total count of `character` in `value`. - * - * @param {any} value Content, coerced to string - * @param {string} character Single character to look for - * @return {number} Number of times `character` occurred in `value`. - */ -function ccount(value, character) { - var source = String(value); - var count = 0; - var index; - - if (typeof character !== 'string') { - throw new Error('Expected character') - } - - index = source.indexOf(character); - - while (index !== -1) { - count++; - index = source.indexOf(character, index + character.length); - } - - return count -} - -/** - * @typedef Options Configuration. - * @property {Test} [ignore] `unist-util-is` test used to assert parents - * - * @typedef {import('mdast').Root} Root - * @typedef {import('mdast').Content} Content - * @typedef {import('mdast').PhrasingContent} PhrasingContent - * @typedef {import('mdast').Text} Text - * @typedef {Content|Root} Node - * @typedef {Extract} Parent - * - * @typedef {import('unist-util-visit-parents').Test} Test - * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult - * - * @typedef RegExpMatchObject - * @property {number} index - * @property {string} input - * - * @typedef {string|RegExp} Find - * @typedef {string|ReplaceFunction} Replace - * - * @typedef {[Find, Replace]} FindAndReplaceTuple - * @typedef {Object.} FindAndReplaceSchema - * @typedef {Array.} FindAndReplaceList - * - * @typedef {[RegExp, ReplaceFunction]} Pair - * @typedef {Array.} Pairs - */ - -const own = {}.hasOwnProperty; - -/** - * @param tree mdast tree - * @param find Value to find and remove. When `string`, escaped and made into a global `RegExp` - * @param [replace] Value to insert. - * * When `string`, turned into a Text node. - * * When `Function`, called with the results of calling `RegExp.exec` as - * arguments, in which case it can return a single or a list of `Node`, - * a `string` (which is wrapped in a `Text` node), or `false` to not replace - * @param [options] Configuration. - */ -const findAndReplace = - /** - * @type {( - * ((tree: Node, find: Find, replace?: Replace, options?: Options) => Node) & - * ((tree: Node, schema: FindAndReplaceSchema|FindAndReplaceList, options?: Options) => Node) - * )} - **/ - ( - /** - * @param {Node} tree - * @param {Find|FindAndReplaceSchema|FindAndReplaceList} find - * @param {Replace|Options} [replace] - * @param {Options} [options] - */ - function (tree, find, replace, options) { - /** @type {Options|undefined} */ - let settings; - /** @type {FindAndReplaceSchema|FindAndReplaceList} */ - let schema; - - if (typeof find === 'string' || find instanceof RegExp) { - // @ts-expect-error don’t expect options twice. - schema = [[find, replace]]; - settings = options; - } else { - schema = find; - // @ts-expect-error don’t expect replace twice. - settings = replace; - } - - if (!settings) { - settings = {}; - } - - const ignored = convert(settings.ignore || []); - const pairs = toPairs(schema); - let pairIndex = -1; - - while (++pairIndex < pairs.length) { - visitParents(tree, 'text', visitor); - } - - return tree - - /** @type {import('unist-util-visit-parents').Visitor} */ - function visitor(node, parents) { - let index = -1; - /** @type {Parent|undefined} */ - let grandparent; - - while (++index < parents.length) { - const parent = /** @type {Parent} */ (parents[index]); - - if ( - ignored( - parent, - // @ts-expect-error mdast vs. unist parent. - grandparent ? grandparent.children.indexOf(parent) : undefined, - grandparent - ) - ) { - return - } - - grandparent = parent; - } - - if (grandparent) { - return handler(node, grandparent) - } - } - - /** - * @param {Text} node - * @param {Parent} parent - * @returns {VisitorResult} - */ - function handler(node, parent) { - const find = pairs[pairIndex][0]; - const replace = pairs[pairIndex][1]; - let start = 0; - // @ts-expect-error: TS is wrong, some of these children can be text. - let index = parent.children.indexOf(node); - /** @type {Array.} */ - let nodes = []; - /** @type {number|undefined} */ - let position; - - find.lastIndex = 0; - - let match = find.exec(node.value); - - while (match) { - position = match.index; - // @ts-expect-error this is perfectly fine, typescript. - let value = replace(...match, { - index: match.index, - input: match.input - }); - - if (typeof value === 'string') { - value = value.length > 0 ? {type: 'text', value} : undefined; - } - - if (value !== false) { - if (start !== position) { - nodes.push({ - type: 'text', - value: node.value.slice(start, position) - }); - } - - if (Array.isArray(value)) { - nodes.push(...value); - } else if (value) { - nodes.push(value); - } - - start = position + match[0].length; - } - - if (!find.global) { - break - } - - match = find.exec(node.value); - } - - if (position === undefined) { - nodes = [node]; - index--; - } else { - if (start < node.value.length) { - nodes.push({type: 'text', value: node.value.slice(start)}); - } - - parent.children.splice(index, 1, ...nodes); - } - - return index + nodes.length + 1 - } - } - ); - -/** - * @param {FindAndReplaceSchema|FindAndReplaceList} schema - * @returns {Pairs} - */ -function toPairs(schema) { - /** @type {Pairs} */ - const result = []; - - if (typeof schema !== 'object') { - throw new TypeError('Expected array or object as schema') - } - - if (Array.isArray(schema)) { - let index = -1; - - while (++index < schema.length) { - result.push([ - toExpression(schema[index][0]), - toFunction(schema[index][1]) - ]); - } - } else { - /** @type {string} */ - let key; - - for (key in schema) { - if (own.call(schema, key)) { - result.push([toExpression(key), toFunction(schema[key])]); - } - } - } - - return result -} - -/** - * @param {Find} find - * @returns {RegExp} - */ -function toExpression(find) { - return typeof find === 'string' ? new RegExp(escapeStringRegexp(find), 'g') : find -} - -/** - * @param {Replace} replace - * @returns {ReplaceFunction} - */ -function toFunction(replace) { - return typeof replace === 'function' ? replace : () => replace -} - -/** - * @typedef {import('mdast').Link} Link - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Transform} FromMarkdownTransform - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown/lib/types.js').Options} ToMarkdownExtension - * @typedef {import('mdast-util-find-and-replace').ReplaceFunction} ReplaceFunction - * @typedef {import('mdast-util-find-and-replace').RegExpMatchObject} RegExpMatchObject - * @typedef {import('mdast-util-find-and-replace').PhrasingContent} PhrasingContent - */ - -const inConstruct = 'phrasing'; -const notInConstruct = ['autolink', 'link', 'image', 'label']; - -/** @type {FromMarkdownExtension} */ -const gfmAutolinkLiteralFromMarkdown = { - transforms: [transformGfmAutolinkLiterals], - enter: { - literalAutolink: enterLiteralAutolink, - literalAutolinkEmail: enterLiteralAutolinkValue, - literalAutolinkHttp: enterLiteralAutolinkValue, - literalAutolinkWww: enterLiteralAutolinkValue - }, - exit: { - literalAutolink: exitLiteralAutolink, - literalAutolinkEmail: exitLiteralAutolinkEmail, - literalAutolinkHttp: exitLiteralAutolinkHttp, - literalAutolinkWww: exitLiteralAutolinkWww - } -}; - -/** @type {ToMarkdownExtension} */ -const gfmAutolinkLiteralToMarkdown = { - unsafe: [ - { - character: '@', - before: '[+\\-.\\w]', - after: '[\\-.\\w]', - inConstruct, - notInConstruct - }, - { - character: '.', - before: '[Ww]', - after: '[\\-.\\w]', - inConstruct, - notInConstruct - }, - {character: ':', before: '[ps]', after: '\\/', inConstruct, notInConstruct} - ] -}; - -/** @type {FromMarkdownHandle} */ -function enterLiteralAutolink(token) { - this.enter({type: 'link', title: null, url: '', children: []}, token); -} - -/** @type {FromMarkdownHandle} */ -function enterLiteralAutolinkValue(token) { - this.config.enter.autolinkProtocol.call(this, token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolinkHttp(token) { - this.config.exit.autolinkProtocol.call(this, token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolinkWww(token) { - this.config.exit.data.call(this, token); - const node = /** @type {Link} */ (this.stack[this.stack.length - 1]); - node.url = 'http://' + this.sliceSerialize(token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolinkEmail(token) { - this.config.exit.autolinkEmail.call(this, token); -} - -/** @type {FromMarkdownHandle} */ -function exitLiteralAutolink(token) { - this.exit(token); -} - -/** @type {FromMarkdownTransform} */ -function transformGfmAutolinkLiterals(tree) { - findAndReplace( - tree, - [ - [/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi, findUrl], - [/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/g, findEmail] - ], - {ignore: ['link', 'linkReference']} - ); -} - -/** - * @type {ReplaceFunction} - * @param {string} _ - * @param {string} protocol - * @param {string} domain - * @param {string} path - * @param {RegExpMatchObject} match - */ -// eslint-disable-next-line max-params -function findUrl(_, protocol, domain, path, match) { - let prefix = ''; - - // Not an expected previous character. - if (!previous(match)) { - return false - } - - // Treat `www` as part of the domain. - if (/^w/i.test(protocol)) { - domain = protocol + domain; - protocol = ''; - prefix = 'http://'; - } - - if (!isCorrectDomain(domain)) { - return false - } - - const parts = splitUrl(domain + path); - - if (!parts[0]) return false - - /** @type {PhrasingContent} */ - const result = { - type: 'link', - title: null, - url: prefix + protocol + parts[0], - children: [{type: 'text', value: protocol + parts[0]}] - }; - - if (parts[1]) { - return [result, {type: 'text', value: parts[1]}] - } - - return result -} - -/** - * @type {ReplaceFunction} - * @param {string} _ - * @param {string} atext - * @param {string} label - * @param {RegExpMatchObject} match - */ -function findEmail(_, atext, label, match) { - // Not an expected previous character. - if (!previous(match, true) || /[_-]$/.test(label)) { - return false - } - - return { - type: 'link', - title: null, - url: 'mailto:' + atext + '@' + label, - children: [{type: 'text', value: atext + '@' + label}] - } -} - -/** - * @param {string} domain - * @returns {boolean} - */ -function isCorrectDomain(domain) { - const parts = domain.split('.'); - - if ( - parts.length < 2 || - (parts[parts.length - 1] && - (/_/.test(parts[parts.length - 1]) || - !/[a-zA-Z\d]/.test(parts[parts.length - 1]))) || - (parts[parts.length - 2] && - (/_/.test(parts[parts.length - 2]) || - !/[a-zA-Z\d]/.test(parts[parts.length - 2]))) - ) { - return false - } - - return true -} - -/** - * @param {string} url - * @returns {[string, string|undefined]} - */ -function splitUrl(url) { - const trailExec = /[!"&'),.:;<>?\]}]+$/.exec(url); - /** @type {number} */ - let closingParenIndex; - /** @type {number} */ - let openingParens; - /** @type {number} */ - let closingParens; - /** @type {string|undefined} */ - let trail; - - if (trailExec) { - url = url.slice(0, trailExec.index); - trail = trailExec[0]; - closingParenIndex = trail.indexOf(')'); - openingParens = ccount(url, '('); - closingParens = ccount(url, ')'); - - while (closingParenIndex !== -1 && openingParens > closingParens) { - url += trail.slice(0, closingParenIndex + 1); - trail = trail.slice(closingParenIndex + 1); - closingParenIndex = trail.indexOf(')'); - closingParens++; - } - } - - return [url, trail] -} - -/** - * @param {RegExpMatchObject} match - * @param {boolean} [email=false] - * @returns {boolean} - */ -function previous(match, email) { - const code = match.input.charCodeAt(match.index - 1); - - return ( - (match.index === 0 || - unicodeWhitespace(code) || - unicodePunctuation(code)) && - (!email || code !== 47) - ) -} - -/** - * @typedef {import('mdast').Delete} Delete - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle - */ - -/** @type {FromMarkdownExtension} */ -const gfmStrikethroughFromMarkdown = { - canContainEols: ['delete'], - enter: {strikethrough: enterStrikethrough}, - exit: {strikethrough: exitStrikethrough} -}; - -/** @type {ToMarkdownExtension} */ -const gfmStrikethroughToMarkdown = { - unsafe: [{character: '~', inConstruct: 'phrasing'}], - handlers: {delete: handleDelete} -}; - -handleDelete.peek = peekDelete; - -/** @type {FromMarkdownHandle} */ -function enterStrikethrough(token) { - this.enter({type: 'delete', children: []}, token); -} - -/** @type {FromMarkdownHandle} */ -function exitStrikethrough(token) { - this.exit(token); -} - -/** - * @type {ToMarkdownHandle} - * @param {Delete} node - */ -function handleDelete(node, _, context) { - const exit = context.enter('emphasis'); - const value = containerPhrasing(node, context, {before: '~', after: '~'}); - exit(); - return '~~' + value + '~~' -} - -/** @type {ToMarkdownHandle} */ -function peekDelete() { - return '~' -} - -/** - * @typedef MarkdownTableOptions - * @property {string|null|Array.} [align] - * @property {boolean} [padding=true] - * @property {boolean} [delimiterStart=true] - * @property {boolean} [delimiterStart=true] - * @property {boolean} [delimiterEnd=true] - * @property {boolean} [alignDelimiters=true] - * @property {(value: string) => number} [stringLength] - */ - -/** - * Create a table from a matrix of strings. - * - * @param {Array.>} table - * @param {MarkdownTableOptions} [options] - * @returns {string} - */ -function markdownTable(table, options) { - const settings = options || {}; - const align = (settings.align || []).concat(); - const stringLength = settings.stringLength || defaultStringLength; - /** @type {number[]} Character codes as symbols for alignment per column. */ - const alignments = []; - let rowIndex = -1; - /** @type {string[][]} Cells per row. */ - const cellMatrix = []; - /** @type {number[][]} Sizes of each cell per row. */ - const sizeMatrix = []; - /** @type {number[]} */ - const longestCellByColumn = []; - let mostCellsPerRow = 0; - /** @type {number} */ - let columnIndex; - /** @type {string[]} Cells of current row */ - let row; - /** @type {number[]} Sizes of current row */ - let sizes; - /** @type {number} Sizes of current cell */ - let size; - /** @type {string} Current cell */ - let cell; - /** @type {string[]} Chunks of current line. */ - let line; - /** @type {string} */ - let before; - /** @type {string} */ - let after; - /** @type {number} */ - let code; - - // This is a superfluous loop if we don’t align delimiters, but otherwise we’d - // do superfluous work when aligning, so optimize for aligning. - while (++rowIndex < table.length) { - columnIndex = -1; - row = []; - sizes = []; - - if (table[rowIndex].length > mostCellsPerRow) { - mostCellsPerRow = table[rowIndex].length; - } - - while (++columnIndex < table[rowIndex].length) { - cell = serialize(table[rowIndex][columnIndex]); - - if (settings.alignDelimiters !== false) { - size = stringLength(cell); - sizes[columnIndex] = size; - - if ( - longestCellByColumn[columnIndex] === undefined || - size > longestCellByColumn[columnIndex] - ) { - longestCellByColumn[columnIndex] = size; - } - } - - row.push(cell); - } - - cellMatrix[rowIndex] = row; - sizeMatrix[rowIndex] = sizes; - } - - // Figure out which alignments to use. - columnIndex = -1; - - if (typeof align === 'object' && 'length' in align) { - while (++columnIndex < mostCellsPerRow) { - alignments[columnIndex] = toAlignment(align[columnIndex]); - } - } else { - code = toAlignment(align); - - while (++columnIndex < mostCellsPerRow) { - alignments[columnIndex] = code; - } - } - - // Inject the alignment row. - columnIndex = -1; - row = []; - sizes = []; - - while (++columnIndex < mostCellsPerRow) { - code = alignments[columnIndex]; - before = ''; - after = ''; - - if (code === 99 /* `c` */) { - before = ':'; - after = ':'; - } else if (code === 108 /* `l` */) { - before = ':'; - } else if (code === 114 /* `r` */) { - after = ':'; - } - - // There *must* be at least one hyphen-minus in each alignment cell. - size = - settings.alignDelimiters === false - ? 1 - : Math.max( - 1, - longestCellByColumn[columnIndex] - before.length - after.length - ); - - cell = before + '-'.repeat(size) + after; - - if (settings.alignDelimiters !== false) { - size = before.length + size + after.length; - - if (size > longestCellByColumn[columnIndex]) { - longestCellByColumn[columnIndex] = size; - } - - sizes[columnIndex] = size; - } - - row[columnIndex] = cell; - } - - // Inject the alignment row. - cellMatrix.splice(1, 0, row); - sizeMatrix.splice(1, 0, sizes); - - rowIndex = -1; - /** @type {string[]} */ - const lines = []; - - while (++rowIndex < cellMatrix.length) { - row = cellMatrix[rowIndex]; - sizes = sizeMatrix[rowIndex]; - columnIndex = -1; - line = []; - - while (++columnIndex < mostCellsPerRow) { - cell = row[columnIndex] || ''; - before = ''; - after = ''; - - if (settings.alignDelimiters !== false) { - size = longestCellByColumn[columnIndex] - (sizes[columnIndex] || 0); - code = alignments[columnIndex]; - - if (code === 114 /* `r` */) { - before = ' '.repeat(size); - } else if (code === 99 /* `c` */) { - if (size % 2) { - before = ' '.repeat(size / 2 + 0.5); - after = ' '.repeat(size / 2 - 0.5); - } else { - before = ' '.repeat(size / 2); - after = before; - } - } else { - after = ' '.repeat(size); - } - } - - if (settings.delimiterStart !== false && !columnIndex) { - line.push('|'); - } - - if ( - settings.padding !== false && - // Don’t add the opening space if we’re not aligning and the cell is - // empty: there will be a closing space. - !(settings.alignDelimiters === false && cell === '') && - (settings.delimiterStart !== false || columnIndex) - ) { - line.push(' '); - } - - if (settings.alignDelimiters !== false) { - line.push(before); - } - - line.push(cell); - - if (settings.alignDelimiters !== false) { - line.push(after); - } - - if (settings.padding !== false) { - line.push(' '); - } - - if ( - settings.delimiterEnd !== false || - columnIndex !== mostCellsPerRow - 1 - ) { - line.push('|'); - } - } - - lines.push( - settings.delimiterEnd === false - ? line.join('').replace(/ +$/, '') - : line.join('') - ); - } - - return lines.join('\n') -} - -/** - * @param {string|null|undefined} [value] - * @returns {string} - */ -function serialize(value) { - return value === null || value === undefined ? '' : String(value) -} - -/** - * @param {string} value - * @returns {number} - */ -function defaultStringLength(value) { - return value.length -} - -/** - * @param {string|null|undefined} value - * @returns {number} - */ -function toAlignment(value) { - const code = typeof value === 'string' ? value.charCodeAt(0) : 0; - - return code === 67 /* `C` */ || code === 99 /* `c` */ - ? 99 /* `c` */ - : code === 76 /* `L` */ || code === 108 /* `l` */ - ? 108 /* `l` */ - : code === 82 /* `R` */ || code === 114 /* `r` */ - ? 114 /* `r` */ - : 0 -} - -/** - * @typedef {import('mdast').AlignType} AlignType - * @typedef {import('mdast').Table} Table - * @typedef {import('mdast').TableRow} TableRow - * @typedef {import('mdast').TableCell} TableCell - * @typedef {import('mdast').InlineCode} InlineCode - * @typedef {import('markdown-table').MarkdownTableOptions} MarkdownTableOptions - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Context} ToMarkdownContext - * - * @typedef Options - * @property {boolean} [tableCellPadding=true] - * @property {boolean} [tablePipeAlign=true] - * @property {MarkdownTableOptions['stringLength']} [stringLength] - */ - -/** @type {FromMarkdownExtension} */ -const gfmTableFromMarkdown = { - enter: { - table: enterTable, - tableData: enterCell, - tableHeader: enterCell, - tableRow: enterRow - }, - exit: { - codeText: exitCodeText, - table: exitTable, - tableData: exit, - tableHeader: exit, - tableRow: exit - } -}; - -/** @type {FromMarkdownHandle} */ -function enterTable(token) { - /** @type {AlignType[]} */ - // @ts-expect-error: `align` is custom. - const align = token._align; - this.enter({type: 'table', align, children: []}, token); - this.setData('inTable', true); -} - -/** @type {FromMarkdownHandle} */ -function exitTable(token) { - this.exit(token); - this.setData('inTable'); -} - -/** @type {FromMarkdownHandle} */ -function enterRow(token) { - this.enter({type: 'tableRow', children: []}, token); -} - -/** @type {FromMarkdownHandle} */ -function exit(token) { - this.exit(token); -} - -/** @type {FromMarkdownHandle} */ -function enterCell(token) { - this.enter({type: 'tableCell', children: []}, token); -} - -// Overwrite the default code text data handler to unescape escaped pipes when -// they are in tables. -/** @type {FromMarkdownHandle} */ -function exitCodeText(token) { - let value = this.resume(); - - if (this.getData('inTable')) { - value = value.replace(/\\([\\|])/g, replace); - } - - const node = /** @type {InlineCode} */ (this.stack[this.stack.length - 1]); - node.value = value; - this.exit(token); -} - -/** - * @param {string} $0 - * @param {string} $1 - * @returns {string} - */ -function replace($0, $1) { - // Pipes work, backslashes don’t (but can’t escape pipes). - return $1 === '|' ? $1 : $0 -} - -/** - * @param {Options} [options] - * @returns {ToMarkdownExtension} - */ -function gfmTableToMarkdown(options) { - const settings = options || {}; - const padding = settings.tableCellPadding; - const alignDelimiters = settings.tablePipeAlign; - const stringLength = settings.stringLength; - const around = padding ? ' ' : '|'; - - return { - unsafe: [ - {character: '\r', inConstruct: 'tableCell'}, - {character: '\n', inConstruct: 'tableCell'}, - // A pipe, when followed by a tab or space (padding), or a dash or colon - // (unpadded delimiter row), could result in a table. - {atBreak: true, character: '|', after: '[\t :-]'}, - // A pipe in a cell must be encoded. - {character: '|', inConstruct: 'tableCell'}, - // A colon must be followed by a dash, in which case it could start a - // delimiter row. - {atBreak: true, character: ':', after: '-'}, - // A delimiter row can also start with a dash, when followed by more - // dashes, a colon, or a pipe. - // This is a stricter version than the built in check for lists, thematic - // breaks, and setex heading underlines though: - // - {atBreak: true, character: '-', after: '[:|-]'} - ], - handlers: { - table: handleTable, - tableRow: handleTableRow, - tableCell: handleTableCell, - inlineCode: inlineCodeWithTable - } - } - - /** - * @type {ToMarkdownHandle} - * @param {Table} node - */ - function handleTable(node, _, context) { - // @ts-expect-error: fixed in `markdown-table@3.0.1`. - return serializeData(handleTableAsData(node, context), node.align) - } - - /** - * This function isn’t really used normally, because we handle rows at the - * table level. - * But, if someone passes in a table row, this ensures we make somewhat sense. - * - * @type {ToMarkdownHandle} - * @param {TableRow} node - */ - function handleTableRow(node, _, context) { - const row = handleTableRowAsData(node, context); - // `markdown-table` will always add an align row - const value = serializeData([row]); - return value.slice(0, value.indexOf('\n')) - } - - /** - * @type {ToMarkdownHandle} - * @param {TableCell} node - */ - function handleTableCell(node, _, context) { - const exit = context.enter('tableCell'); - const subexit = context.enter('phrasing'); - const value = containerPhrasing(node, context, { - before: around, - after: around - }); - subexit(); - exit(); - return value - } - - /** - * @param {Array.>} matrix - * @param {Array.} [align] - */ - function serializeData(matrix, align) { - return markdownTable(matrix, { - align, - alignDelimiters, - padding, - stringLength - }) - } - - /** - * @param {Table} node - * @param {ToMarkdownContext} context - */ - function handleTableAsData(node, context) { - const children = node.children; - let index = -1; - /** @type {Array.>} */ - const result = []; - const subexit = context.enter('table'); - - while (++index < children.length) { - result[index] = handleTableRowAsData(children[index], context); - } - - subexit(); - - return result - } - - /** - * @param {TableRow} node - * @param {ToMarkdownContext} context - */ - function handleTableRowAsData(node, context) { - const children = node.children; - let index = -1; - /** @type {Array.} */ - const result = []; - const subexit = context.enter('tableRow'); - - while (++index < children.length) { - result[index] = handleTableCell(children[index], node, context); - } - - subexit(); - - return result - } - - /** - * @type {ToMarkdownHandle} - * @param {InlineCode} node - */ - function inlineCodeWithTable(node, parent, context) { - let value = inlineCode(node, parent, context); - - if (context.stack.includes('tableCell')) { - value = value.replace(/\|/g, '\\$&'); - } - - return value - } -} - -/** - * @typedef {import('mdast').ListItem} ListItem - * @typedef {import('mdast').Paragraph} Paragraph - * @typedef {import('mdast').BlockContent} BlockContent - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle - */ - -/** @type {FromMarkdownExtension} */ -const gfmTaskListItemFromMarkdown = { - exit: { - taskListCheckValueChecked: exitCheck, - taskListCheckValueUnchecked: exitCheck, - paragraph: exitParagraphWithTaskListItem - } -}; - -/** @type {ToMarkdownExtension} */ -const gfmTaskListItemToMarkdown = { - unsafe: [{atBreak: true, character: '-', after: '[:|-]'}], - handlers: {listItem: listItemWithTaskListItem} -}; - -/** @type {FromMarkdownHandle} */ -function exitCheck(token) { - // We’re always in a paragraph, in a list item. - this.stack[this.stack.length - 2].checked = - token.type === 'taskListCheckValueChecked'; -} - -/** @type {FromMarkdownHandle} */ -function exitParagraphWithTaskListItem(token) { - const parent = this.stack[this.stack.length - 2]; - /** @type {Paragraph} */ - // @ts-expect-error: must be true. - const node = this.stack[this.stack.length - 1]; - /** @type {BlockContent[]} */ - // @ts-expect-error: check whether `parent` is a `listItem` later. - const siblings = parent.children; - const head = node.children[0]; - let index = -1; - /** @type {Paragraph|undefined} */ - let firstParaghraph; - - if ( - parent && - parent.type === 'listItem' && - typeof parent.checked === 'boolean' && - head && - head.type === 'text' - ) { - while (++index < siblings.length) { - const sibling = siblings[index]; - if (sibling.type === 'paragraph') { - firstParaghraph = sibling; - break - } - } - - if (firstParaghraph === node) { - // Must start with a space or a tab. - head.value = head.value.slice(1); - - if (head.value.length === 0) { - node.children.shift(); - } else { - // @ts-expect-error: must be true. - head.position.start.column++; - // @ts-expect-error: must be true. - head.position.start.offset++; - // @ts-expect-error: must be true. - node.position.start = Object.assign({}, head.position.start); - } - } - } - - this.exit(token); -} - -/** - * @type {ToMarkdownHandle} - * @param {ListItem} node - */ -function listItemWithTaskListItem(node, parent, context) { - const head = node.children[0]; - let value = listItem(node, parent, context); - - if (typeof node.checked === 'boolean' && head && head.type === 'paragraph') { - value = value.replace(/^(?:[*+-]|\d+\.)([\r\n]| {1,3})/, check); - } - - return value - - /** - * @param {string} $0 - * @returns {string} - */ - function check($0) { - return $0 + '[' + (node.checked ? 'x' : ' ') + '] ' - } -} - -/** - * @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension - * @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension - * - * @typedef {import('mdast-util-gfm-table').Options} Options - */ - -/** - * @type {Array.} - */ -const gfmFromMarkdown = [ - gfmAutolinkLiteralFromMarkdown, - gfmStrikethroughFromMarkdown, - gfmTableFromMarkdown, - gfmTaskListItemFromMarkdown -]; - -/** - * @param {Options} [options] - * @returns {ToMarkdownExtension} - */ -function gfmToMarkdown(options) { - return { - extensions: [ - gfmAutolinkLiteralToMarkdown, - gfmStrikethroughToMarkdown, - gfmTableToMarkdown(options), - gfmTaskListItemToMarkdown - ] - } -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('micromark-extension-gfm').Options & import('mdast-util-gfm').Options} Options - */ - -/** - * Plugin to support GitHub Flavored Markdown (GFM). - * - * @type {import('unified').Plugin<[Options?]|void[], Root>} - */ -function remarkGfm(options = {}) { - const data = this.data(); - - add('micromarkExtensions', gfm(options)); - add('fromMarkdownExtensions', gfmFromMarkdown); - add('toMarkdownExtensions', gfmToMarkdown(options)); - - /** - * @param {string} field - * @param {unknown} value - */ - function add(field, value) { - const list = /** @type {unknown[]} */ ( - // Other extensions - /* c8 ignore next 2 */ - data[field] ? data[field] : (data[field] = []) - ); - - list.push(value); - } -} - -// To aid in future maintenance, this layout closely matches remark-cli/cli.js. - -args({ - processor: remark().use(remarkGfm).use(remarkPresetLintNode), - name: proc.name, - description: cli.description, - version: [ - proc.name + ': ' + proc.version, - cli.name + ': ' + cli.version, - ].join(', '), - pluginPrefix: proc.name, - presetPrefix: proc.name + '-preset', - packageField: proc.name + 'Config', - rcName: '.' + proc.name + 'rc', - ignoreName: '.' + proc.name + 'ignore', - extensions: markdownExtensions, - detectConfig: false, -}); diff --git a/tools/lint-md/.gitignore b/tools/lint-md/.gitignore new file mode 100644 index 00000000000000..3c3629e647f5dd --- /dev/null +++ b/tools/lint-md/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/tools/lint-md/lint-md.mjs b/tools/lint-md/lint-md.mjs new file mode 100644 index 00000000000000..fb02f6c5025bd3 --- /dev/null +++ b/tools/lint-md/lint-md.mjs @@ -0,0 +1,29189 @@ +import fs from 'fs'; +import path$1 from 'path'; +import { fileURLToPath, pathToFileURL, URL as URL$1 } from 'url'; +import process$1 from 'process'; +import os from 'os'; +import tty from 'tty'; + +/** + * Throw a given error. + * + * @param {Error | null | undefined} [error] + */ +function bail(error) { + if (error) { + throw error + } +} + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function commonjsRequire (path) { + throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); +} + +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ + +var isBuffer = function isBuffer (obj) { + return obj != null && obj.constructor != null && + typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +}; + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; +var defineProperty = Object.defineProperty; +var gOPD = Object.getOwnPropertyDescriptor; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject$1 = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) { /**/ } + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target +var setProperty = function setProperty(target, options) { + if (defineProperty && options.name === '__proto__') { + defineProperty(target, options.name, { + enumerable: true, + configurable: true, + value: options.newValue, + writable: true + }); + } else { + target[options.name] = options.newValue; + } +}; + +// Return undefined instead of __proto__ if '__proto__' is not an own property +var getProperty = function getProperty(obj, name) { + if (name === '__proto__') { + if (!hasOwn.call(obj, name)) { + return void 0; + } else if (gOPD) { + // In early versions of node, obj['__proto__'] is buggy when obj has + // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. + return gOPD(obj, name).value; + } + } + + return obj[name]; +}; + +var extend$1 = function extend() { + var options, name, src, copy, copyIsArray, clone; + var target = arguments[0]; + var i = 1; + var length = arguments.length; + var deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = getProperty(target, name); + copy = getProperty(options, name); + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject$1(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject$1(src) ? src : {}; + } + + // Never move original objects, clone them + setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + setProperty(target, { name: name, newValue: copy }); + } + } + } + } + } + + // Return the modified object + return target; +}; + +function isPlainObject(value) { + if (Object.prototype.toString.call(value) !== '[object Object]') { + return false; + } + + const prototype = Object.getPrototypeOf(value); + return prototype === null || prototype === Object.prototype; +} + +/** + * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback + * @typedef {(...input: any[]) => any} Middleware + * + * @typedef {(...input: any[]) => void} Run Call all middleware. + * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. + * @typedef {{run: Run, use: Use}} Pipeline + */ + +/** + * Create new middleware. + * + * @returns {Pipeline} + */ +function trough() { + /** @type {Middleware[]} */ + const fns = []; + /** @type {Pipeline} */ + const pipeline = {run, use}; + + return pipeline + + /** @type {Run} */ + function run(...values) { + let middlewareIndex = -1; + /** @type {Callback} */ + const callback = values.pop(); + + if (typeof callback !== 'function') { + throw new TypeError('Expected function as last argument, not ' + callback) + } + + next(null, ...values); + + /** + * Run the next `fn`, or we’re done. + * + * @param {Error|null|undefined} error + * @param {any[]} output + */ + function next(error, ...output) { + const fn = fns[++middlewareIndex]; + let index = -1; + + if (error) { + callback(error); + return + } + + // Copy non-nullish input into values. + while (++index < values.length) { + if (output[index] === null || output[index] === undefined) { + output[index] = values[index]; + } + } + + // Save the newly created `output` for the next call. + values = output; + + // Next or done. + if (fn) { + wrap(fn, next)(...output); + } else { + callback(null, ...output); + } + } + } + + /** @type {Use} */ + function use(middelware) { + if (typeof middelware !== 'function') { + throw new TypeError( + 'Expected `middelware` to be a function, not ' + middelware + ) + } + + fns.push(middelware); + return pipeline + } +} + +/** + * Wrap `middleware`. + * Can be sync or async; return a promise, receive a callback, or return new + * values and errors. + * + * @param {Middleware} middleware + * @param {Callback} callback + */ +function wrap(middleware, callback) { + /** @type {boolean} */ + let called; + + return wrapped + + /** + * Call `middleware`. + * @param {any[]} parameters + * @returns {void} + */ + function wrapped(...parameters) { + const fnExpectsCallback = middleware.length > parameters.length; + /** @type {any} */ + let result; + + if (fnExpectsCallback) { + parameters.push(done); + } + + try { + result = middleware(...parameters); + } catch (error) { + /** @type {Error} */ + const exception = error; + + // Well, this is quite the pickle. + // `middleware` received a callback and called it synchronously, but that + // threw an error. + // The only thing left to do is to throw the thing instead. + if (fnExpectsCallback && called) { + throw exception + } + + return done(exception) + } + + if (!fnExpectsCallback) { + if (result instanceof Promise) { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } + } + + /** + * Call `callback`, only once. + * @type {Callback} + */ + function done(error, ...output) { + if (!called) { + called = true; + callback(error, ...output); + } + } + + /** + * Call `done` with one value. + * + * @param {any} [value] + */ + function then(value) { + done(null, value); + } +} + +var own$8 = {}.hasOwnProperty; + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + */ + +/** + * Stringify one point, a position (start and end points), or a node’s + * positional information. + * + * @param {Node|Position|Point} [value] + * @returns {string} + */ +function stringifyPosition(value) { + // Nothing. + if (!value || typeof value !== 'object') { + return '' + } + + // Node. + if (own$8.call(value, 'position') || own$8.call(value, 'type')) { + // @ts-ignore looks like a node. + return position(value.position) + } + + // Position. + if (own$8.call(value, 'start') || own$8.call(value, 'end')) { + // @ts-ignore looks like a position. + return position(value) + } + + // Point. + if (own$8.call(value, 'line') || own$8.call(value, 'column')) { + // @ts-ignore looks like a point. + return point$1(value) + } + + // ? + return '' +} + +/** + * @param {Point} point + * @returns {string} + */ +function point$1(point) { + return index(point && point.line) + ':' + index(point && point.column) +} + +/** + * @param {Position} pos + * @returns {string} + */ +function position(pos) { + return point$1(pos && pos.start) + '-' + point$1(pos && pos.end) +} + +/** + * @param {number} value + * @returns {number} + */ +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + */ + +class VFileMessage extends Error { + /** + * Constructor of a message for `reason` at `place` from `origin`. + * When an error is passed in as `reason`, copies the `stack`. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + */ + constructor(reason, place, origin) { + /** @type {[string?, string?]} */ + var parts = [null, null]; + /** @type {Position} */ + var position = { + start: {line: null, column: null}, + end: {line: null, column: null} + }; + /** @type {number} */ + var index; + + super(); + + if (typeof place === 'string') { + origin = place; + place = null; + } + + if (typeof origin === 'string') { + index = origin.indexOf(':'); + + if (index === -1) { + parts[1] = origin; + } else { + parts[0] = origin.slice(0, index); + parts[1] = origin.slice(index + 1); + } + } + + if (place) { + // Node. + if ('type' in place || 'position' in place) { + if (place.position) { + position = place.position; + } + } + // Position. + else if ('start' in place || 'end' in place) { + // @ts-ignore Looks like a position. + position = place; + } + // Point. + else if ('line' in place || 'column' in place) { + // @ts-ignore Looks like a point. + position.start = place; + } + } + + // Fields from `Error` + this.name = stringifyPosition(place) || '1:1'; + this.message = typeof reason === 'object' ? reason.message : reason; + this.stack = typeof reason === 'object' ? reason.stack : ''; + + /** + * Reason for message. + * @type {string} + */ + this.reason = this.message; + /** + * Starting line of error. + * @type {number?} + */ + this.line = position.start.line; + /** + * Starting column of error. + * @type {number?} + */ + this.column = position.start.column; + /** + * Namespace of warning. + * @type {string?} + */ + this.source = parts[0]; + /** + * Category of message. + * @type {string?} + */ + this.ruleId = parts[1]; + /** + * Full range information, when available. + * Has start and end properties, both set to an object with line and column, set to number?. + * @type {Position?} + */ + this.position = position; + + // The following fields are “well known”. + // Not standard. + // Feel free to add other non-standard fields to your messages. + + /* eslint-disable no-unused-expressions */ + /** + * You may add a file property with a path of a file (used throughout the VFile ecosystem). + * @type {string?} + */ + this.file; + /** + * If true, marks associated file as no longer processable. + * @type {boolean?} + */ + this.fatal; + /** + * You may add a url property with a link to documentation for the message. + * @type {string?} + */ + this.url; + /** + * You may add a note property with a long form description of the message (supported by vfile-reporter). + * @type {string?} + */ + this.note; + /* eslint-enable no-unused-expressions */ + } +} + +VFileMessage.prototype.file = ''; +VFileMessage.prototype.name = ''; +VFileMessage.prototype.reason = ''; +VFileMessage.prototype.message = ''; +VFileMessage.prototype.stack = ''; +VFileMessage.prototype.fatal = null; +VFileMessage.prototype.column = null; +VFileMessage.prototype.line = null; +VFileMessage.prototype.source = null; +VFileMessage.prototype.ruleId = null; +VFileMessage.prototype.position = null; + +const proc = process$1; + +/** + * @typedef URL + * @property {string} hash + * @property {string} host + * @property {string} hostname + * @property {string} href + * @property {string} origin + * @property {string} password + * @property {string} pathname + * @property {string} port + * @property {string} protocol + * @property {string} search + * @property {any} searchParams + * @property {string} username + * @property {() => string} toString + * @property {() => string} toJSON + */ + +/** + * @param {unknown} fileURLOrPath + * @returns {fileURLOrPath is URL} + */ +// From: +function isUrl(fileURLOrPath) { + return ( + fileURLOrPath !== null && + typeof fileURLOrPath === 'object' && + // @ts-expect-error: indexable. + fileURLOrPath.href && + // @ts-expect-error: indexable. + fileURLOrPath.origin + ) +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * @typedef {import('./minurl.shared.js').URL} URL + * + * @typedef {'ascii'|'utf8'|'utf-8'|'utf16le'|'ucs2'|'ucs-2'|'base64'|'latin1'|'binary'|'hex'} BufferEncoding + * Encodings supported by the buffer class. + * This is a copy of the typing from Node, copied to prevent Node globals from + * being needed. + * Copied from: + * + * @typedef {string|Uint8Array} VFileValue + * Contents of the file. + * Can either be text, or a Buffer like structure. + * This does not directly use type `Buffer`, because it can also be used in a + * browser context. + * Instead this leverages `Uint8Array` which is the base type for `Buffer`, + * and a native JavaScript construct. + * + * @typedef {VFileValue|VFileOptions|VFile|URL} VFileCompatible + * Things that can be passed to the constructor. + * + * @typedef VFileCoreOptions + * @property {VFileValue} [value] + * @property {string} [cwd] + * @property {Array.} [history] + * @property {string|URL} [path] + * @property {string} [basename] + * @property {string} [stem] + * @property {string} [extname] + * @property {string} [dirname] + * @property {Object.} [data] + * + * @typedef {{[key: string]: unknown} & VFileCoreOptions} VFileOptions + * Configuration: a bunch of keys that will be shallow copied over to the new + * file. + * + * @typedef {Object.} VFileReporterSettings + * @typedef {(files: VFile[], options: T) => string} VFileReporter + */ + +// Order of setting (least specific to most), we need this because otherwise +// `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a +// stem can be set. +const order = ['history', 'path', 'basename', 'stem', 'extname', 'dirname']; + +class VFile { + /** + * Create a new virtual file. + * + * If `options` is `string` or `Buffer`, treats it as `{value: options}`. + * If `options` is a `VFile`, shallow copies its data over to the new file. + * All other given fields are set on the newly created `VFile`. + * + * Path related properties are set in the following order (least specific to + * most specific): `history`, `path`, `basename`, `stem`, `extname`, + * `dirname`. + * + * It’s not possible to set either `dirname` or `extname` without setting + * either `history`, `path`, `basename`, or `stem` as well. + * + * @param {VFileCompatible} [value] + */ + constructor(value) { + /** @type {VFileOptions} */ + let options; + + if (!value) { + options = {}; + } else if (typeof value === 'string' || isBuffer(value)) { + // @ts-expect-error Looks like a buffer. + options = {value}; + } else if (isUrl(value)) { + options = {path: value}; + } else { + // @ts-expect-error Looks like file or options. + options = value; + } + + /** + * Place to store custom information. + * It’s OK to store custom data directly on the file, moving it to `data` + * gives a little more privacy. + * @type {Object.} + */ + this.data = {}; + + /** + * List of messages associated with the file. + * @type {Array.} + */ + this.messages = []; + + /** + * List of file paths the file moved between. + * @type {Array.} + */ + this.history = []; + + /** + * Base of `path`. + * Defaults to `process.cwd()` (`/` in browsers). + * @type {string} + */ + this.cwd = proc.cwd(); + + /* eslint-disable no-unused-expressions */ + /** + * Raw value. + * @type {VFileValue} + */ + this.value; + + // The below are non-standard, they are “well-known”. + // As in, used in several tools. + + /** + * Whether a file was saved to disk. + * This is used by vfile reporters. + * @type {boolean} + */ + this.stored; + + /** + * Sometimes files have a non-string representation. + * This can be stored in the `result` field. + * One example is when turning markdown into React nodes. + * This is used by unified to store non-string results. + * @type {unknown} + */ + this.result; + + /** + * Sometimes files have a source map associated with them. + * This can be stored in the `map` field. + * This should be a `RawSourceMap` type from the `source-map` module. + * @type {unknown} + */ + this.map; + /* eslint-enable no-unused-expressions */ + + // Set path related properties in the correct order. + let index = -1; + + while (++index < order.length) { + const prop = order[index]; + + // Note: we specifically use `in` instead of `hasOwnProperty` to accept + // `vfile`s too. + if (prop in options && options[prop] !== undefined) { + // @ts-expect-error: TS is confused by the different types for `history`. + this[prop] = prop === 'history' ? [...options[prop]] : options[prop]; + } + } + + /** @type {string} */ + let prop; + + // Set non-path related properties. + for (prop in options) { + // @ts-expect-error: fine to set other things. + if (!order.includes(prop)) this[prop] = options[prop]; + } + } + + /** + * Access full path (`~/index.min.js`). + * + * @returns {string} + */ + get path() { + return this.history[this.history.length - 1] + } + + /** + * Set full path (`~/index.min.js`). + * Cannot be nullified. + * + * @param {string|URL} path + */ + set path(path) { + if (isUrl(path)) { + path = fileURLToPath(path); + } + + assertNonEmpty(path, 'path'); + + if (this.path !== path) { + this.history.push(path); + } + } + + /** + * Access parent path (`~`). + */ + get dirname() { + return typeof this.path === 'string' ? path$1.dirname(this.path) : undefined + } + + /** + * Set parent path (`~`). + * Cannot be set if there's no `path` yet. + */ + set dirname(dirname) { + assertPath(this.basename, 'dirname'); + this.path = path$1.join(dirname || '', this.basename); + } + + /** + * Access basename (including extname) (`index.min.js`). + */ + get basename() { + return typeof this.path === 'string' ? path$1.basename(this.path) : undefined + } + + /** + * Set basename (`index.min.js`). + * Cannot contain path separators. + * Cannot be nullified either (use `file.path = file.dirname` instead). + */ + set basename(basename) { + assertNonEmpty(basename, 'basename'); + assertPart(basename, 'basename'); + this.path = path$1.join(this.dirname || '', basename); + } + + /** + * Access extname (including dot) (`.js`). + */ + get extname() { + return typeof this.path === 'string' ? path$1.extname(this.path) : undefined + } + + /** + * Set extname (including dot) (`.js`). + * Cannot be set if there's no `path` yet and cannot contain path separators. + */ + set extname(extname) { + assertPart(extname, 'extname'); + assertPath(this.dirname, 'extname'); + + if (extname) { + if (extname.charCodeAt(0) !== 46 /* `.` */) { + throw new Error('`extname` must start with `.`') + } + + if (extname.includes('.', 1)) { + throw new Error('`extname` cannot contain multiple dots') + } + } + + this.path = path$1.join(this.dirname, this.stem + (extname || '')); + } + + /** + * Access stem (w/o extname) (`index.min`). + */ + get stem() { + return typeof this.path === 'string' + ? path$1.basename(this.path, this.extname) + : undefined + } + + /** + * Set stem (w/o extname) (`index.min`). + * Cannot be nullified, and cannot contain path separators. + */ + set stem(stem) { + assertNonEmpty(stem, 'stem'); + assertPart(stem, 'stem'); + this.path = path$1.join(this.dirname || '', stem + (this.extname || '')); + } + + /** + * Serialize the file. + * + * @param {BufferEncoding} [encoding='utf8'] If `file.value` is a buffer, `encoding` is used to serialize buffers. + * @returns {string} + */ + toString(encoding) { + // @ts-expect-error string’s don’t accept the parameter, but buffers do. + return (this.value || '').toString(encoding) + } + + /** + * Create a message and associates it w/ the file. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + * @returns {VFileMessage} + */ + message(reason, place, origin) { + const message = new VFileMessage(reason, place, origin); + + if (this.path) { + message.name = this.path + ':' + message.name; + message.file = this.path; + } + + message.fatal = false; + + this.messages.push(message); + + return message + } + + /** + * Info: create a message, associate it with the file, and mark the fatality + * as `null`. + * Calls `message()` internally. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + * @returns {VFileMessage} + */ + info(reason, place, origin) { + const message = this.message(reason, place, origin); + + message.fatal = null; + + return message + } + + /** + * Fail: create a message, associate it with the file, mark the fatality as + * `true`. + * Note: fatal errors mean a file is no longer processable. + * Calls `message()` internally. + * + * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. + * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). + * @param {string} [origin] Place in code the message originates from (`string`, optional). + * @returns {never} + */ + fail(reason, place, origin) { + const message = this.message(reason, place, origin); + + message.fatal = true; + + throw message + } +} + +/** + * Assert that `part` is not a path (as in, does not contain `path.sep`). + * + * @param {string|undefined} part + * @param {string} name + * @returns {void} + */ +function assertPart(part, name) { + if (part && part.includes(path$1.sep)) { + throw new Error( + '`' + name + '` cannot be a path: did not expect `' + path$1.sep + '`' + ) + } +} + +/** + * Assert that `part` is not empty. + * + * @param {string|undefined} part + * @param {string} name + * @returns {asserts part is string} + */ +function assertNonEmpty(part, name) { + if (!part) { + throw new Error('`' + name + '` cannot be empty') + } +} + +/** + * Assert `path` exists. + * + * @param {string|undefined} path + * @param {string} name + * @returns {asserts path is string} + */ +function assertPath(path, name) { + if (!path) { + throw new Error('Setting `' + name + '` requires `path` to be set too') + } +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFileCompatible} VFileCompatible + * @typedef {import('vfile').VFileValue} VFileValue + * @typedef {import('..').Processor} Processor + * @typedef {import('..').Plugin} Plugin + * @typedef {import('..').Preset} Preset + * @typedef {import('..').Pluggable} Pluggable + * @typedef {import('..').PluggableList} PluggableList + * @typedef {import('..').Transformer} Transformer + * @typedef {import('..').Parser} Parser + * @typedef {import('..').Compiler} Compiler + * @typedef {import('..').RunCallback} RunCallback + * @typedef {import('..').ProcessCallback} ProcessCallback + * + * @typedef Context + * @property {Node} tree + * @property {VFile} file + */ + +// Expose a frozen processor. +const unified = base().freeze(); + +const own$7 = {}.hasOwnProperty; + +// Function to create the first processor. +/** + * @returns {Processor} + */ +function base() { + const transformers = trough(); + /** @type {Processor['attachers']} */ + const attachers = []; + /** @type {Record} */ + let namespace = {}; + /** @type {boolean|undefined} */ + let frozen; + let freezeIndex = -1; + + // Data management. + // @ts-expect-error: overloads are handled. + processor.data = data; + processor.Parser = undefined; + processor.Compiler = undefined; + + // Lock. + processor.freeze = freeze; + + // Plugins. + processor.attachers = attachers; + // @ts-expect-error: overloads are handled. + processor.use = use; + + // API. + processor.parse = parse; + processor.stringify = stringify; + // @ts-expect-error: overloads are handled. + processor.run = run; + processor.runSync = runSync; + // @ts-expect-error: overloads are handled. + processor.process = process; + processor.processSync = processSync; + + // Expose. + return processor + + // Create a new processor based on the processor in the current scope. + /** @type {Processor} */ + function processor() { + const destination = base(); + let index = -1; + + while (++index < attachers.length) { + destination.use(...attachers[index]); + } + + destination.data(extend$1(true, {}, namespace)); + + return destination + } + + /** + * @param {string|Record} [key] + * @param {unknown} [value] + * @returns {unknown} + */ + function data(key, value) { + if (typeof key === 'string') { + // Set `key`. + if (arguments.length === 2) { + assertUnfrozen('data', frozen); + namespace[key] = value; + return processor + } + + // Get `key`. + return (own$7.call(namespace, key) && namespace[key]) || null + } + + // Set space. + if (key) { + assertUnfrozen('data', frozen); + namespace = key; + return processor + } + + // Get space. + return namespace + } + + /** @type {Processor['freeze']} */ + function freeze() { + if (frozen) { + return processor + } + + while (++freezeIndex < attachers.length) { + const [attacher, ...options] = attachers[freezeIndex]; + + if (options[0] === false) { + continue + } + + if (options[0] === true) { + options[1] = undefined; + } + + /** @type {Transformer|void} */ + const transformer = attacher.call(processor, ...options); + + if (typeof transformer === 'function') { + transformers.use(transformer); + } + } + + frozen = true; + freezeIndex = Number.POSITIVE_INFINITY; + + return processor + } + + /** + * @param {Pluggable|null|undefined} [value] + * @param {...unknown} options + * @returns {Processor} + */ + function use(value, ...options) { + /** @type {Record|undefined} */ + let settings; + + assertUnfrozen('use', frozen); + + if (value === null || value === undefined) ; else if (typeof value === 'function') { + addPlugin(value, ...options); + } else if (typeof value === 'object') { + if (Array.isArray(value)) { + addList(value); + } else { + addPreset(value); + } + } else { + throw new TypeError('Expected usable value, not `' + value + '`') + } + + if (settings) { + namespace.settings = Object.assign(namespace.settings || {}, settings); + } + + return processor + + /** + * @param {import('..').Pluggable} value + * @returns {void} + */ + function add(value) { + if (typeof value === 'function') { + addPlugin(value); + } else if (typeof value === 'object') { + if (Array.isArray(value)) { + const [plugin, ...options] = value; + addPlugin(plugin, ...options); + } else { + addPreset(value); + } + } else { + throw new TypeError('Expected usable value, not `' + value + '`') + } + } + + /** + * @param {Preset} result + * @returns {void} + */ + function addPreset(result) { + addList(result.plugins); + + if (result.settings) { + settings = Object.assign(settings || {}, result.settings); + } + } + + /** + * @param {PluggableList|null|undefined} [plugins] + * @returns {void} + */ + function addList(plugins) { + let index = -1; + + if (plugins === null || plugins === undefined) ; else if (Array.isArray(plugins)) { + while (++index < plugins.length) { + const thing = plugins[index]; + add(thing); + } + } else { + throw new TypeError('Expected a list of plugins, not `' + plugins + '`') + } + } + + /** + * @param {Plugin} plugin + * @param {...unknown} [value] + * @returns {void} + */ + function addPlugin(plugin, value) { + let index = -1; + /** @type {Processor['attachers'][number]|undefined} */ + let entry; + + while (++index < attachers.length) { + if (attachers[index][0] === plugin) { + entry = attachers[index]; + break + } + } + + if (entry) { + if (isPlainObject(entry[1]) && isPlainObject(value)) { + value = extend$1(true, entry[1], value); + } + + entry[1] = value; + } else { + // @ts-expect-error: fine. + attachers.push([...arguments]); + } + } + } + + /** @type {Processor['parse']} */ + function parse(doc) { + processor.freeze(); + const file = vfile(doc); + const Parser = processor.Parser; + assertParser('parse', Parser); + + if (newable(Parser, 'parse')) { + // @ts-expect-error: `newable` checks this. + return new Parser(String(file), file).parse() + } + + // @ts-expect-error: `newable` checks this. + return Parser(String(file), file) // eslint-disable-line new-cap + } + + /** @type {Processor['stringify']} */ + function stringify(node, doc) { + processor.freeze(); + const file = vfile(doc); + const Compiler = processor.Compiler; + assertCompiler('stringify', Compiler); + assertNode(node); + + if (newable(Compiler, 'compile')) { + // @ts-expect-error: `newable` checks this. + return new Compiler(node, file).compile() + } + + // @ts-expect-error: `newable` checks this. + return Compiler(node, file) // eslint-disable-line new-cap + } + + /** + * @param {Node} node + * @param {VFileCompatible|RunCallback} [doc] + * @param {RunCallback} [callback] + * @returns {Promise|void} + */ + function run(node, doc, callback) { + assertNode(node); + processor.freeze(); + + if (!callback && typeof doc === 'function') { + callback = doc; + doc = undefined; + } + + if (!callback) { + return new Promise(executor) + } + + executor(null, callback); + + /** + * @param {null|((node: Node) => void)} resolve + * @param {(error: Error) => void} reject + * @returns {void} + */ + function executor(resolve, reject) { + // @ts-expect-error: `doc` can’t be a callback anymore, we checked. + transformers.run(node, vfile(doc), done); + + /** + * @param {Error|null} error + * @param {Node} tree + * @param {VFile} file + * @returns {void} + */ + function done(error, tree, file) { + tree = tree || node; + if (error) { + reject(error); + } else if (resolve) { + resolve(tree); + } else { + // @ts-expect-error: `callback` is defined if `resolve` is not. + callback(null, tree, file); + } + } + } + } + + /** @type {Processor['runSync']} */ + function runSync(node, file) { + /** @type {Node|undefined} */ + let result; + /** @type {boolean|undefined} */ + let complete; + + processor.run(node, file, done); + + assertDone('runSync', 'run', complete); + + // @ts-expect-error: we either bailed on an error or have a tree. + return result + + /** + * @param {Error|null} [error] + * @param {Node} [tree] + * @returns {void} + */ + function done(error, tree) { + bail(error); + result = tree; + complete = true; + } + } + + /** + * @param {VFileCompatible} doc + * @param {ProcessCallback} [callback] + * @returns {Promise|undefined} + */ + function process(doc, callback) { + processor.freeze(); + assertParser('process', processor.Parser); + assertCompiler('process', processor.Compiler); + + if (!callback) { + return new Promise(executor) + } + + executor(null, callback); + + /** + * @param {null|((file: VFile) => void)} resolve + * @param {(error?: Error|null|undefined) => void} reject + * @returns {void} + */ + function executor(resolve, reject) { + const file = vfile(doc); + + processor.run(processor.parse(file), file, (error, tree, file) => { + if (error || !tree || !file) { + done(error); + } else { + /** @type {unknown} */ + const result = processor.stringify(tree, file); + + if (result === undefined || result === null) ; else if (looksLikeAVFileValue(result)) { + file.value = result; + } else { + file.result = result; + } + + done(error, file); + } + }); + + /** + * @param {Error|null|undefined} [error] + * @param {VFile|undefined} [file] + * @returns {void} + */ + function done(error, file) { + if (error || !file) { + reject(error); + } else if (resolve) { + resolve(file); + } else { + // @ts-expect-error: `callback` is defined if `resolve` is not. + callback(null, file); + } + } + } + } + + /** @type {Processor['processSync']} */ + function processSync(doc) { + /** @type {boolean|undefined} */ + let complete; + + processor.freeze(); + assertParser('processSync', processor.Parser); + assertCompiler('processSync', processor.Compiler); + + const file = vfile(doc); + + processor.process(file, done); + + assertDone('processSync', 'process', complete); + + return file + + /** + * @param {Error|null|undefined} [error] + * @returns {void} + */ + function done(error) { + complete = true; + bail(error); + } + } +} + +/** + * Check if `value` is a constructor. + * + * @param {unknown} value + * @param {string} name + * @returns {boolean} + */ +function newable(value, name) { + return ( + typeof value === 'function' && + // Prototypes do exist. + // type-coverage:ignore-next-line + value.prototype && + // A function with keys in its prototype is probably a constructor. + // Classes’ prototype methods are not enumerable, so we check if some value + // exists in the prototype. + // type-coverage:ignore-next-line + (keys(value.prototype) || name in value.prototype) + ) +} + +/** + * Check if `value` is an object with keys. + * + * @param {Record} value + * @returns {boolean} + */ +function keys(value) { + /** @type {string} */ + let key; + + for (key in value) { + if (own$7.call(value, key)) { + return true + } + } + + return false +} + +/** + * Assert a parser is available. + * + * @param {string} name + * @param {unknown} value + * @returns {asserts value is Parser} + */ +function assertParser(name, value) { + if (typeof value !== 'function') { + throw new TypeError('Cannot `' + name + '` without `Parser`') + } +} + +/** + * Assert a compiler is available. + * + * @param {string} name + * @param {unknown} value + * @returns {asserts value is Compiler} + */ +function assertCompiler(name, value) { + if (typeof value !== 'function') { + throw new TypeError('Cannot `' + name + '` without `Compiler`') + } +} + +/** + * Assert the processor is not frozen. + * + * @param {string} name + * @param {unknown} frozen + * @returns {asserts frozen is false} + */ +function assertUnfrozen(name, frozen) { + if (frozen) { + throw new Error( + 'Cannot call `' + + name + + '` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.' + ) + } +} + +/** + * Assert `node` is a unist node. + * + * @param {unknown} node + * @returns {asserts node is Node} + */ +function assertNode(node) { + // `isPlainObj` unfortunately uses `any` instead of `unknown`. + // type-coverage:ignore-next-line + if (!isPlainObject(node) || typeof node.type !== 'string') { + throw new TypeError('Expected node, got `' + node + '`') + // Fine. + } +} + +/** + * Assert that `complete` is `true`. + * + * @param {string} name + * @param {string} asyncName + * @param {unknown} complete + * @returns {asserts complete is true} + */ +function assertDone(name, asyncName, complete) { + if (!complete) { + throw new Error( + '`' + name + '` finished async. Use `' + asyncName + '` instead' + ) + } +} + +/** + * @param {VFileCompatible} [value] + * @returns {VFile} + */ +function vfile(value) { + return looksLikeAVFile$1(value) ? value : new VFile(value) +} + +/** + * @param {VFileCompatible} [value] + * @returns {value is VFile} + */ +function looksLikeAVFile$1(value) { + return Boolean( + value && + typeof value === 'object' && + 'message' in value && + 'messages' in value + ) +} + +/** + * @param {unknown} [value] + * @returns {value is VFileValue} + */ +function looksLikeAVFileValue(value) { + return typeof value === 'string' || isBuffer(value) +} + +/** + * @typedef Options + * @property {boolean} [includeImageAlt=true] + */ + +/** + * Get the text content of a node. + * Prefer the node’s plain-text fields, otherwise serialize its children, + * and if the given value is an array, serialize the nodes in it. + * + * @param {unknown} node + * @param {Options} [options] + * @returns {string} + */ +function toString(node, options) { + var {includeImageAlt = true} = options || {}; + return one(node, includeImageAlt) +} + +/** + * @param {unknown} node + * @param {boolean} includeImageAlt + * @returns {string} + */ +function one(node, includeImageAlt) { + return ( + (node && + typeof node === 'object' && + // @ts-ignore looks like a literal. + (node.value || + // @ts-ignore looks like an image. + (includeImageAlt ? node.alt : '') || + // @ts-ignore looks like a parent. + ('children' in node && all(node.children, includeImageAlt)) || + (Array.isArray(node) && all(node, includeImageAlt)))) || + '' + ) +} + +/** + * @param {Array.} values + * @param {boolean} includeImageAlt + * @returns {string} + */ +function all(values, includeImageAlt) { + /** @type {Array.} */ + var result = []; + var index = -1; + + while (++index < values.length) { + result[index] = one(values[index], includeImageAlt); + } + + return result.join('') +} + +/** + * Like `Array#splice`, but smarter for giant arrays. + * + * `Array#splice` takes all items to be inserted as individual argument which + * causes a stack overflow in V8 when trying to insert 100k items for instance. + * + * Otherwise, this does not return the removed items, and takes `items` as an + * array instead of rest parameters. + * + * @template {unknown} T + * @param {T[]} list + * @param {number} start + * @param {number} remove + * @param {T[]} items + * @returns {void} + */ +function splice(list, start, remove, items) { + const end = list.length; + let chunkStart = 0; + /** @type {unknown[]} */ + + let parameters; // Make start between zero and `end` (included). + + if (start < 0) { + start = -start > end ? 0 : end + start; + } else { + start = start > end ? end : start; + } + + remove = remove > 0 ? remove : 0; // No need to chunk the items if there’s only a couple (10k) items. + + if (items.length < 10000) { + parameters = Array.from(items); + parameters.unshift(start, remove) // @ts-expect-error Hush, it’s fine. + ;[].splice.apply(list, parameters); + } else { + // Delete `remove` items starting from `start` + if (remove) [].splice.apply(list, [start, remove]); // Insert the items in chunks to not cause stack overflows. + + while (chunkStart < items.length) { + parameters = items.slice(chunkStart, chunkStart + 10000); + parameters.unshift(start, 0) // @ts-expect-error Hush, it’s fine. + ;[].splice.apply(list, parameters); + chunkStart += 10000; + start += 10000; + } + } +} +/** + * Append `items` (an array) at the end of `list` (another array). + * When `list` was empty, returns `items` instead. + * + * This prevents a potentially expensive operation when `list` is empty, + * and adds items in batches to prevent V8 from hanging. + * + * @template {unknown} T + * @param {T[]} list + * @param {T[]} items + * @returns {T[]} + */ + +function push(list, items) { + if (list.length > 0) { + splice(list, list.length, 0, items); + return list + } + + return items +} + +/** + * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +const hasOwnProperty = {}.hasOwnProperty; + +/** + * Combine several syntax extensions into one. + * + * @param {Extension[]} extensions List of syntax extensions. + * @returns {NormalizedExtension} A single combined extension. + */ +function combineExtensions(extensions) { + /** @type {NormalizedExtension} */ + const all = {}; + let index = -1; + + while (++index < extensions.length) { + syntaxExtension(all, extensions[index]); + } + + return all +} + +/** + * Merge `extension` into `all`. + * + * @param {NormalizedExtension} all Extension to merge into. + * @param {Extension} extension Extension to merge. + * @returns {void} + */ +function syntaxExtension(all, extension) { + /** @type {string} */ + let hook; + + for (hook in extension) { + const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; + const left = maybe || (all[hook] = {}); + const right = extension[hook]; + /** @type {string} */ + let code; + + for (code in right) { + if (!hasOwnProperty.call(left, code)) left[code] = []; + const value = right[code]; + constructs( + // @ts-expect-error Looks like a list. + left[code], + Array.isArray(value) ? value : value ? [value] : [] + ); + } + } +} + +/** + * Merge `list` into `existing` (both lists of constructs). + * Mutates `existing`. + * + * @param {unknown[]} existing + * @param {unknown[]} list + * @returns {void} + */ +function constructs(existing, list) { + let index = -1; + /** @type {unknown[]} */ + const before = []; + + while (++index < list.length) { +(list[index].add === 'after' ? existing : before).push(list[index]); + } + + splice(existing, 0, 0, before); +} + +/** + * Combine several HTML extensions into one. + * + * @param {HtmlExtension[]} htmlExtensions List of HTML extensions. + * @returns {HtmlExtension} A single combined extension. + */ +function combineHtmlExtensions(htmlExtensions) { + /** @type {HtmlExtension} */ + const handlers = {}; + let index = -1; + + while (++index < htmlExtensions.length) { + htmlExtension(handlers, htmlExtensions[index]); + } + + return handlers +} + +/** + * Merge `extension` into `all`. + * + * @param {HtmlExtension} all Extension to merge into. + * @param {HtmlExtension} extension Extension to merge. + * @returns {void} + */ +function htmlExtension(all, extension) { + /** @type {string} */ + let hook; + + for (hook in extension) { + const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; + const left = maybe || (all[hook] = {}); + const right = extension[hook]; + /** @type {string} */ + let type; + + if (right) { + for (type in right) { + left[type] = right[type]; + } + } + } +} + +// This module is generated by `script/`. +// +// CommonMark handles attention (emphasis, strong) markers based on what comes +// before or after them. +// One such difference is if those characters are Unicode punctuation. +// This script is generated from the Unicode data. +const unicodePunctuationRegex = + /[!-/:-@[-`{-~\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; + +/** + * @typedef {import('micromark-util-types').Code} Code + */ +/** + * Check whether the character code represents an ASCII alpha (`a` through `z`, + * case insensitive). + * + * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. + * + * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) + * to U+005A (`Z`). + * + * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) + * to U+007A (`z`). + */ + +const asciiAlpha = regexCheck(/[A-Za-z]/); +/** + * Check whether the character code represents an ASCII digit (`0` through `9`). + * + * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to + * U+0039 (`9`). + */ + +const asciiDigit = regexCheck(/\d/); +/** + * Check whether the character code represents an ASCII hex digit (`a` through + * `f`, case insensitive, or `0` through `9`). + * + * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex + * digit, or an ASCII lower hex digit. + * + * An **ASCII upper hex digit** is a character in the inclusive range U+0041 + * (`A`) to U+0046 (`F`). + * + * An **ASCII lower hex digit** is a character in the inclusive range U+0061 + * (`a`) to U+0066 (`f`). + */ + +const asciiHexDigit = regexCheck(/[\dA-Fa-f]/); +/** + * Check whether the character code represents an ASCII alphanumeric (`a` + * through `z`, case insensitive, or `0` through `9`). + * + * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha + * (see `asciiAlpha`). + */ + +const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/); +/** + * Check whether the character code represents ASCII punctuation. + * + * An **ASCII punctuation** is a character in the inclusive ranges U+0021 + * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT + * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT + * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). + */ + +const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/); +/** + * Check whether the character code represents an ASCII atext. + * + * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in + * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), + * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F + * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E + * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE + * (`{`) to U+007E TILDE (`~`). + * + * See: + * **\[RFC5322]**: + * [Internet Message Format](https://tools.ietf.org/html/rfc5322). + * P. Resnick. + * IETF. + */ + +const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/); +/** + * Check whether a character code is an ASCII control character. + * + * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) + * to U+001F (US), or U+007F (DEL). + * + * @param {Code} code + * @returns {code is number} + */ + +function asciiControl(code) { + return ( + // Special whitespace codes (which have negative values), C0 and Control + // character DEL + code !== null && (code < 32 || code === 127) + ) +} +/** + * Check whether a character code is a markdown line ending (see + * `markdownLineEnding`) or markdown space (see `markdownSpace`). + * + * @param {Code} code + * @returns {code is number} + */ + +function markdownLineEndingOrSpace(code) { + return code !== null && (code < 0 || code === 32) +} +/** + * Check whether a character code is a markdown line ending. + * + * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN + * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). + * + * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE + * RETURN (CR) are replaced by these virtual characters depending on whether + * they occurred together. + * + * @param {Code} code + * @returns {code is number} + */ + +function markdownLineEnding(code) { + return code !== null && code < -2 +} +/** + * Check whether a character code is a markdown space. + * + * A **markdown space** is the concrete character U+0020 SPACE (SP) and the + * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). + * + * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is + * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL + * SPACE (VS) characters, depending on the column at which the tab occurred. + * + * @param {Code} code + * @returns {code is number} + */ + +function markdownSpace(code) { + return code === -2 || code === -1 || code === 32 +} +/** + * Check whether the character code represents Unicode whitespace. + * + * Note that this does handle micromark specific markdown whitespace characters. + * See `markdownLineEndingOrSpace` to check that. + * + * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, + * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), + * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + */ + +const unicodeWhitespace = regexCheck(/\s/); +/** + * Check whether the character code represents Unicode punctuation. + * + * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, + * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` + * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` + * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII + * punctuation (see `asciiPunctuation`). + * + * See: + * **\[UNICODE]**: + * [The Unicode Standard](https://www.unicode.org/versions/). + * Unicode Consortium. + */ +// Size note: removing ASCII from the regex and using `asciiPunctuation` here +// In fact adds to the bundle size. + +const unicodePunctuation = regexCheck(unicodePunctuationRegex); +/** + * Create a code check from a regex. + * + * @param {RegExp} regex + * @returns {(code: Code) => code is number} + */ + +function regexCheck(regex) { + return check + /** + * Check whether a code matches the bound regex. + * + * @param {Code} code Character code + * @returns {code is number} Whether the character code matches the bound regex + */ + + function check(code) { + return code !== null && regex.test(String.fromCharCode(code)) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ +/** + * @param {Effects} effects + * @param {State} ok + * @param {string} type + * @param {number} [max=Infinity] + * @returns {State} + */ + +function factorySpace(effects, ok, type, max) { + const limit = max ? max - 1 : Number.POSITIVE_INFINITY; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + if (markdownSpace(code)) { + effects.enter(type); + return prefix(code) + } + + return ok(code) + } + /** @type {State} */ + + function prefix(code) { + if (markdownSpace(code) && size++ < limit) { + effects.consume(code); + return prefix + } + + effects.exit(type); + return ok(code) + } +} + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {InitialConstruct} */ +const content$1 = { + tokenize: initializeContent +}; +/** @type {Initializer} */ + +function initializeContent(effects) { + const contentStart = effects.attempt( + this.parser.constructs.contentInitial, + afterContentStartConstruct, + paragraphInitial + ); + /** @type {Token} */ + + let previous; + return contentStart + /** @type {State} */ + + function afterContentStartConstruct(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, contentStart, 'linePrefix') + } + /** @type {State} */ + + function paragraphInitial(code) { + effects.enter('paragraph'); + return lineStart(code) + } + /** @type {State} */ + + function lineStart(code) { + const token = effects.enter('chunkText', { + contentType: 'text', + previous + }); + + if (previous) { + previous.next = token; + } + + previous = token; + return data(code) + } + /** @type {State} */ + + function data(code) { + if (code === null) { + effects.exit('chunkText'); + effects.exit('paragraph'); + effects.consume(code); + return + } + + if (markdownLineEnding(code)) { + effects.consume(code); + effects.exit('chunkText'); + return lineStart + } // Data. + + effects.consume(code); + return data + } +} + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Point} Point + */ +/** @type {InitialConstruct} */ + +const document$1 = { + tokenize: initializeDocument +}; +/** @type {Construct} */ + +const containerConstruct = { + tokenize: tokenizeContainer +}; +/** @type {Initializer} */ + +function initializeDocument(effects) { + const self = this; + /** @type {StackItem[]} */ + + const stack = []; + let continued = 0; + /** @type {TokenizeContext|undefined} */ + + let childFlow; + /** @type {Token|undefined} */ + + let childToken; + /** @type {number} */ + + let lineStartOffset; + return start + /** @type {State} */ + + function start(code) { + // First we iterate through the open blocks, starting with the root + // document, and descending through last children down to the last open + // block. + // Each block imposes a condition that the line must satisfy if the block is + // to remain open. + // For example, a block quote requires a `>` character. + // A paragraph requires a non-blank line. + // In this phase we may match all or just some of the open blocks. + // But we cannot close unmatched blocks yet, because we may have a lazy + // continuation line. + if (continued < stack.length) { + const item = stack[continued]; + self.containerState = item[1]; + return effects.attempt( + item[0].continuation, + documentContinue, + checkNewContainers + )(code) + } // Done. + + return checkNewContainers(code) + } + /** @type {State} */ + + function documentContinue(code) { + continued++; // Note: this field is called `_closeFlow` but it also closes containers. + // Perhaps a good idea to rename it but it’s already used in the wild by + // extensions. + + if (self.containerState._closeFlow) { + self.containerState._closeFlow = undefined; + + if (childFlow) { + closeFlow(); + } // Note: this algorithm for moving events around is similar to the + // algorithm when dealing with lazy lines in `writeToChild`. + + const indexBeforeExits = self.events.length; + let indexBeforeFlow = indexBeforeExits; + /** @type {Point|undefined} */ + + let point; // Find the flow chunk. + + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + point = self.events[indexBeforeFlow][1].end; + break + } + } + + exitContainers(continued); // Fix positions. + + let index = indexBeforeExits; + + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point); + index++; + } // Inject the exits earlier (they’re still also at the end). + + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ); // Discard the duplicate exits. + + self.events.length = index; + return checkNewContainers(code) + } + + return start(code) + } + /** @type {State} */ + + function checkNewContainers(code) { + // Next, after consuming the continuation markers for existing blocks, we + // look for new block starts (e.g. `>` for a block quote). + // If we encounter a new block start, we close any blocks unmatched in + // step 1 before creating the new block as a child of the last matched + // block. + if (continued === stack.length) { + // No need to `check` whether there’s a container, of `exitContainers` + // would be moot. + // We can instead immediately `attempt` to parse one. + if (!childFlow) { + return documentContinued(code) + } // If we have concrete content, such as block HTML or fenced code, + // we can’t have containers “pierce” into them, so we can immediately + // start. + + if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { + return flowStart(code) + } // If we do have flow, it could still be a blank line, + // but we’d be interrupting it w/ a new container if there’s a current + // construct. + + self.interrupt = Boolean(childFlow.currentConstruct); + } // Check if there is a new container. + + self.containerState = {}; + return effects.check( + containerConstruct, + thereIsANewContainer, + thereIsNoNewContainer + )(code) + } + /** @type {State} */ + + function thereIsANewContainer(code) { + if (childFlow) closeFlow(); + exitContainers(continued); + return documentContinued(code) + } + /** @type {State} */ + + function thereIsNoNewContainer(code) { + self.parser.lazy[self.now().line] = continued !== stack.length; + lineStartOffset = self.now().offset; + return flowStart(code) + } + /** @type {State} */ + + function documentContinued(code) { + // Try new containers. + self.containerState = {}; + return effects.attempt( + containerConstruct, + containerContinue, + flowStart + )(code) + } + /** @type {State} */ + + function containerContinue(code) { + continued++; + stack.push([self.currentConstruct, self.containerState]); // Try another. + + return documentContinued(code) + } + /** @type {State} */ + + function flowStart(code) { + if (code === null) { + if (childFlow) closeFlow(); + exitContainers(0); + effects.consume(code); + return + } + + childFlow = childFlow || self.parser.flow(self.now()); + effects.enter('chunkFlow', { + contentType: 'flow', + previous: childToken, + _tokenizer: childFlow + }); + return flowContinue(code) + } + /** @type {State} */ + + function flowContinue(code) { + if (code === null) { + writeToChild(effects.exit('chunkFlow'), true); + exitContainers(0); + effects.consume(code); + return + } + + if (markdownLineEnding(code)) { + effects.consume(code); + writeToChild(effects.exit('chunkFlow')); // Get ready for the next line. + + continued = 0; + self.interrupt = undefined; + return start + } + + effects.consume(code); + return flowContinue + } + /** + * @param {Token} token + * @param {boolean} [eof] + * @returns {void} + */ + + function writeToChild(token, eof) { + const stream = self.sliceStream(token); + if (eof) stream.push(null); + token.previous = childToken; + if (childToken) childToken.next = token; + childToken = token; + childFlow.defineSkip(token.start); + childFlow.write(stream); // Alright, so we just added a lazy line: + // + // ```markdown + // > a + // b. + // + // Or: + // + // > ~~~c + // d + // + // Or: + // + // > | e | + // f + // ``` + // + // The construct in the second example (fenced code) does not accept lazy + // lines, so it marked itself as done at the end of its first line, and + // then the content construct parses `d`. + // Most constructs in markdown match on the first line: if the first line + // forms a construct, a non-lazy line can’t “unmake” it. + // + // The construct in the third example is potentially a GFM table, and + // those are *weird*. + // It *could* be a table, from the first line, if the following line + // matches a condition. + // In this case, that second line is lazy, which “unmakes” the first line + // and turns the whole into one content block. + // + // We’ve now parsed the non-lazy and the lazy line, and can figure out + // whether the lazy line started a new flow block. + // If it did, we exit the current containers between the two flow blocks. + + if (self.parser.lazy[token.start.line]) { + let index = childFlow.events.length; + + while (index--) { + if ( + // The token starts before the line ending… + childFlow.events[index][1].start.offset < lineStartOffset && + (!childFlow.events[index][1].end || // …or ends after it. + childFlow.events[index][1].end.offset > lineStartOffset) + ) { + // Exit: there’s still something open, which means it’s a lazy line + // part of something. + return + } + } // Note: this algorithm for moving events around is similar to the + // algorithm when closing flow in `documentContinue`. + + const indexBeforeExits = self.events.length; + let indexBeforeFlow = indexBeforeExits; + /** @type {boolean|undefined} */ + + let seen; + /** @type {Point|undefined} */ + + let point; // Find the previous chunk (the one before the lazy line). + + while (indexBeforeFlow--) { + if ( + self.events[indexBeforeFlow][0] === 'exit' && + self.events[indexBeforeFlow][1].type === 'chunkFlow' + ) { + if (seen) { + point = self.events[indexBeforeFlow][1].end; + break + } + + seen = true; + } + } + + exitContainers(continued); // Fix positions. + + index = indexBeforeExits; + + while (index < self.events.length) { + self.events[index][1].end = Object.assign({}, point); + index++; + } // Inject the exits earlier (they’re still also at the end). + + splice( + self.events, + indexBeforeFlow + 1, + 0, + self.events.slice(indexBeforeExits) + ); // Discard the duplicate exits. + + self.events.length = index; + } + } + /** + * @param {number} size + * @returns {void} + */ + + function exitContainers(size) { + let index = stack.length; // Exit open containers. + + while (index-- > size) { + const entry = stack[index]; + self.containerState = entry[1]; + entry[0].exit.call(self, effects); + } + + stack.length = size; + } + + function closeFlow() { + childFlow.write([null]); + childToken = undefined; + childFlow = undefined; + self.containerState._closeFlow = undefined; + } +} +/** @type {Tokenizer} */ + +function tokenizeContainer(effects, ok, nok) { + return factorySpace( + effects, + effects.attempt(this.parser.constructs.document, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} + +/** + * @typedef {import('micromark-util-types').Code} Code + */ + +/** + * Classify whether a character code represents whitespace, punctuation, or + * something else. + * + * Used for attention (emphasis, strong), whose sequences can open or close + * based on the class of surrounding characters. + * + * Note that eof (`null`) is seen as whitespace. + * + * @param {Code} code + * @returns {number|undefined} + */ +function classifyCharacter(code) { + if ( + code === null || + markdownLineEndingOrSpace(code) || + unicodeWhitespace(code) + ) { + return 1 + } + + if (unicodePunctuation(code)) { + return 2 + } +} + +/** + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Resolver} Resolver + */ + +/** + * Call all `resolveAll`s. + * + * @param {{resolveAll?: Resolver}[]} constructs + * @param {Event[]} events + * @param {TokenizeContext} context + * @returns {Event[]} + */ +function resolveAll(constructs, events, context) { + /** @type {Resolver[]} */ + const called = []; + let index = -1; + + while (++index < constructs.length) { + const resolve = constructs[index].resolveAll; + + if (resolve && !called.includes(resolve)) { + events = resolve(events, context); + called.push(resolve); + } + } + + return events +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Point} Point + */ + +/** @type {Construct} */ +const attention = { + name: 'attention', + tokenize: tokenizeAttention, + resolveAll: resolveAllAttention +}; +/** + * Take all events and resolve attention to emphasis or strong. + * + * @type {Resolver} + */ + +function resolveAllAttention(events, context) { + let index = -1; + /** @type {number} */ + + let open; + /** @type {Token} */ + + let group; + /** @type {Token} */ + + let text; + /** @type {Token} */ + + let openingSequence; + /** @type {Token} */ + + let closingSequence; + /** @type {number} */ + + let use; + /** @type {Event[]} */ + + let nextEvents; + /** @type {number} */ + + let offset; // Walk through all events. + // + // Note: performance of this is fine on an mb of normal markdown, but it’s + // a bottleneck for malicious stuff. + + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'attentionSequence' && + events[index][1]._close + ) { + open = index; // Now walk back to find an opener. + + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'attentionSequence' && + events[open][1]._open && // If the markers are the same: + context.sliceSerialize(events[open][1]).charCodeAt(0) === + context.sliceSerialize(events[index][1]).charCodeAt(0) + ) { + // If the opening can close or the closing can open, + // and the close size *is not* a multiple of three, + // but the sum of the opening and closing size *is* multiple of three, + // then don’t match. + if ( + (events[open][1]._close || events[index][1]._open) && + (events[index][1].end.offset - events[index][1].start.offset) % 3 && + !( + (events[open][1].end.offset - + events[open][1].start.offset + + events[index][1].end.offset - + events[index][1].start.offset) % + 3 + ) + ) { + continue + } // Number of markers to use from the sequence. + + use = + events[open][1].end.offset - events[open][1].start.offset > 1 && + events[index][1].end.offset - events[index][1].start.offset > 1 + ? 2 + : 1; + const start = Object.assign({}, events[open][1].end); + const end = Object.assign({}, events[index][1].start); + movePoint(start, -use); + movePoint(end, use); + openingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start, + end: Object.assign({}, events[open][1].end) + }; + closingSequence = { + type: use > 1 ? 'strongSequence' : 'emphasisSequence', + start: Object.assign({}, events[index][1].start), + end + }; + text = { + type: use > 1 ? 'strongText' : 'emphasisText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + }; + group = { + type: use > 1 ? 'strong' : 'emphasis', + start: Object.assign({}, openingSequence.start), + end: Object.assign({}, closingSequence.end) + }; + events[open][1].end = Object.assign({}, openingSequence.start); + events[index][1].start = Object.assign({}, closingSequence.end); + nextEvents = []; // If there are more markers in the opening, add them before. + + if (events[open][1].end.offset - events[open][1].start.offset) { + nextEvents = push(nextEvents, [ + ['enter', events[open][1], context], + ['exit', events[open][1], context] + ]); + } // Opening. + + nextEvents = push(nextEvents, [ + ['enter', group, context], + ['enter', openingSequence, context], + ['exit', openingSequence, context], + ['enter', text, context] + ]); // Between. + + nextEvents = push( + nextEvents, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ); // Closing. + + nextEvents = push(nextEvents, [ + ['exit', text, context], + ['enter', closingSequence, context], + ['exit', closingSequence, context], + ['exit', group, context] + ]); // If there are more markers in the closing, add them after. + + if (events[index][1].end.offset - events[index][1].start.offset) { + offset = 2; + nextEvents = push(nextEvents, [ + ['enter', events[index][1], context], + ['exit', events[index][1], context] + ]); + } else { + offset = 0; + } + + splice(events, open - 1, index - open + 3, nextEvents); + index = open + nextEvents.length - offset - 2; + break + } + } + } + } // Remove remaining sequences. + + index = -1; + + while (++index < events.length) { + if (events[index][1].type === 'attentionSequence') { + events[index][1].type = 'data'; + } + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeAttention(effects, ok) { + const attentionMarkers = this.parser.constructs.attentionMarkers.null; + const previous = this.previous; + const before = classifyCharacter(previous); + /** @type {NonNullable} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('attentionSequence'); + marker = code; + return sequence(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === marker) { + effects.consume(code); + return sequence + } + + const token = effects.exit('attentionSequence'); + const after = classifyCharacter(code); + const open = + !after || (after === 2 && before) || attentionMarkers.includes(code); + const close = + !before || (before === 2 && after) || attentionMarkers.includes(previous); + token._open = Boolean(marker === 42 ? open : open && (before || !close)); + token._close = Boolean(marker === 42 ? close : close && (after || !open)); + return ok(code) + } +} +/** + * Move a point a bit. + * + * Note: `move` only works inside lines! It’s not possible to move past other + * chunks (replacement characters, tabs, or line endings). + * + * @param {Point} point + * @param {number} offset + * @returns {void} + */ + +function movePoint(point, offset) { + point.column += offset; + point.offset += offset; + point._bufferIndex += offset; +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const autolink = { + name: 'autolink', + tokenize: tokenizeAutolink +}; +/** @type {Tokenizer} */ + +function tokenizeAutolink(effects, ok, nok) { + let size = 1; + return start + /** @type {State} */ + + function start(code) { + effects.enter('autolink'); + effects.enter('autolinkMarker'); + effects.consume(code); + effects.exit('autolinkMarker'); + effects.enter('autolinkProtocol'); + return open + } + /** @type {State} */ + + function open(code) { + if (asciiAlpha(code)) { + effects.consume(code); + return schemeOrEmailAtext + } + + return asciiAtext(code) ? emailAtext(code) : nok(code) + } + /** @type {State} */ + + function schemeOrEmailAtext(code) { + return code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code) + ? schemeInsideOrEmailAtext(code) + : emailAtext(code) + } + /** @type {State} */ + + function schemeInsideOrEmailAtext(code) { + if (code === 58) { + effects.consume(code); + return urlInside + } + + if ( + (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && + size++ < 32 + ) { + effects.consume(code); + return schemeInsideOrEmailAtext + } + + return emailAtext(code) + } + /** @type {State} */ + + function urlInside(code) { + if (code === 62) { + effects.exit('autolinkProtocol'); + return end(code) + } + + if (code === null || code === 32 || code === 60 || asciiControl(code)) { + return nok(code) + } + + effects.consume(code); + return urlInside + } + /** @type {State} */ + + function emailAtext(code) { + if (code === 64) { + effects.consume(code); + size = 0; + return emailAtSignOrDot + } + + if (asciiAtext(code)) { + effects.consume(code); + return emailAtext + } + + return nok(code) + } + /** @type {State} */ + + function emailAtSignOrDot(code) { + return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) + } + /** @type {State} */ + + function emailLabel(code) { + if (code === 46) { + effects.consume(code); + size = 0; + return emailAtSignOrDot + } + + if (code === 62) { + // Exit, then change the type. + effects.exit('autolinkProtocol').type = 'autolinkEmail'; + return end(code) + } + + return emailValue(code) + } + /** @type {State} */ + + function emailValue(code) { + if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { + effects.consume(code); + return code === 45 ? emailValue : emailLabel + } + + return nok(code) + } + /** @type {State} */ + + function end(code) { + effects.enter('autolinkMarker'); + effects.consume(code); + effects.exit('autolinkMarker'); + effects.exit('autolink'); + return ok + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const blankLine = { + tokenize: tokenizeBlankLine, + partial: true +}; +/** @type {Tokenizer} */ + +function tokenizeBlankLine(effects, ok, nok) { + return factorySpace(effects, afterWhitespace, 'linePrefix') + /** @type {State} */ + + function afterWhitespace(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const blockQuote = { + name: 'blockQuote', + tokenize: tokenizeBlockQuoteStart, + continuation: { + tokenize: tokenizeBlockQuoteContinuation + }, + exit: exit$1 +}; +/** @type {Tokenizer} */ + +function tokenizeBlockQuoteStart(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + if (code === 62) { + const state = self.containerState; + + if (!state.open) { + effects.enter('blockQuote', { + _container: true + }); + state.open = true; + } + + effects.enter('blockQuotePrefix'); + effects.enter('blockQuoteMarker'); + effects.consume(code); + effects.exit('blockQuoteMarker'); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + if (markdownSpace(code)) { + effects.enter('blockQuotePrefixWhitespace'); + effects.consume(code); + effects.exit('blockQuotePrefixWhitespace'); + effects.exit('blockQuotePrefix'); + return ok + } + + effects.exit('blockQuotePrefix'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeBlockQuoteContinuation(effects, ok, nok) { + return factorySpace( + effects, + effects.attempt(blockQuote, ok, nok), + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 + ) +} +/** @type {Exiter} */ + +function exit$1(effects) { + effects.exit('blockQuote'); +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const characterEscape = { + name: 'characterEscape', + tokenize: tokenizeCharacterEscape +}; +/** @type {Tokenizer} */ + +function tokenizeCharacterEscape(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('characterEscape'); + effects.enter('escapeMarker'); + effects.consume(code); + effects.exit('escapeMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (asciiPunctuation(code)) { + effects.enter('characterEscapeValue'); + effects.consume(code); + effects.exit('characterEscapeValue'); + effects.exit('characterEscape'); + return ok + } + + return nok(code) + } +} + +var characterEntities = { + AEli: 'Æ', + AElig: 'Æ', + AM: '&', + AMP: '&', + Aacut: 'Á', + Aacute: 'Á', + Abreve: 'Ă', + Acir: 'Â', + Acirc: 'Â', + Acy: 'А', + Afr: '𝔄', + Agrav: 'À', + Agrave: 'À', + Alpha: 'Α', + Amacr: 'Ā', + And: '⩓', + Aogon: 'Ą', + Aopf: '𝔸', + ApplyFunction: '⁡', + Arin: 'Å', + Aring: 'Å', + Ascr: '𝒜', + Assign: '≔', + Atild: 'Ã', + Atilde: 'Ã', + Aum: 'Ä', + Auml: 'Ä', + Backslash: '∖', + Barv: '⫧', + Barwed: '⌆', + Bcy: 'Б', + Because: '∵', + Bernoullis: 'ℬ', + Beta: 'Β', + Bfr: '𝔅', + Bopf: '𝔹', + Breve: '˘', + Bscr: 'ℬ', + Bumpeq: '≎', + CHcy: 'Ч', + COP: '©', + COPY: '©', + Cacute: 'Ć', + Cap: '⋒', + CapitalDifferentialD: 'ⅅ', + Cayleys: 'ℭ', + Ccaron: 'Č', + Ccedi: 'Ç', + Ccedil: 'Ç', + Ccirc: 'Ĉ', + Cconint: '∰', + Cdot: 'Ċ', + Cedilla: '¸', + CenterDot: '·', + Cfr: 'ℭ', + Chi: 'Χ', + CircleDot: '⊙', + CircleMinus: '⊖', + CirclePlus: '⊕', + CircleTimes: '⊗', + ClockwiseContourIntegral: '∲', + CloseCurlyDoubleQuote: '”', + CloseCurlyQuote: '’', + Colon: '∷', + Colone: '⩴', + Congruent: '≡', + Conint: '∯', + ContourIntegral: '∮', + Copf: 'ℂ', + Coproduct: '∐', + CounterClockwiseContourIntegral: '∳', + Cross: '⨯', + Cscr: '𝒞', + Cup: '⋓', + CupCap: '≍', + DD: 'ⅅ', + DDotrahd: '⤑', + DJcy: 'Ђ', + DScy: 'Ѕ', + DZcy: 'Џ', + Dagger: '‡', + Darr: '↡', + Dashv: '⫤', + Dcaron: 'Ď', + Dcy: 'Д', + Del: '∇', + Delta: 'Δ', + Dfr: '𝔇', + DiacriticalAcute: '´', + DiacriticalDot: '˙', + DiacriticalDoubleAcute: '˝', + DiacriticalGrave: '`', + DiacriticalTilde: '˜', + Diamond: '⋄', + DifferentialD: 'ⅆ', + Dopf: '𝔻', + Dot: '¨', + DotDot: '⃜', + DotEqual: '≐', + DoubleContourIntegral: '∯', + DoubleDot: '¨', + DoubleDownArrow: '⇓', + DoubleLeftArrow: '⇐', + DoubleLeftRightArrow: '⇔', + DoubleLeftTee: '⫤', + DoubleLongLeftArrow: '⟸', + DoubleLongLeftRightArrow: '⟺', + DoubleLongRightArrow: '⟹', + DoubleRightArrow: '⇒', + DoubleRightTee: '⊨', + DoubleUpArrow: '⇑', + DoubleUpDownArrow: '⇕', + DoubleVerticalBar: '∥', + DownArrow: '↓', + DownArrowBar: '⤓', + DownArrowUpArrow: '⇵', + DownBreve: '̑', + DownLeftRightVector: '⥐', + DownLeftTeeVector: '⥞', + DownLeftVector: '↽', + DownLeftVectorBar: '⥖', + DownRightTeeVector: '⥟', + DownRightVector: '⇁', + DownRightVectorBar: '⥗', + DownTee: '⊤', + DownTeeArrow: '↧', + Downarrow: '⇓', + Dscr: '𝒟', + Dstrok: 'Đ', + ENG: 'Ŋ', + ET: 'Ð', + ETH: 'Ð', + Eacut: 'É', + Eacute: 'É', + Ecaron: 'Ě', + Ecir: 'Ê', + Ecirc: 'Ê', + Ecy: 'Э', + Edot: 'Ė', + Efr: '𝔈', + Egrav: 'È', + Egrave: 'È', + Element: '∈', + Emacr: 'Ē', + EmptySmallSquare: '◻', + EmptyVerySmallSquare: '▫', + Eogon: 'Ę', + Eopf: '𝔼', + Epsilon: 'Ε', + Equal: '⩵', + EqualTilde: '≂', + Equilibrium: '⇌', + Escr: 'ℰ', + Esim: '⩳', + Eta: 'Η', + Eum: 'Ë', + Euml: 'Ë', + Exists: '∃', + ExponentialE: 'ⅇ', + Fcy: 'Ф', + Ffr: '𝔉', + FilledSmallSquare: '◼', + FilledVerySmallSquare: '▪', + Fopf: '𝔽', + ForAll: '∀', + Fouriertrf: 'ℱ', + Fscr: 'ℱ', + GJcy: 'Ѓ', + G: '>', + GT: '>', + Gamma: 'Γ', + Gammad: 'Ϝ', + Gbreve: 'Ğ', + Gcedil: 'Ģ', + Gcirc: 'Ĝ', + Gcy: 'Г', + Gdot: 'Ġ', + Gfr: '𝔊', + Gg: '⋙', + Gopf: '𝔾', + GreaterEqual: '≥', + GreaterEqualLess: '⋛', + GreaterFullEqual: '≧', + GreaterGreater: '⪢', + GreaterLess: '≷', + GreaterSlantEqual: '⩾', + GreaterTilde: '≳', + Gscr: '𝒢', + Gt: '≫', + HARDcy: 'Ъ', + Hacek: 'ˇ', + Hat: '^', + Hcirc: 'Ĥ', + Hfr: 'ℌ', + HilbertSpace: 'ℋ', + Hopf: 'ℍ', + HorizontalLine: '─', + Hscr: 'ℋ', + Hstrok: 'Ħ', + HumpDownHump: '≎', + HumpEqual: '≏', + IEcy: 'Е', + IJlig: 'IJ', + IOcy: 'Ё', + Iacut: 'Í', + Iacute: 'Í', + Icir: 'Î', + Icirc: 'Î', + Icy: 'И', + Idot: 'İ', + Ifr: 'ℑ', + Igrav: 'Ì', + Igrave: 'Ì', + Im: 'ℑ', + Imacr: 'Ī', + ImaginaryI: 'ⅈ', + Implies: '⇒', + Int: '∬', + Integral: '∫', + Intersection: '⋂', + InvisibleComma: '⁣', + InvisibleTimes: '⁢', + Iogon: 'Į', + Iopf: '𝕀', + Iota: 'Ι', + Iscr: 'ℐ', + Itilde: 'Ĩ', + Iukcy: 'І', + Ium: 'Ï', + Iuml: 'Ï', + Jcirc: 'Ĵ', + Jcy: 'Й', + Jfr: '𝔍', + Jopf: '𝕁', + Jscr: '𝒥', + Jsercy: 'Ј', + Jukcy: 'Є', + KHcy: 'Х', + KJcy: 'Ќ', + Kappa: 'Κ', + Kcedil: 'Ķ', + Kcy: 'К', + Kfr: '𝔎', + Kopf: '𝕂', + Kscr: '𝒦', + LJcy: 'Љ', + L: '<', + LT: '<', + Lacute: 'Ĺ', + Lambda: 'Λ', + Lang: '⟪', + Laplacetrf: 'ℒ', + Larr: '↞', + Lcaron: 'Ľ', + Lcedil: 'Ļ', + Lcy: 'Л', + LeftAngleBracket: '⟨', + LeftArrow: '←', + LeftArrowBar: '⇤', + LeftArrowRightArrow: '⇆', + LeftCeiling: '⌈', + LeftDoubleBracket: '⟦', + LeftDownTeeVector: '⥡', + LeftDownVector: '⇃', + LeftDownVectorBar: '⥙', + LeftFloor: '⌊', + LeftRightArrow: '↔', + LeftRightVector: '⥎', + LeftTee: '⊣', + LeftTeeArrow: '↤', + LeftTeeVector: '⥚', + LeftTriangle: '⊲', + LeftTriangleBar: '⧏', + LeftTriangleEqual: '⊴', + LeftUpDownVector: '⥑', + LeftUpTeeVector: '⥠', + LeftUpVector: '↿', + LeftUpVectorBar: '⥘', + LeftVector: '↼', + LeftVectorBar: '⥒', + Leftarrow: '⇐', + Leftrightarrow: '⇔', + LessEqualGreater: '⋚', + LessFullEqual: '≦', + LessGreater: '≶', + LessLess: '⪡', + LessSlantEqual: '⩽', + LessTilde: '≲', + Lfr: '𝔏', + Ll: '⋘', + Lleftarrow: '⇚', + Lmidot: 'Ŀ', + LongLeftArrow: '⟵', + LongLeftRightArrow: '⟷', + LongRightArrow: '⟶', + Longleftarrow: '⟸', + Longleftrightarrow: '⟺', + Longrightarrow: '⟹', + Lopf: '𝕃', + LowerLeftArrow: '↙', + LowerRightArrow: '↘', + Lscr: 'ℒ', + Lsh: '↰', + Lstrok: 'Ł', + Lt: '≪', + Map: '⤅', + Mcy: 'М', + MediumSpace: ' ', + Mellintrf: 'ℳ', + Mfr: '𝔐', + MinusPlus: '∓', + Mopf: '𝕄', + Mscr: 'ℳ', + Mu: 'Μ', + NJcy: 'Њ', + Nacute: 'Ń', + Ncaron: 'Ň', + Ncedil: 'Ņ', + Ncy: 'Н', + NegativeMediumSpace: '​', + NegativeThickSpace: '​', + NegativeThinSpace: '​', + NegativeVeryThinSpace: '​', + NestedGreaterGreater: '≫', + NestedLessLess: '≪', + NewLine: '\n', + Nfr: '𝔑', + NoBreak: '⁠', + NonBreakingSpace: ' ', + Nopf: 'ℕ', + Not: '⫬', + NotCongruent: '≢', + NotCupCap: '≭', + NotDoubleVerticalBar: '∦', + NotElement: '∉', + NotEqual: '≠', + NotEqualTilde: '≂̸', + NotExists: '∄', + NotGreater: '≯', + NotGreaterEqual: '≱', + NotGreaterFullEqual: '≧̸', + NotGreaterGreater: '≫̸', + NotGreaterLess: '≹', + NotGreaterSlantEqual: '⩾̸', + NotGreaterTilde: '≵', + NotHumpDownHump: '≎̸', + NotHumpEqual: '≏̸', + NotLeftTriangle: '⋪', + NotLeftTriangleBar: '⧏̸', + NotLeftTriangleEqual: '⋬', + NotLess: '≮', + NotLessEqual: '≰', + NotLessGreater: '≸', + NotLessLess: '≪̸', + NotLessSlantEqual: '⩽̸', + NotLessTilde: '≴', + NotNestedGreaterGreater: '⪢̸', + NotNestedLessLess: '⪡̸', + NotPrecedes: '⊀', + NotPrecedesEqual: '⪯̸', + NotPrecedesSlantEqual: '⋠', + NotReverseElement: '∌', + NotRightTriangle: '⋫', + NotRightTriangleBar: '⧐̸', + NotRightTriangleEqual: '⋭', + NotSquareSubset: '⊏̸', + NotSquareSubsetEqual: '⋢', + NotSquareSuperset: '⊐̸', + NotSquareSupersetEqual: '⋣', + NotSubset: '⊂⃒', + NotSubsetEqual: '⊈', + NotSucceeds: '⊁', + NotSucceedsEqual: '⪰̸', + NotSucceedsSlantEqual: '⋡', + NotSucceedsTilde: '≿̸', + NotSuperset: '⊃⃒', + NotSupersetEqual: '⊉', + NotTilde: '≁', + NotTildeEqual: '≄', + NotTildeFullEqual: '≇', + NotTildeTilde: '≉', + NotVerticalBar: '∤', + Nscr: '𝒩', + Ntild: 'Ñ', + Ntilde: 'Ñ', + Nu: 'Ν', + OElig: 'Œ', + Oacut: 'Ó', + Oacute: 'Ó', + Ocir: 'Ô', + Ocirc: 'Ô', + Ocy: 'О', + Odblac: 'Ő', + Ofr: '𝔒', + Ograv: 'Ò', + Ograve: 'Ò', + Omacr: 'Ō', + Omega: 'Ω', + Omicron: 'Ο', + Oopf: '𝕆', + OpenCurlyDoubleQuote: '“', + OpenCurlyQuote: '‘', + Or: '⩔', + Oscr: '𝒪', + Oslas: 'Ø', + Oslash: 'Ø', + Otild: 'Õ', + Otilde: 'Õ', + Otimes: '⨷', + Oum: 'Ö', + Ouml: 'Ö', + OverBar: '‾', + OverBrace: '⏞', + OverBracket: '⎴', + OverParenthesis: '⏜', + PartialD: '∂', + Pcy: 'П', + Pfr: '𝔓', + Phi: 'Φ', + Pi: 'Π', + PlusMinus: '±', + Poincareplane: 'ℌ', + Popf: 'ℙ', + Pr: '⪻', + Precedes: '≺', + PrecedesEqual: '⪯', + PrecedesSlantEqual: '≼', + PrecedesTilde: '≾', + Prime: '″', + Product: '∏', + Proportion: '∷', + Proportional: '∝', + Pscr: '𝒫', + Psi: 'Ψ', + QUO: '"', + QUOT: '"', + Qfr: '𝔔', + Qopf: 'ℚ', + Qscr: '𝒬', + RBarr: '⤐', + RE: '®', + REG: '®', + Racute: 'Ŕ', + Rang: '⟫', + Rarr: '↠', + Rarrtl: '⤖', + Rcaron: 'Ř', + Rcedil: 'Ŗ', + Rcy: 'Р', + Re: 'ℜ', + ReverseElement: '∋', + ReverseEquilibrium: '⇋', + ReverseUpEquilibrium: '⥯', + Rfr: 'ℜ', + Rho: 'Ρ', + RightAngleBracket: '⟩', + RightArrow: '→', + RightArrowBar: '⇥', + RightArrowLeftArrow: '⇄', + RightCeiling: '⌉', + RightDoubleBracket: '⟧', + RightDownTeeVector: '⥝', + RightDownVector: '⇂', + RightDownVectorBar: '⥕', + RightFloor: '⌋', + RightTee: '⊢', + RightTeeArrow: '↦', + RightTeeVector: '⥛', + RightTriangle: '⊳', + RightTriangleBar: '⧐', + RightTriangleEqual: '⊵', + RightUpDownVector: '⥏', + RightUpTeeVector: '⥜', + RightUpVector: '↾', + RightUpVectorBar: '⥔', + RightVector: '⇀', + RightVectorBar: '⥓', + Rightarrow: '⇒', + Ropf: 'ℝ', + RoundImplies: '⥰', + Rrightarrow: '⇛', + Rscr: 'ℛ', + Rsh: '↱', + RuleDelayed: '⧴', + SHCHcy: 'Щ', + SHcy: 'Ш', + SOFTcy: 'Ь', + Sacute: 'Ś', + Sc: '⪼', + Scaron: 'Š', + Scedil: 'Ş', + Scirc: 'Ŝ', + Scy: 'С', + Sfr: '𝔖', + ShortDownArrow: '↓', + ShortLeftArrow: '←', + ShortRightArrow: '→', + ShortUpArrow: '↑', + Sigma: 'Σ', + SmallCircle: '∘', + Sopf: '𝕊', + Sqrt: '√', + Square: '□', + SquareIntersection: '⊓', + SquareSubset: '⊏', + SquareSubsetEqual: '⊑', + SquareSuperset: '⊐', + SquareSupersetEqual: '⊒', + SquareUnion: '⊔', + Sscr: '𝒮', + Star: '⋆', + Sub: '⋐', + Subset: '⋐', + SubsetEqual: '⊆', + Succeeds: '≻', + SucceedsEqual: '⪰', + SucceedsSlantEqual: '≽', + SucceedsTilde: '≿', + SuchThat: '∋', + Sum: '∑', + Sup: '⋑', + Superset: '⊃', + SupersetEqual: '⊇', + Supset: '⋑', + THOR: 'Þ', + THORN: 'Þ', + TRADE: '™', + TSHcy: 'Ћ', + TScy: 'Ц', + Tab: '\t', + Tau: 'Τ', + Tcaron: 'Ť', + Tcedil: 'Ţ', + Tcy: 'Т', + Tfr: '𝔗', + Therefore: '∴', + Theta: 'Θ', + ThickSpace: '  ', + ThinSpace: ' ', + Tilde: '∼', + TildeEqual: '≃', + TildeFullEqual: '≅', + TildeTilde: '≈', + Topf: '𝕋', + TripleDot: '⃛', + Tscr: '𝒯', + Tstrok: 'Ŧ', + Uacut: 'Ú', + Uacute: 'Ú', + Uarr: '↟', + Uarrocir: '⥉', + Ubrcy: 'Ў', + Ubreve: 'Ŭ', + Ucir: 'Û', + Ucirc: 'Û', + Ucy: 'У', + Udblac: 'Ű', + Ufr: '𝔘', + Ugrav: 'Ù', + Ugrave: 'Ù', + Umacr: 'Ū', + UnderBar: '_', + UnderBrace: '⏟', + UnderBracket: '⎵', + UnderParenthesis: '⏝', + Union: '⋃', + UnionPlus: '⊎', + Uogon: 'Ų', + Uopf: '𝕌', + UpArrow: '↑', + UpArrowBar: '⤒', + UpArrowDownArrow: '⇅', + UpDownArrow: '↕', + UpEquilibrium: '⥮', + UpTee: '⊥', + UpTeeArrow: '↥', + Uparrow: '⇑', + Updownarrow: '⇕', + UpperLeftArrow: '↖', + UpperRightArrow: '↗', + Upsi: 'ϒ', + Upsilon: 'Υ', + Uring: 'Ů', + Uscr: '𝒰', + Utilde: 'Ũ', + Uum: 'Ü', + Uuml: 'Ü', + VDash: '⊫', + Vbar: '⫫', + Vcy: 'В', + Vdash: '⊩', + Vdashl: '⫦', + Vee: '⋁', + Verbar: '‖', + Vert: '‖', + VerticalBar: '∣', + VerticalLine: '|', + VerticalSeparator: '❘', + VerticalTilde: '≀', + VeryThinSpace: ' ', + Vfr: '𝔙', + Vopf: '𝕍', + Vscr: '𝒱', + Vvdash: '⊪', + Wcirc: 'Ŵ', + Wedge: '⋀', + Wfr: '𝔚', + Wopf: '𝕎', + Wscr: '𝒲', + Xfr: '𝔛', + Xi: 'Ξ', + Xopf: '𝕏', + Xscr: '𝒳', + YAcy: 'Я', + YIcy: 'Ї', + YUcy: 'Ю', + Yacut: 'Ý', + Yacute: 'Ý', + Ycirc: 'Ŷ', + Ycy: 'Ы', + Yfr: '𝔜', + Yopf: '𝕐', + Yscr: '𝒴', + Yuml: 'Ÿ', + ZHcy: 'Ж', + Zacute: 'Ź', + Zcaron: 'Ž', + Zcy: 'З', + Zdot: 'Ż', + ZeroWidthSpace: '​', + Zeta: 'Ζ', + Zfr: 'ℨ', + Zopf: 'ℤ', + Zscr: '𝒵', + aacut: 'á', + aacute: 'á', + abreve: 'ă', + ac: '∾', + acE: '∾̳', + acd: '∿', + acir: 'â', + acirc: 'â', + acut: '´', + acute: '´', + acy: 'а', + aeli: 'æ', + aelig: 'æ', + af: '⁡', + afr: '𝔞', + agrav: 'à', + agrave: 'à', + alefsym: 'ℵ', + aleph: 'ℵ', + alpha: 'α', + amacr: 'ā', + amalg: '⨿', + am: '&', + amp: '&', + and: '∧', + andand: '⩕', + andd: '⩜', + andslope: '⩘', + andv: '⩚', + ang: '∠', + ange: '⦤', + angle: '∠', + angmsd: '∡', + angmsdaa: '⦨', + angmsdab: '⦩', + angmsdac: '⦪', + angmsdad: '⦫', + angmsdae: '⦬', + angmsdaf: '⦭', + angmsdag: '⦮', + angmsdah: '⦯', + angrt: '∟', + angrtvb: '⊾', + angrtvbd: '⦝', + angsph: '∢', + angst: 'Å', + angzarr: '⍼', + aogon: 'ą', + aopf: '𝕒', + ap: '≈', + apE: '⩰', + apacir: '⩯', + ape: '≊', + apid: '≋', + apos: "'", + approx: '≈', + approxeq: '≊', + arin: 'å', + aring: 'å', + ascr: '𝒶', + ast: '*', + asymp: '≈', + asympeq: '≍', + atild: 'ã', + atilde: 'ã', + aum: 'ä', + auml: 'ä', + awconint: '∳', + awint: '⨑', + bNot: '⫭', + backcong: '≌', + backepsilon: '϶', + backprime: '‵', + backsim: '∽', + backsimeq: '⋍', + barvee: '⊽', + barwed: '⌅', + barwedge: '⌅', + bbrk: '⎵', + bbrktbrk: '⎶', + bcong: '≌', + bcy: 'б', + bdquo: '„', + becaus: '∵', + because: '∵', + bemptyv: '⦰', + bepsi: '϶', + bernou: 'ℬ', + beta: 'β', + beth: 'ℶ', + between: '≬', + bfr: '𝔟', + bigcap: '⋂', + bigcirc: '◯', + bigcup: '⋃', + bigodot: '⨀', + bigoplus: '⨁', + bigotimes: '⨂', + bigsqcup: '⨆', + bigstar: '★', + bigtriangledown: '▽', + bigtriangleup: '△', + biguplus: '⨄', + bigvee: '⋁', + bigwedge: '⋀', + bkarow: '⤍', + blacklozenge: '⧫', + blacksquare: '▪', + blacktriangle: '▴', + blacktriangledown: '▾', + blacktriangleleft: '◂', + blacktriangleright: '▸', + blank: '␣', + blk12: '▒', + blk14: '░', + blk34: '▓', + block: '█', + bne: '=⃥', + bnequiv: '≡⃥', + bnot: '⌐', + bopf: '𝕓', + bot: '⊥', + bottom: '⊥', + bowtie: '⋈', + boxDL: '╗', + boxDR: '╔', + boxDl: '╖', + boxDr: '╓', + boxH: '═', + boxHD: '╦', + boxHU: '╩', + boxHd: '╤', + boxHu: '╧', + boxUL: '╝', + boxUR: '╚', + boxUl: '╜', + boxUr: '╙', + boxV: '║', + boxVH: '╬', + boxVL: '╣', + boxVR: '╠', + boxVh: '╫', + boxVl: '╢', + boxVr: '╟', + boxbox: '⧉', + boxdL: '╕', + boxdR: '╒', + boxdl: '┐', + boxdr: '┌', + boxh: '─', + boxhD: '╥', + boxhU: '╨', + boxhd: '┬', + boxhu: '┴', + boxminus: '⊟', + boxplus: '⊞', + boxtimes: '⊠', + boxuL: '╛', + boxuR: '╘', + boxul: '┘', + boxur: '└', + boxv: '│', + boxvH: '╪', + boxvL: '╡', + boxvR: '╞', + boxvh: '┼', + boxvl: '┤', + boxvr: '├', + bprime: '‵', + breve: '˘', + brvba: '¦', + brvbar: '¦', + bscr: '𝒷', + bsemi: '⁏', + bsim: '∽', + bsime: '⋍', + bsol: '\\', + bsolb: '⧅', + bsolhsub: '⟈', + bull: '•', + bullet: '•', + bump: '≎', + bumpE: '⪮', + bumpe: '≏', + bumpeq: '≏', + cacute: 'ć', + cap: '∩', + capand: '⩄', + capbrcup: '⩉', + capcap: '⩋', + capcup: '⩇', + capdot: '⩀', + caps: '∩︀', + caret: '⁁', + caron: 'ˇ', + ccaps: '⩍', + ccaron: 'č', + ccedi: 'ç', + ccedil: 'ç', + ccirc: 'ĉ', + ccups: '⩌', + ccupssm: '⩐', + cdot: 'ċ', + cedi: '¸', + cedil: '¸', + cemptyv: '⦲', + cen: '¢', + cent: '¢', + centerdot: '·', + cfr: '𝔠', + chcy: 'ч', + check: '✓', + checkmark: '✓', + chi: 'χ', + cir: '○', + cirE: '⧃', + circ: 'ˆ', + circeq: '≗', + circlearrowleft: '↺', + circlearrowright: '↻', + circledR: '®', + circledS: 'Ⓢ', + circledast: '⊛', + circledcirc: '⊚', + circleddash: '⊝', + cire: '≗', + cirfnint: '⨐', + cirmid: '⫯', + cirscir: '⧂', + clubs: '♣', + clubsuit: '♣', + colon: ':', + colone: '≔', + coloneq: '≔', + comma: ',', + commat: '@', + comp: '∁', + compfn: '∘', + complement: '∁', + complexes: 'ℂ', + cong: '≅', + congdot: '⩭', + conint: '∮', + copf: '𝕔', + coprod: '∐', + cop: '©', + copy: '©', + copysr: '℗', + crarr: '↵', + cross: '✗', + cscr: '𝒸', + csub: '⫏', + csube: '⫑', + csup: '⫐', + csupe: '⫒', + ctdot: '⋯', + cudarrl: '⤸', + cudarrr: '⤵', + cuepr: '⋞', + cuesc: '⋟', + cularr: '↶', + cularrp: '⤽', + cup: '∪', + cupbrcap: '⩈', + cupcap: '⩆', + cupcup: '⩊', + cupdot: '⊍', + cupor: '⩅', + cups: '∪︀', + curarr: '↷', + curarrm: '⤼', + curlyeqprec: '⋞', + curlyeqsucc: '⋟', + curlyvee: '⋎', + curlywedge: '⋏', + curre: '¤', + curren: '¤', + curvearrowleft: '↶', + curvearrowright: '↷', + cuvee: '⋎', + cuwed: '⋏', + cwconint: '∲', + cwint: '∱', + cylcty: '⌭', + dArr: '⇓', + dHar: '⥥', + dagger: '†', + daleth: 'ℸ', + darr: '↓', + dash: '‐', + dashv: '⊣', + dbkarow: '⤏', + dblac: '˝', + dcaron: 'ď', + dcy: 'д', + dd: 'ⅆ', + ddagger: '‡', + ddarr: '⇊', + ddotseq: '⩷', + de: '°', + deg: '°', + delta: 'δ', + demptyv: '⦱', + dfisht: '⥿', + dfr: '𝔡', + dharl: '⇃', + dharr: '⇂', + diam: '⋄', + diamond: '⋄', + diamondsuit: '♦', + diams: '♦', + die: '¨', + digamma: 'ϝ', + disin: '⋲', + div: '÷', + divid: '÷', + divide: '÷', + divideontimes: '⋇', + divonx: '⋇', + djcy: 'ђ', + dlcorn: '⌞', + dlcrop: '⌍', + dollar: '$', + dopf: '𝕕', + dot: '˙', + doteq: '≐', + doteqdot: '≑', + dotminus: '∸', + dotplus: '∔', + dotsquare: '⊡', + doublebarwedge: '⌆', + downarrow: '↓', + downdownarrows: '⇊', + downharpoonleft: '⇃', + downharpoonright: '⇂', + drbkarow: '⤐', + drcorn: '⌟', + drcrop: '⌌', + dscr: '𝒹', + dscy: 'ѕ', + dsol: '⧶', + dstrok: 'đ', + dtdot: '⋱', + dtri: '▿', + dtrif: '▾', + duarr: '⇵', + duhar: '⥯', + dwangle: '⦦', + dzcy: 'џ', + dzigrarr: '⟿', + eDDot: '⩷', + eDot: '≑', + eacut: 'é', + eacute: 'é', + easter: '⩮', + ecaron: 'ě', + ecir: 'ê', + ecirc: 'ê', + ecolon: '≕', + ecy: 'э', + edot: 'ė', + ee: 'ⅇ', + efDot: '≒', + efr: '𝔢', + eg: '⪚', + egrav: 'è', + egrave: 'è', + egs: '⪖', + egsdot: '⪘', + el: '⪙', + elinters: '⏧', + ell: 'ℓ', + els: '⪕', + elsdot: '⪗', + emacr: 'ē', + empty: '∅', + emptyset: '∅', + emptyv: '∅', + emsp13: ' ', + emsp14: ' ', + emsp: ' ', + eng: 'ŋ', + ensp: ' ', + eogon: 'ę', + eopf: '𝕖', + epar: '⋕', + eparsl: '⧣', + eplus: '⩱', + epsi: 'ε', + epsilon: 'ε', + epsiv: 'ϵ', + eqcirc: '≖', + eqcolon: '≕', + eqsim: '≂', + eqslantgtr: '⪖', + eqslantless: '⪕', + equals: '=', + equest: '≟', + equiv: '≡', + equivDD: '⩸', + eqvparsl: '⧥', + erDot: '≓', + erarr: '⥱', + escr: 'ℯ', + esdot: '≐', + esim: '≂', + eta: 'η', + et: 'ð', + eth: 'ð', + eum: 'ë', + euml: 'ë', + euro: '€', + excl: '!', + exist: '∃', + expectation: 'ℰ', + exponentiale: 'ⅇ', + fallingdotseq: '≒', + fcy: 'ф', + female: '♀', + ffilig: 'ffi', + fflig: 'ff', + ffllig: 'ffl', + ffr: '𝔣', + filig: 'fi', + fjlig: 'fj', + flat: '♭', + fllig: 'fl', + fltns: '▱', + fnof: 'ƒ', + fopf: '𝕗', + forall: '∀', + fork: '⋔', + forkv: '⫙', + fpartint: '⨍', + frac1: '¼', + frac12: '½', + frac13: '⅓', + frac14: '¼', + frac15: '⅕', + frac16: '⅙', + frac18: '⅛', + frac23: '⅔', + frac25: '⅖', + frac3: '¾', + frac34: '¾', + frac35: '⅗', + frac38: '⅜', + frac45: '⅘', + frac56: '⅚', + frac58: '⅝', + frac78: '⅞', + frasl: '⁄', + frown: '⌢', + fscr: '𝒻', + gE: '≧', + gEl: '⪌', + gacute: 'ǵ', + gamma: 'γ', + gammad: 'ϝ', + gap: '⪆', + gbreve: 'ğ', + gcirc: 'ĝ', + gcy: 'г', + gdot: 'ġ', + ge: '≥', + gel: '⋛', + geq: '≥', + geqq: '≧', + geqslant: '⩾', + ges: '⩾', + gescc: '⪩', + gesdot: '⪀', + gesdoto: '⪂', + gesdotol: '⪄', + gesl: '⋛︀', + gesles: '⪔', + gfr: '𝔤', + gg: '≫', + ggg: '⋙', + gimel: 'ℷ', + gjcy: 'ѓ', + gl: '≷', + glE: '⪒', + gla: '⪥', + glj: '⪤', + gnE: '≩', + gnap: '⪊', + gnapprox: '⪊', + gne: '⪈', + gneq: '⪈', + gneqq: '≩', + gnsim: '⋧', + gopf: '𝕘', + grave: '`', + gscr: 'ℊ', + gsim: '≳', + gsime: '⪎', + gsiml: '⪐', + g: '>', + gt: '>', + gtcc: '⪧', + gtcir: '⩺', + gtdot: '⋗', + gtlPar: '⦕', + gtquest: '⩼', + gtrapprox: '⪆', + gtrarr: '⥸', + gtrdot: '⋗', + gtreqless: '⋛', + gtreqqless: '⪌', + gtrless: '≷', + gtrsim: '≳', + gvertneqq: '≩︀', + gvnE: '≩︀', + hArr: '⇔', + hairsp: ' ', + half: '½', + hamilt: 'ℋ', + hardcy: 'ъ', + harr: '↔', + harrcir: '⥈', + harrw: '↭', + hbar: 'ℏ', + hcirc: 'ĥ', + hearts: '♥', + heartsuit: '♥', + hellip: '…', + hercon: '⊹', + hfr: '𝔥', + hksearow: '⤥', + hkswarow: '⤦', + hoarr: '⇿', + homtht: '∻', + hookleftarrow: '↩', + hookrightarrow: '↪', + hopf: '𝕙', + horbar: '―', + hscr: '𝒽', + hslash: 'ℏ', + hstrok: 'ħ', + hybull: '⁃', + hyphen: '‐', + iacut: 'í', + iacute: 'í', + ic: '⁣', + icir: 'î', + icirc: 'î', + icy: 'и', + iecy: 'е', + iexc: '¡', + iexcl: '¡', + iff: '⇔', + ifr: '𝔦', + igrav: 'ì', + igrave: 'ì', + ii: 'ⅈ', + iiiint: '⨌', + iiint: '∭', + iinfin: '⧜', + iiota: '℩', + ijlig: 'ij', + imacr: 'ī', + image: 'ℑ', + imagline: 'ℐ', + imagpart: 'ℑ', + imath: 'ı', + imof: '⊷', + imped: 'Ƶ', + in: '∈', + incare: '℅', + infin: '∞', + infintie: '⧝', + inodot: 'ı', + int: '∫', + intcal: '⊺', + integers: 'ℤ', + intercal: '⊺', + intlarhk: '⨗', + intprod: '⨼', + iocy: 'ё', + iogon: 'į', + iopf: '𝕚', + iota: 'ι', + iprod: '⨼', + iques: '¿', + iquest: '¿', + iscr: '𝒾', + isin: '∈', + isinE: '⋹', + isindot: '⋵', + isins: '⋴', + isinsv: '⋳', + isinv: '∈', + it: '⁢', + itilde: 'ĩ', + iukcy: 'і', + ium: 'ï', + iuml: 'ï', + jcirc: 'ĵ', + jcy: 'й', + jfr: '𝔧', + jmath: 'ȷ', + jopf: '𝕛', + jscr: '𝒿', + jsercy: 'ј', + jukcy: 'є', + kappa: 'κ', + kappav: 'ϰ', + kcedil: 'ķ', + kcy: 'к', + kfr: '𝔨', + kgreen: 'ĸ', + khcy: 'х', + kjcy: 'ќ', + kopf: '𝕜', + kscr: '𝓀', + lAarr: '⇚', + lArr: '⇐', + lAtail: '⤛', + lBarr: '⤎', + lE: '≦', + lEg: '⪋', + lHar: '⥢', + lacute: 'ĺ', + laemptyv: '⦴', + lagran: 'ℒ', + lambda: 'λ', + lang: '⟨', + langd: '⦑', + langle: '⟨', + lap: '⪅', + laqu: '«', + laquo: '«', + larr: '←', + larrb: '⇤', + larrbfs: '⤟', + larrfs: '⤝', + larrhk: '↩', + larrlp: '↫', + larrpl: '⤹', + larrsim: '⥳', + larrtl: '↢', + lat: '⪫', + latail: '⤙', + late: '⪭', + lates: '⪭︀', + lbarr: '⤌', + lbbrk: '❲', + lbrace: '{', + lbrack: '[', + lbrke: '⦋', + lbrksld: '⦏', + lbrkslu: '⦍', + lcaron: 'ľ', + lcedil: 'ļ', + lceil: '⌈', + lcub: '{', + lcy: 'л', + ldca: '⤶', + ldquo: '“', + ldquor: '„', + ldrdhar: '⥧', + ldrushar: '⥋', + ldsh: '↲', + le: '≤', + leftarrow: '←', + leftarrowtail: '↢', + leftharpoondown: '↽', + leftharpoonup: '↼', + leftleftarrows: '⇇', + leftrightarrow: '↔', + leftrightarrows: '⇆', + leftrightharpoons: '⇋', + leftrightsquigarrow: '↭', + leftthreetimes: '⋋', + leg: '⋚', + leq: '≤', + leqq: '≦', + leqslant: '⩽', + les: '⩽', + lescc: '⪨', + lesdot: '⩿', + lesdoto: '⪁', + lesdotor: '⪃', + lesg: '⋚︀', + lesges: '⪓', + lessapprox: '⪅', + lessdot: '⋖', + lesseqgtr: '⋚', + lesseqqgtr: '⪋', + lessgtr: '≶', + lesssim: '≲', + lfisht: '⥼', + lfloor: '⌊', + lfr: '𝔩', + lg: '≶', + lgE: '⪑', + lhard: '↽', + lharu: '↼', + lharul: '⥪', + lhblk: '▄', + ljcy: 'љ', + ll: '≪', + llarr: '⇇', + llcorner: '⌞', + llhard: '⥫', + lltri: '◺', + lmidot: 'ŀ', + lmoust: '⎰', + lmoustache: '⎰', + lnE: '≨', + lnap: '⪉', + lnapprox: '⪉', + lne: '⪇', + lneq: '⪇', + lneqq: '≨', + lnsim: '⋦', + loang: '⟬', + loarr: '⇽', + lobrk: '⟦', + longleftarrow: '⟵', + longleftrightarrow: '⟷', + longmapsto: '⟼', + longrightarrow: '⟶', + looparrowleft: '↫', + looparrowright: '↬', + lopar: '⦅', + lopf: '𝕝', + loplus: '⨭', + lotimes: '⨴', + lowast: '∗', + lowbar: '_', + loz: '◊', + lozenge: '◊', + lozf: '⧫', + lpar: '(', + lparlt: '⦓', + lrarr: '⇆', + lrcorner: '⌟', + lrhar: '⇋', + lrhard: '⥭', + lrm: '‎', + lrtri: '⊿', + lsaquo: '‹', + lscr: '𝓁', + lsh: '↰', + lsim: '≲', + lsime: '⪍', + lsimg: '⪏', + lsqb: '[', + lsquo: '‘', + lsquor: '‚', + lstrok: 'ł', + l: '<', + lt: '<', + ltcc: '⪦', + ltcir: '⩹', + ltdot: '⋖', + lthree: '⋋', + ltimes: '⋉', + ltlarr: '⥶', + ltquest: '⩻', + ltrPar: '⦖', + ltri: '◃', + ltrie: '⊴', + ltrif: '◂', + lurdshar: '⥊', + luruhar: '⥦', + lvertneqq: '≨︀', + lvnE: '≨︀', + mDDot: '∺', + mac: '¯', + macr: '¯', + male: '♂', + malt: '✠', + maltese: '✠', + map: '↦', + mapsto: '↦', + mapstodown: '↧', + mapstoleft: '↤', + mapstoup: '↥', + marker: '▮', + mcomma: '⨩', + mcy: 'м', + mdash: '—', + measuredangle: '∡', + mfr: '𝔪', + mho: '℧', + micr: 'µ', + micro: 'µ', + mid: '∣', + midast: '*', + midcir: '⫰', + middo: '·', + middot: '·', + minus: '−', + minusb: '⊟', + minusd: '∸', + minusdu: '⨪', + mlcp: '⫛', + mldr: '…', + mnplus: '∓', + models: '⊧', + mopf: '𝕞', + mp: '∓', + mscr: '𝓂', + mstpos: '∾', + mu: 'μ', + multimap: '⊸', + mumap: '⊸', + nGg: '⋙̸', + nGt: '≫⃒', + nGtv: '≫̸', + nLeftarrow: '⇍', + nLeftrightarrow: '⇎', + nLl: '⋘̸', + nLt: '≪⃒', + nLtv: '≪̸', + nRightarrow: '⇏', + nVDash: '⊯', + nVdash: '⊮', + nabla: '∇', + nacute: 'ń', + nang: '∠⃒', + nap: '≉', + napE: '⩰̸', + napid: '≋̸', + napos: 'ʼn', + napprox: '≉', + natur: '♮', + natural: '♮', + naturals: 'ℕ', + nbs: ' ', + nbsp: ' ', + nbump: '≎̸', + nbumpe: '≏̸', + ncap: '⩃', + ncaron: 'ň', + ncedil: 'ņ', + ncong: '≇', + ncongdot: '⩭̸', + ncup: '⩂', + ncy: 'н', + ndash: '–', + ne: '≠', + neArr: '⇗', + nearhk: '⤤', + nearr: '↗', + nearrow: '↗', + nedot: '≐̸', + nequiv: '≢', + nesear: '⤨', + nesim: '≂̸', + nexist: '∄', + nexists: '∄', + nfr: '𝔫', + ngE: '≧̸', + nge: '≱', + ngeq: '≱', + ngeqq: '≧̸', + ngeqslant: '⩾̸', + nges: '⩾̸', + ngsim: '≵', + ngt: '≯', + ngtr: '≯', + nhArr: '⇎', + nharr: '↮', + nhpar: '⫲', + ni: '∋', + nis: '⋼', + nisd: '⋺', + niv: '∋', + njcy: 'њ', + nlArr: '⇍', + nlE: '≦̸', + nlarr: '↚', + nldr: '‥', + nle: '≰', + nleftarrow: '↚', + nleftrightarrow: '↮', + nleq: '≰', + nleqq: '≦̸', + nleqslant: '⩽̸', + nles: '⩽̸', + nless: '≮', + nlsim: '≴', + nlt: '≮', + nltri: '⋪', + nltrie: '⋬', + nmid: '∤', + nopf: '𝕟', + no: '¬', + not: '¬', + notin: '∉', + notinE: '⋹̸', + notindot: '⋵̸', + notinva: '∉', + notinvb: '⋷', + notinvc: '⋶', + notni: '∌', + notniva: '∌', + notnivb: '⋾', + notnivc: '⋽', + npar: '∦', + nparallel: '∦', + nparsl: '⫽⃥', + npart: '∂̸', + npolint: '⨔', + npr: '⊀', + nprcue: '⋠', + npre: '⪯̸', + nprec: '⊀', + npreceq: '⪯̸', + nrArr: '⇏', + nrarr: '↛', + nrarrc: '⤳̸', + nrarrw: '↝̸', + nrightarrow: '↛', + nrtri: '⋫', + nrtrie: '⋭', + nsc: '⊁', + nsccue: '⋡', + nsce: '⪰̸', + nscr: '𝓃', + nshortmid: '∤', + nshortparallel: '∦', + nsim: '≁', + nsime: '≄', + nsimeq: '≄', + nsmid: '∤', + nspar: '∦', + nsqsube: '⋢', + nsqsupe: '⋣', + nsub: '⊄', + nsubE: '⫅̸', + nsube: '⊈', + nsubset: '⊂⃒', + nsubseteq: '⊈', + nsubseteqq: '⫅̸', + nsucc: '⊁', + nsucceq: '⪰̸', + nsup: '⊅', + nsupE: '⫆̸', + nsupe: '⊉', + nsupset: '⊃⃒', + nsupseteq: '⊉', + nsupseteqq: '⫆̸', + ntgl: '≹', + ntild: 'ñ', + ntilde: 'ñ', + ntlg: '≸', + ntriangleleft: '⋪', + ntrianglelefteq: '⋬', + ntriangleright: '⋫', + ntrianglerighteq: '⋭', + nu: 'ν', + num: '#', + numero: '№', + numsp: ' ', + nvDash: '⊭', + nvHarr: '⤄', + nvap: '≍⃒', + nvdash: '⊬', + nvge: '≥⃒', + nvgt: '>⃒', + nvinfin: '⧞', + nvlArr: '⤂', + nvle: '≤⃒', + nvlt: '<⃒', + nvltrie: '⊴⃒', + nvrArr: '⤃', + nvrtrie: '⊵⃒', + nvsim: '∼⃒', + nwArr: '⇖', + nwarhk: '⤣', + nwarr: '↖', + nwarrow: '↖', + nwnear: '⤧', + oS: 'Ⓢ', + oacut: 'ó', + oacute: 'ó', + oast: '⊛', + ocir: 'ô', + ocirc: 'ô', + ocy: 'о', + odash: '⊝', + odblac: 'ő', + odiv: '⨸', + odot: '⊙', + odsold: '⦼', + oelig: 'œ', + ofcir: '⦿', + ofr: '𝔬', + ogon: '˛', + ograv: 'ò', + ograve: 'ò', + ogt: '⧁', + ohbar: '⦵', + ohm: 'Ω', + oint: '∮', + olarr: '↺', + olcir: '⦾', + olcross: '⦻', + oline: '‾', + olt: '⧀', + omacr: 'ō', + omega: 'ω', + omicron: 'ο', + omid: '⦶', + ominus: '⊖', + oopf: '𝕠', + opar: '⦷', + operp: '⦹', + oplus: '⊕', + or: '∨', + orarr: '↻', + ord: 'º', + order: 'ℴ', + orderof: 'ℴ', + ordf: 'ª', + ordm: 'º', + origof: '⊶', + oror: '⩖', + orslope: '⩗', + orv: '⩛', + oscr: 'ℴ', + oslas: 'ø', + oslash: 'ø', + osol: '⊘', + otild: 'õ', + otilde: 'õ', + otimes: '⊗', + otimesas: '⨶', + oum: 'ö', + ouml: 'ö', + ovbar: '⌽', + par: '¶', + para: '¶', + parallel: '∥', + parsim: '⫳', + parsl: '⫽', + part: '∂', + pcy: 'п', + percnt: '%', + period: '.', + permil: '‰', + perp: '⊥', + pertenk: '‱', + pfr: '𝔭', + phi: 'φ', + phiv: 'ϕ', + phmmat: 'ℳ', + phone: '☎', + pi: 'π', + pitchfork: '⋔', + piv: 'ϖ', + planck: 'ℏ', + planckh: 'ℎ', + plankv: 'ℏ', + plus: '+', + plusacir: '⨣', + plusb: '⊞', + pluscir: '⨢', + plusdo: '∔', + plusdu: '⨥', + pluse: '⩲', + plusm: '±', + plusmn: '±', + plussim: '⨦', + plustwo: '⨧', + pm: '±', + pointint: '⨕', + popf: '𝕡', + poun: '£', + pound: '£', + pr: '≺', + prE: '⪳', + prap: '⪷', + prcue: '≼', + pre: '⪯', + prec: '≺', + precapprox: '⪷', + preccurlyeq: '≼', + preceq: '⪯', + precnapprox: '⪹', + precneqq: '⪵', + precnsim: '⋨', + precsim: '≾', + prime: '′', + primes: 'ℙ', + prnE: '⪵', + prnap: '⪹', + prnsim: '⋨', + prod: '∏', + profalar: '⌮', + profline: '⌒', + profsurf: '⌓', + prop: '∝', + propto: '∝', + prsim: '≾', + prurel: '⊰', + pscr: '𝓅', + psi: 'ψ', + puncsp: ' ', + qfr: '𝔮', + qint: '⨌', + qopf: '𝕢', + qprime: '⁗', + qscr: '𝓆', + quaternions: 'ℍ', + quatint: '⨖', + quest: '?', + questeq: '≟', + quo: '"', + quot: '"', + rAarr: '⇛', + rArr: '⇒', + rAtail: '⤜', + rBarr: '⤏', + rHar: '⥤', + race: '∽̱', + racute: 'ŕ', + radic: '√', + raemptyv: '⦳', + rang: '⟩', + rangd: '⦒', + range: '⦥', + rangle: '⟩', + raqu: '»', + raquo: '»', + rarr: '→', + rarrap: '⥵', + rarrb: '⇥', + rarrbfs: '⤠', + rarrc: '⤳', + rarrfs: '⤞', + rarrhk: '↪', + rarrlp: '↬', + rarrpl: '⥅', + rarrsim: '⥴', + rarrtl: '↣', + rarrw: '↝', + ratail: '⤚', + ratio: '∶', + rationals: 'ℚ', + rbarr: '⤍', + rbbrk: '❳', + rbrace: '}', + rbrack: ']', + rbrke: '⦌', + rbrksld: '⦎', + rbrkslu: '⦐', + rcaron: 'ř', + rcedil: 'ŗ', + rceil: '⌉', + rcub: '}', + rcy: 'р', + rdca: '⤷', + rdldhar: '⥩', + rdquo: '”', + rdquor: '”', + rdsh: '↳', + real: 'ℜ', + realine: 'ℛ', + realpart: 'ℜ', + reals: 'ℝ', + rect: '▭', + re: '®', + reg: '®', + rfisht: '⥽', + rfloor: '⌋', + rfr: '𝔯', + rhard: '⇁', + rharu: '⇀', + rharul: '⥬', + rho: 'ρ', + rhov: 'ϱ', + rightarrow: '→', + rightarrowtail: '↣', + rightharpoondown: '⇁', + rightharpoonup: '⇀', + rightleftarrows: '⇄', + rightleftharpoons: '⇌', + rightrightarrows: '⇉', + rightsquigarrow: '↝', + rightthreetimes: '⋌', + ring: '˚', + risingdotseq: '≓', + rlarr: '⇄', + rlhar: '⇌', + rlm: '‏', + rmoust: '⎱', + rmoustache: '⎱', + rnmid: '⫮', + roang: '⟭', + roarr: '⇾', + robrk: '⟧', + ropar: '⦆', + ropf: '𝕣', + roplus: '⨮', + rotimes: '⨵', + rpar: ')', + rpargt: '⦔', + rppolint: '⨒', + rrarr: '⇉', + rsaquo: '›', + rscr: '𝓇', + rsh: '↱', + rsqb: ']', + rsquo: '’', + rsquor: '’', + rthree: '⋌', + rtimes: '⋊', + rtri: '▹', + rtrie: '⊵', + rtrif: '▸', + rtriltri: '⧎', + ruluhar: '⥨', + rx: '℞', + sacute: 'ś', + sbquo: '‚', + sc: '≻', + scE: '⪴', + scap: '⪸', + scaron: 'š', + sccue: '≽', + sce: '⪰', + scedil: 'ş', + scirc: 'ŝ', + scnE: '⪶', + scnap: '⪺', + scnsim: '⋩', + scpolint: '⨓', + scsim: '≿', + scy: 'с', + sdot: '⋅', + sdotb: '⊡', + sdote: '⩦', + seArr: '⇘', + searhk: '⤥', + searr: '↘', + searrow: '↘', + sec: '§', + sect: '§', + semi: ';', + seswar: '⤩', + setminus: '∖', + setmn: '∖', + sext: '✶', + sfr: '𝔰', + sfrown: '⌢', + sharp: '♯', + shchcy: 'щ', + shcy: 'ш', + shortmid: '∣', + shortparallel: '∥', + sh: '­', + shy: '­', + sigma: 'σ', + sigmaf: 'ς', + sigmav: 'ς', + sim: '∼', + simdot: '⩪', + sime: '≃', + simeq: '≃', + simg: '⪞', + simgE: '⪠', + siml: '⪝', + simlE: '⪟', + simne: '≆', + simplus: '⨤', + simrarr: '⥲', + slarr: '←', + smallsetminus: '∖', + smashp: '⨳', + smeparsl: '⧤', + smid: '∣', + smile: '⌣', + smt: '⪪', + smte: '⪬', + smtes: '⪬︀', + softcy: 'ь', + sol: '/', + solb: '⧄', + solbar: '⌿', + sopf: '𝕤', + spades: '♠', + spadesuit: '♠', + spar: '∥', + sqcap: '⊓', + sqcaps: '⊓︀', + sqcup: '⊔', + sqcups: '⊔︀', + sqsub: '⊏', + sqsube: '⊑', + sqsubset: '⊏', + sqsubseteq: '⊑', + sqsup: '⊐', + sqsupe: '⊒', + sqsupset: '⊐', + sqsupseteq: '⊒', + squ: '□', + square: '□', + squarf: '▪', + squf: '▪', + srarr: '→', + sscr: '𝓈', + ssetmn: '∖', + ssmile: '⌣', + sstarf: '⋆', + star: '☆', + starf: '★', + straightepsilon: 'ϵ', + straightphi: 'ϕ', + strns: '¯', + sub: '⊂', + subE: '⫅', + subdot: '⪽', + sube: '⊆', + subedot: '⫃', + submult: '⫁', + subnE: '⫋', + subne: '⊊', + subplus: '⪿', + subrarr: '⥹', + subset: '⊂', + subseteq: '⊆', + subseteqq: '⫅', + subsetneq: '⊊', + subsetneqq: '⫋', + subsim: '⫇', + subsub: '⫕', + subsup: '⫓', + succ: '≻', + succapprox: '⪸', + succcurlyeq: '≽', + succeq: '⪰', + succnapprox: '⪺', + succneqq: '⪶', + succnsim: '⋩', + succsim: '≿', + sum: '∑', + sung: '♪', + sup: '⊃', + sup1: '¹', + sup2: '²', + sup3: '³', + supE: '⫆', + supdot: '⪾', + supdsub: '⫘', + supe: '⊇', + supedot: '⫄', + suphsol: '⟉', + suphsub: '⫗', + suplarr: '⥻', + supmult: '⫂', + supnE: '⫌', + supne: '⊋', + supplus: '⫀', + supset: '⊃', + supseteq: '⊇', + supseteqq: '⫆', + supsetneq: '⊋', + supsetneqq: '⫌', + supsim: '⫈', + supsub: '⫔', + supsup: '⫖', + swArr: '⇙', + swarhk: '⤦', + swarr: '↙', + swarrow: '↙', + swnwar: '⤪', + szli: 'ß', + szlig: 'ß', + target: '⌖', + tau: 'τ', + tbrk: '⎴', + tcaron: 'ť', + tcedil: 'ţ', + tcy: 'т', + tdot: '⃛', + telrec: '⌕', + tfr: '𝔱', + there4: '∴', + therefore: '∴', + theta: 'θ', + thetasym: 'ϑ', + thetav: 'ϑ', + thickapprox: '≈', + thicksim: '∼', + thinsp: ' ', + thkap: '≈', + thksim: '∼', + thor: 'þ', + thorn: 'þ', + tilde: '˜', + time: '×', + times: '×', + timesb: '⊠', + timesbar: '⨱', + timesd: '⨰', + tint: '∭', + toea: '⤨', + top: '⊤', + topbot: '⌶', + topcir: '⫱', + topf: '𝕥', + topfork: '⫚', + tosa: '⤩', + tprime: '‴', + trade: '™', + triangle: '▵', + triangledown: '▿', + triangleleft: '◃', + trianglelefteq: '⊴', + triangleq: '≜', + triangleright: '▹', + trianglerighteq: '⊵', + tridot: '◬', + trie: '≜', + triminus: '⨺', + triplus: '⨹', + trisb: '⧍', + tritime: '⨻', + trpezium: '⏢', + tscr: '𝓉', + tscy: 'ц', + tshcy: 'ћ', + tstrok: 'ŧ', + twixt: '≬', + twoheadleftarrow: '↞', + twoheadrightarrow: '↠', + uArr: '⇑', + uHar: '⥣', + uacut: 'ú', + uacute: 'ú', + uarr: '↑', + ubrcy: 'ў', + ubreve: 'ŭ', + ucir: 'û', + ucirc: 'û', + ucy: 'у', + udarr: '⇅', + udblac: 'ű', + udhar: '⥮', + ufisht: '⥾', + ufr: '𝔲', + ugrav: 'ù', + ugrave: 'ù', + uharl: '↿', + uharr: '↾', + uhblk: '▀', + ulcorn: '⌜', + ulcorner: '⌜', + ulcrop: '⌏', + ultri: '◸', + umacr: 'ū', + um: '¨', + uml: '¨', + uogon: 'ų', + uopf: '𝕦', + uparrow: '↑', + updownarrow: '↕', + upharpoonleft: '↿', + upharpoonright: '↾', + uplus: '⊎', + upsi: 'υ', + upsih: 'ϒ', + upsilon: 'υ', + upuparrows: '⇈', + urcorn: '⌝', + urcorner: '⌝', + urcrop: '⌎', + uring: 'ů', + urtri: '◹', + uscr: '𝓊', + utdot: '⋰', + utilde: 'ũ', + utri: '▵', + utrif: '▴', + uuarr: '⇈', + uum: 'ü', + uuml: 'ü', + uwangle: '⦧', + vArr: '⇕', + vBar: '⫨', + vBarv: '⫩', + vDash: '⊨', + vangrt: '⦜', + varepsilon: 'ϵ', + varkappa: 'ϰ', + varnothing: '∅', + varphi: 'ϕ', + varpi: 'ϖ', + varpropto: '∝', + varr: '↕', + varrho: 'ϱ', + varsigma: 'ς', + varsubsetneq: '⊊︀', + varsubsetneqq: '⫋︀', + varsupsetneq: '⊋︀', + varsupsetneqq: '⫌︀', + vartheta: 'ϑ', + vartriangleleft: '⊲', + vartriangleright: '⊳', + vcy: 'в', + vdash: '⊢', + vee: '∨', + veebar: '⊻', + veeeq: '≚', + vellip: '⋮', + verbar: '|', + vert: '|', + vfr: '𝔳', + vltri: '⊲', + vnsub: '⊂⃒', + vnsup: '⊃⃒', + vopf: '𝕧', + vprop: '∝', + vrtri: '⊳', + vscr: '𝓋', + vsubnE: '⫋︀', + vsubne: '⊊︀', + vsupnE: '⫌︀', + vsupne: '⊋︀', + vzigzag: '⦚', + wcirc: 'ŵ', + wedbar: '⩟', + wedge: '∧', + wedgeq: '≙', + weierp: '℘', + wfr: '𝔴', + wopf: '𝕨', + wp: '℘', + wr: '≀', + wreath: '≀', + wscr: '𝓌', + xcap: '⋂', + xcirc: '◯', + xcup: '⋃', + xdtri: '▽', + xfr: '𝔵', + xhArr: '⟺', + xharr: '⟷', + xi: 'ξ', + xlArr: '⟸', + xlarr: '⟵', + xmap: '⟼', + xnis: '⋻', + xodot: '⨀', + xopf: '𝕩', + xoplus: '⨁', + xotime: '⨂', + xrArr: '⟹', + xrarr: '⟶', + xscr: '𝓍', + xsqcup: '⨆', + xuplus: '⨄', + xutri: '△', + xvee: '⋁', + xwedge: '⋀', + yacut: 'ý', + yacute: 'ý', + yacy: 'я', + ycirc: 'ŷ', + ycy: 'ы', + ye: '¥', + yen: '¥', + yfr: '𝔶', + yicy: 'ї', + yopf: '𝕪', + yscr: '𝓎', + yucy: 'ю', + yum: 'ÿ', + yuml: 'ÿ', + zacute: 'ź', + zcaron: 'ž', + zcy: 'з', + zdot: 'ż', + zeetrf: 'ℨ', + zeta: 'ζ', + zfr: '𝔷', + zhcy: 'ж', + zigrarr: '⇝', + zopf: '𝕫', + zscr: '𝓏', + zwj: '‍', + zwnj: '‌' +}; + +var own$6 = {}.hasOwnProperty; + +/** + * @param {string} characters + * @returns {string|false} + */ +function decodeEntity(characters) { + return own$6.call(characterEntities, characters) + ? characterEntities[characters] + : false +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const characterReference = { + name: 'characterReference', + tokenize: tokenizeCharacterReference +}; +/** @type {Tokenizer} */ + +function tokenizeCharacterReference(effects, ok, nok) { + const self = this; + let size = 0; + /** @type {number} */ + + let max; + /** @type {(code: Code) => code is number} */ + + let test; + return start + /** @type {State} */ + + function start(code) { + effects.enter('characterReference'); + effects.enter('characterReferenceMarker'); + effects.consume(code); + effects.exit('characterReferenceMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 35) { + effects.enter('characterReferenceMarkerNumeric'); + effects.consume(code); + effects.exit('characterReferenceMarkerNumeric'); + return numeric + } + + effects.enter('characterReferenceValue'); + max = 31; + test = asciiAlphanumeric; + return value(code) + } + /** @type {State} */ + + function numeric(code) { + if (code === 88 || code === 120) { + effects.enter('characterReferenceMarkerHexadecimal'); + effects.consume(code); + effects.exit('characterReferenceMarkerHexadecimal'); + effects.enter('characterReferenceValue'); + max = 6; + test = asciiHexDigit; + return value + } + + effects.enter('characterReferenceValue'); + max = 7; + test = asciiDigit; + return value(code) + } + /** @type {State} */ + + function value(code) { + /** @type {Token} */ + let token; + + if (code === 59 && size) { + token = effects.exit('characterReferenceValue'); + + if ( + test === asciiAlphanumeric && + !decodeEntity(self.sliceSerialize(token)) + ) { + return nok(code) + } + + effects.enter('characterReferenceMarker'); + effects.consume(code); + effects.exit('characterReferenceMarker'); + effects.exit('characterReference'); + return ok + } + + if (test(code) && size++ < max) { + effects.consume(code); + return value + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const codeFenced = { + name: 'codeFenced', + tokenize: tokenizeCodeFenced, + concrete: true +}; +/** @type {Tokenizer} */ + +function tokenizeCodeFenced(effects, ok, nok) { + const self = this; + /** @type {Construct} */ + + const closingFenceConstruct = { + tokenize: tokenizeClosingFence, + partial: true + }; + /** @type {Construct} */ + + const nonLazyLine = { + tokenize: tokenizeNonLazyLine, + partial: true + }; + const tail = this.events[this.events.length - 1]; + const initialPrefix = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0; + let sizeOpen = 0; + /** @type {NonNullable} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('codeFenced'); + effects.enter('codeFencedFence'); + effects.enter('codeFencedFenceSequence'); + marker = code; + return sequenceOpen(code) + } + /** @type {State} */ + + function sequenceOpen(code) { + if (code === marker) { + effects.consume(code); + sizeOpen++; + return sequenceOpen + } + + effects.exit('codeFencedFenceSequence'); + return sizeOpen < 3 + ? nok(code) + : factorySpace(effects, infoOpen, 'whitespace')(code) + } + /** @type {State} */ + + function infoOpen(code) { + if (code === null || markdownLineEnding(code)) { + return openAfter(code) + } + + effects.enter('codeFencedFenceInfo'); + effects.enter('chunkString', { + contentType: 'string' + }); + return info(code) + } + /** @type {State} */ + + function info(code) { + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('chunkString'); + effects.exit('codeFencedFenceInfo'); + return factorySpace(effects, infoAfter, 'whitespace')(code) + } + + if (code === 96 && code === marker) return nok(code) + effects.consume(code); + return info + } + /** @type {State} */ + + function infoAfter(code) { + if (code === null || markdownLineEnding(code)) { + return openAfter(code) + } + + effects.enter('codeFencedFenceMeta'); + effects.enter('chunkString', { + contentType: 'string' + }); + return meta(code) + } + /** @type {State} */ + + function meta(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('chunkString'); + effects.exit('codeFencedFenceMeta'); + return openAfter(code) + } + + if (code === 96 && code === marker) return nok(code) + effects.consume(code); + return meta + } + /** @type {State} */ + + function openAfter(code) { + effects.exit('codeFencedFence'); + return self.interrupt ? ok(code) : contentStart(code) + } + /** @type {State} */ + + function contentStart(code) { + if (code === null) { + return after(code) + } + + if (markdownLineEnding(code)) { + return effects.attempt( + nonLazyLine, + effects.attempt( + closingFenceConstruct, + after, + initialPrefix + ? factorySpace( + effects, + contentStart, + 'linePrefix', + initialPrefix + 1 + ) + : contentStart + ), + after + )(code) + } + + effects.enter('codeFlowValue'); + return contentContinue(code) + } + /** @type {State} */ + + function contentContinue(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue'); + return contentStart(code) + } + + effects.consume(code); + return contentContinue + } + /** @type {State} */ + + function after(code) { + effects.exit('codeFenced'); + return ok(code) + } + /** @type {Tokenizer} */ + + function tokenizeNonLazyLine(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return lineStart + } + /** @type {State} */ + + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } + } + /** @type {Tokenizer} */ + + function tokenizeClosingFence(effects, ok, nok) { + let size = 0; + return factorySpace( + effects, + closingSequenceStart, + 'linePrefix', + this.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + ) + /** @type {State} */ + + function closingSequenceStart(code) { + effects.enter('codeFencedFence'); + effects.enter('codeFencedFenceSequence'); + return closingSequence(code) + } + /** @type {State} */ + + function closingSequence(code) { + if (code === marker) { + effects.consume(code); + size++; + return closingSequence + } + + if (size < sizeOpen) return nok(code) + effects.exit('codeFencedFenceSequence'); + return factorySpace(effects, closingSequenceEnd, 'whitespace')(code) + } + /** @type {State} */ + + function closingSequenceEnd(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFencedFence'); + return ok(code) + } + + return nok(code) + } + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const codeIndented = { + name: 'codeIndented', + tokenize: tokenizeCodeIndented +}; +/** @type {Construct} */ + +const indentedContent = { + tokenize: tokenizeIndentedContent, + partial: true +}; +/** @type {Tokenizer} */ + +function tokenizeCodeIndented(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('codeIndented'); + return factorySpace(effects, afterStartPrefix, 'linePrefix', 4 + 1)(code) + } + /** @type {State} */ + + function afterStartPrefix(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? afterPrefix(code) + : nok(code) + } + /** @type {State} */ + + function afterPrefix(code) { + if (code === null) { + return after(code) + } + + if (markdownLineEnding(code)) { + return effects.attempt(indentedContent, afterPrefix, after)(code) + } + + effects.enter('codeFlowValue'); + return content(code) + } + /** @type {State} */ + + function content(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('codeFlowValue'); + return afterPrefix(code) + } + + effects.consume(code); + return content + } + /** @type {State} */ + + function after(code) { + effects.exit('codeIndented'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeIndentedContent(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + // If this is a lazy line, it can’t be code. + if (self.parser.lazy[self.now().line]) { + return nok(code) + } + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return start + } + + return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) + } + /** @type {State} */ + + function afterPrefix(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ? ok(code) + : markdownLineEnding(code) + ? start(code) + : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const codeText = { + name: 'codeText', + tokenize: tokenizeCodeText, + resolve: resolveCodeText, + previous: previous$1 +}; +/** @type {Resolver} */ + +function resolveCodeText(events) { + let tailExitIndex = events.length - 4; + let headEnterIndex = 3; + /** @type {number} */ + + let index; + /** @type {number|undefined} */ + + let enter; // If we start and end with an EOL or a space. + + if ( + (events[headEnterIndex][1].type === 'lineEnding' || + events[headEnterIndex][1].type === 'space') && + (events[tailExitIndex][1].type === 'lineEnding' || + events[tailExitIndex][1].type === 'space') + ) { + index = headEnterIndex; // And we have data. + + while (++index < tailExitIndex) { + if (events[index][1].type === 'codeTextData') { + // Then we have padding. + events[headEnterIndex][1].type = 'codeTextPadding'; + events[tailExitIndex][1].type = 'codeTextPadding'; + headEnterIndex += 2; + tailExitIndex -= 2; + break + } + } + } // Merge adjacent spaces and data. + + index = headEnterIndex - 1; + tailExitIndex++; + + while (++index <= tailExitIndex) { + if (enter === undefined) { + if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { + enter = index; + } + } else if ( + index === tailExitIndex || + events[index][1].type === 'lineEnding' + ) { + events[enter][1].type = 'codeTextData'; + + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end; + events.splice(enter + 2, index - enter - 2); + tailExitIndex -= index - enter - 2; + index = enter + 2; + } + + enter = undefined; + } + } + + return events +} +/** @type {Previous} */ + +function previous$1(code) { + // If there is a previous code, there will always be a tail. + return ( + code !== 96 || + this.events[this.events.length - 1][1].type === 'characterEscape' + ) +} +/** @type {Tokenizer} */ + +function tokenizeCodeText(effects, ok, nok) { + let sizeOpen = 0; + /** @type {number} */ + + let size; + /** @type {Token} */ + + let token; + return start + /** @type {State} */ + + function start(code) { + effects.enter('codeText'); + effects.enter('codeTextSequence'); + return openingSequence(code) + } + /** @type {State} */ + + function openingSequence(code) { + if (code === 96) { + effects.consume(code); + sizeOpen++; + return openingSequence + } + + effects.exit('codeTextSequence'); + return gap(code) + } + /** @type {State} */ + + function gap(code) { + // EOF. + if (code === null) { + return nok(code) + } // Closing fence? + // Could also be data. + + if (code === 96) { + token = effects.enter('codeTextSequence'); + size = 0; + return closingSequence(code) + } // Tabs don’t work, and virtual spaces don’t make sense. + + if (code === 32) { + effects.enter('space'); + effects.consume(code); + effects.exit('space'); + return gap + } + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return gap + } // Data. + + effects.enter('codeTextData'); + return data(code) + } // In code. + + /** @type {State} */ + + function data(code) { + if ( + code === null || + code === 32 || + code === 96 || + markdownLineEnding(code) + ) { + effects.exit('codeTextData'); + return gap(code) + } + + effects.consume(code); + return data + } // Closing fence. + + /** @type {State} */ + + function closingSequence(code) { + // More. + if (code === 96) { + effects.consume(code); + size++; + return closingSequence + } // Done! + + if (size === sizeOpen) { + effects.exit('codeTextSequence'); + effects.exit('codeText'); + return ok(code) + } // More or less accents: mark as data. + + token.type = 'codeTextData'; + return data(code) + } +} + +/** + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Event} Event + */ + +/** + * Tokenize subcontent. + * + * @param {Event[]} events + * @returns {boolean} + */ +function subtokenize(events) { + /** @type {Record} */ + const jumps = {}; + let index = -1; + /** @type {Event} */ + + let event; + /** @type {number|undefined} */ + + let lineIndex; + /** @type {number} */ + + let otherIndex; + /** @type {Event} */ + + let otherEvent; + /** @type {Event[]} */ + + let parameters; + /** @type {Event[]} */ + + let subevents; + /** @type {boolean|undefined} */ + + let more; + + while (++index < events.length) { + while (index in jumps) { + index = jumps[index]; + } + + event = events[index]; // Add a hook for the GFM tasklist extension, which needs to know if text + // is in the first content of a list item. + + if ( + index && + event[1].type === 'chunkFlow' && + events[index - 1][1].type === 'listItemPrefix' + ) { + subevents = event[1]._tokenizer.events; + otherIndex = 0; + + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'lineEndingBlank' + ) { + otherIndex += 2; + } + + if ( + otherIndex < subevents.length && + subevents[otherIndex][1].type === 'content' + ) { + while (++otherIndex < subevents.length) { + if (subevents[otherIndex][1].type === 'content') { + break + } + + if (subevents[otherIndex][1].type === 'chunkText') { + subevents[otherIndex][1]._isInFirstContentOfListItem = true; + otherIndex++; + } + } + } + } // Enter. + + if (event[0] === 'enter') { + if (event[1].contentType) { + Object.assign(jumps, subcontent(events, index)); + index = jumps[index]; + more = true; + } + } // Exit. + else if (event[1]._container) { + otherIndex = index; + lineIndex = undefined; + + while (otherIndex--) { + otherEvent = events[otherIndex]; + + if ( + otherEvent[1].type === 'lineEnding' || + otherEvent[1].type === 'lineEndingBlank' + ) { + if (otherEvent[0] === 'enter') { + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank'; + } + + otherEvent[1].type = 'lineEnding'; + lineIndex = otherIndex; + } + } else { + break + } + } + + if (lineIndex) { + // Fix position. + event[1].end = Object.assign({}, events[lineIndex][1].start); // Switch container exit w/ line endings. + + parameters = events.slice(lineIndex, index); + parameters.unshift(event); + splice(events, lineIndex, index - lineIndex + 1, parameters); + } + } + } + + return !more +} +/** + * Tokenize embedded tokens. + * + * @param {Event[]} events + * @param {number} eventIndex + * @returns {Record} + */ + +function subcontent(events, eventIndex) { + const token = events[eventIndex][1]; + const context = events[eventIndex][2]; + let startPosition = eventIndex - 1; + /** @type {number[]} */ + + const startPositions = []; + const tokenizer = + token._tokenizer || context.parser[token.contentType](token.start); + const childEvents = tokenizer.events; + /** @type {[number, number][]} */ + + const jumps = []; + /** @type {Record} */ + + const gaps = {}; + /** @type {Chunk[]} */ + + let stream; + /** @type {Token|undefined} */ + + let previous; + let index = -1; + /** @type {Token|undefined} */ + + let current = token; + let adjust = 0; + let start = 0; + const breaks = [start]; // Loop forward through the linked tokens to pass them in order to the + // subtokenizer. + + while (current) { + // Find the position of the event for this token. + while (events[++startPosition][1] !== current) { + // Empty. + } + + startPositions.push(startPosition); + + if (!current._tokenizer) { + stream = context.sliceStream(current); + + if (!current.next) { + stream.push(null); + } + + if (previous) { + tokenizer.defineSkip(current.start); + } + + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = true; + } + + tokenizer.write(stream); + + if (current._isInFirstContentOfListItem) { + tokenizer._gfmTasklistFirstContentOfListItem = undefined; + } + } // Unravel the next token. + + previous = current; + current = current.next; + } // Now, loop back through all events (and linked tokens), to figure out which + // parts belong where. + + current = token; + + while (++index < childEvents.length) { + if ( + // Find a void token that includes a break. + childEvents[index][0] === 'exit' && + childEvents[index - 1][0] === 'enter' && + childEvents[index][1].type === childEvents[index - 1][1].type && + childEvents[index][1].start.line !== childEvents[index][1].end.line + ) { + start = index + 1; + breaks.push(start); // Help GC. + + current._tokenizer = undefined; + current.previous = undefined; + current = current.next; + } + } // Help GC. + + tokenizer.events = []; // If there’s one more token (which is the cases for lines that end in an + // EOF), that’s perfect: the last point we found starts it. + // If there isn’t then make sure any remaining content is added to it. + + if (current) { + // Help GC. + current._tokenizer = undefined; + current.previous = undefined; + } else { + breaks.pop(); + } // Now splice the events from the subtokenizer into the current events, + // moving back to front so that splice indices aren’t affected. + + index = breaks.length; + + while (index--) { + const slice = childEvents.slice(breaks[index], breaks[index + 1]); + const start = startPositions.pop(); + jumps.unshift([start, start + slice.length - 1]); + splice(events, start, 2, slice); + } + + index = -1; + + while (++index < jumps.length) { + gaps[adjust + jumps[index][0]] = adjust + jumps[index][1]; + adjust += jumps[index][1] - jumps[index][0] - 1; + } + + return gaps +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** + * No name because it must not be turned off. + * @type {Construct} + */ +const content = { + tokenize: tokenizeContent, + resolve: resolveContent +}; +/** @type {Construct} */ + +const continuationConstruct = { + tokenize: tokenizeContinuation, + partial: true +}; +/** + * Content is transparent: it’s parsed right now. That way, definitions are also + * parsed right now: before text in paragraphs (specifically, media) are parsed. + * + * @type {Resolver} + */ + +function resolveContent(events) { + subtokenize(events); + return events +} +/** @type {Tokenizer} */ + +function tokenizeContent(effects, ok) { + /** @type {Token} */ + let previous; + return start + /** @type {State} */ + + function start(code) { + effects.enter('content'); + previous = effects.enter('chunkContent', { + contentType: 'content' + }); + return data(code) + } + /** @type {State} */ + + function data(code) { + if (code === null) { + return contentEnd(code) + } + + if (markdownLineEnding(code)) { + return effects.check( + continuationConstruct, + contentContinue, + contentEnd + )(code) + } // Data. + + effects.consume(code); + return data + } + /** @type {State} */ + + function contentEnd(code) { + effects.exit('chunkContent'); + effects.exit('content'); + return ok(code) + } + /** @type {State} */ + + function contentContinue(code) { + effects.consume(code); + effects.exit('chunkContent'); + previous.next = effects.enter('chunkContent', { + contentType: 'content', + previous + }); + previous = previous.next; + return data + } +} +/** @type {Tokenizer} */ + +function tokenizeContinuation(effects, ok, nok) { + const self = this; + return startLookahead + /** @type {State} */ + + function startLookahead(code) { + effects.exit('chunkContent'); + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, prefixed, 'linePrefix') + } + /** @type {State} */ + + function prefixed(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + const tail = self.events[self.events.length - 1]; + + if ( + !self.parser.constructs.disable.null.includes('codeIndented') && + tail && + tail[1].type === 'linePrefix' && + tail[2].sliceSerialize(tail[1], true).length >= 4 + ) { + return ok(code) + } + + return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + +/** + * @param {Effects} effects + * @param {State} ok + * @param {State} nok + * @param {string} type + * @param {string} literalType + * @param {string} literalMarkerType + * @param {string} rawType + * @param {string} stringType + * @param {number} [max=Infinity] + * @returns {State} + */ +// eslint-disable-next-line max-params +function factoryDestination( + effects, + ok, + nok, + type, + literalType, + literalMarkerType, + rawType, + stringType, + max +) { + const limit = max || Number.POSITIVE_INFINITY; + let balance = 0; + return start + /** @type {State} */ + + function start(code) { + if (code === 60) { + effects.enter(type); + effects.enter(literalType); + effects.enter(literalMarkerType); + effects.consume(code); + effects.exit(literalMarkerType); + return destinationEnclosedBefore + } + + if (code === null || code === 41 || asciiControl(code)) { + return nok(code) + } + + effects.enter(type); + effects.enter(rawType); + effects.enter(stringType); + effects.enter('chunkString', { + contentType: 'string' + }); + return destinationRaw(code) + } + /** @type {State} */ + + function destinationEnclosedBefore(code) { + if (code === 62) { + effects.enter(literalMarkerType); + effects.consume(code); + effects.exit(literalMarkerType); + effects.exit(literalType); + effects.exit(type); + return ok + } + + effects.enter(stringType); + effects.enter('chunkString', { + contentType: 'string' + }); + return destinationEnclosed(code) + } + /** @type {State} */ + + function destinationEnclosed(code) { + if (code === 62) { + effects.exit('chunkString'); + effects.exit(stringType); + return destinationEnclosedBefore(code) + } + + if (code === null || code === 60 || markdownLineEnding(code)) { + return nok(code) + } + + effects.consume(code); + return code === 92 ? destinationEnclosedEscape : destinationEnclosed + } + /** @type {State} */ + + function destinationEnclosedEscape(code) { + if (code === 60 || code === 62 || code === 92) { + effects.consume(code); + return destinationEnclosed + } + + return destinationEnclosed(code) + } + /** @type {State} */ + + function destinationRaw(code) { + if (code === 40) { + if (++balance > limit) return nok(code) + effects.consume(code); + return destinationRaw + } + + if (code === 41) { + if (!balance--) { + effects.exit('chunkString'); + effects.exit(stringType); + effects.exit(rawType); + effects.exit(type); + return ok(code) + } + + effects.consume(code); + return destinationRaw + } + + if (code === null || markdownLineEndingOrSpace(code)) { + if (balance) return nok(code) + effects.exit('chunkString'); + effects.exit(stringType); + effects.exit(rawType); + effects.exit(type); + return ok(code) + } + + if (asciiControl(code)) return nok(code) + effects.consume(code); + return code === 92 ? destinationRawEscape : destinationRaw + } + /** @type {State} */ + + function destinationRawEscape(code) { + if (code === 40 || code === 41 || code === 92) { + effects.consume(code); + return destinationRaw + } + + return destinationRaw(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').State} State + */ + +/** + * @this {TokenizeContext} + * @param {Effects} effects + * @param {State} ok + * @param {State} nok + * @param {string} type + * @param {string} markerType + * @param {string} stringType + * @returns {State} + */ +// eslint-disable-next-line max-params +function factoryLabel(effects, ok, nok, type, markerType, stringType) { + const self = this; + let size = 0; + /** @type {boolean} */ + + let data; + return start + /** @type {State} */ + + function start(code) { + effects.enter(type); + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + effects.enter(stringType); + return atBreak + } + /** @type {State} */ + + function atBreak(code) { + if ( + code === null || + code === 91 || + (code === 93 && !data) || + /* Hidden footnotes hook */ + + /* c8 ignore next 3 */ + (code === 94 && + !size && + '_hiddenFootnoteSupport' in self.parser.constructs) || + size > 999 + ) { + return nok(code) + } + + if (code === 93) { + effects.exit(stringType); + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + effects.exit(type); + return ok + } + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return atBreak + } + + effects.enter('chunkString', { + contentType: 'string' + }); + return label(code) + } + /** @type {State} */ + + function label(code) { + if ( + code === null || + code === 91 || + code === 93 || + markdownLineEnding(code) || + size++ > 999 + ) { + effects.exit('chunkString'); + return atBreak(code) + } + + effects.consume(code); + data = data || !markdownSpace(code); + return code === 92 ? labelEscape : label + } + /** @type {State} */ + + function labelEscape(code) { + if (code === 91 || code === 92 || code === 93) { + effects.consume(code); + size++; + return label + } + + return label(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** + * @param {Effects} effects + * @param {State} ok + * @param {State} nok + * @param {string} type + * @param {string} markerType + * @param {string} stringType + * @returns {State} + */ +// eslint-disable-next-line max-params +function factoryTitle(effects, ok, nok, type, markerType, stringType) { + /** @type {NonNullable} */ + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter(type); + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + marker = code === 40 ? 41 : code; + return atFirstTitleBreak + } + /** @type {State} */ + + function atFirstTitleBreak(code) { + if (code === marker) { + effects.enter(markerType); + effects.consume(code); + effects.exit(markerType); + effects.exit(type); + return ok + } + + effects.enter(stringType); + return atTitleBreak(code) + } + /** @type {State} */ + + function atTitleBreak(code) { + if (code === marker) { + effects.exit(stringType); + return atFirstTitleBreak(marker) + } + + if (code === null) { + return nok(code) + } // Note: blank lines can’t exist in content. + + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, atTitleBreak, 'linePrefix') + } + + effects.enter('chunkString', { + contentType: 'string' + }); + return title(code) + } + /** @type {State} */ + + function title(code) { + if (code === marker || code === null || markdownLineEnding(code)) { + effects.exit('chunkString'); + return atTitleBreak(code) + } + + effects.consume(code); + return code === 92 ? titleEscape : title + } + /** @type {State} */ + + function titleEscape(code) { + if (code === marker || code === 92) { + effects.consume(code); + return title + } + + return title(code) + } +} + +/** + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + */ + +/** + * @param {Effects} effects + * @param {State} ok + */ +function factoryWhitespace(effects, ok) { + /** @type {boolean} */ + let seen; + return start + /** @type {State} */ + + function start(code) { + if (markdownLineEnding(code)) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + seen = true; + return start + } + + if (markdownSpace(code)) { + return factorySpace( + effects, + start, + seen ? 'linePrefix' : 'lineSuffix' + )(code) + } + + return ok(code) + } +} + +/** + * Normalize an identifier (such as used in definitions). + * + * @param {string} value + * @returns {string} + */ +function normalizeIdentifier(value) { + return ( + value // Collapse Markdown whitespace. + .replace(/[\t\n\r ]+/g, ' ') // Trim. + .replace(/^ | $/g, '') // Some characters are considered “uppercase”, but if their lowercase + // counterpart is uppercased will result in a different uppercase + // character. + // Hence, to get that form, we perform both lower- and uppercase. + // Upper case makes sure keys will not interact with default prototypal + // methods: no method is uppercase. + .toLowerCase() + .toUpperCase() + ) +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const definition$1 = { + name: 'definition', + tokenize: tokenizeDefinition +}; +/** @type {Construct} */ + +const titleConstruct = { + tokenize: tokenizeTitle, + partial: true +}; +/** @type {Tokenizer} */ + +function tokenizeDefinition(effects, ok, nok) { + const self = this; + /** @type {string} */ + + let identifier; + return start + /** @type {State} */ + + function start(code) { + effects.enter('definition'); + return factoryLabel.call( + self, + effects, + labelAfter, + nok, + 'definitionLabel', + 'definitionLabelMarker', + 'definitionLabelString' + )(code) + } + /** @type {State} */ + + function labelAfter(code) { + identifier = normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ); + + if (code === 58) { + effects.enter('definitionMarker'); + effects.consume(code); + effects.exit('definitionMarker'); // Note: blank lines can’t exist in content. + + return factoryWhitespace( + effects, + factoryDestination( + effects, + effects.attempt( + titleConstruct, + factorySpace(effects, after, 'whitespace'), + factorySpace(effects, after, 'whitespace') + ), + nok, + 'definitionDestination', + 'definitionDestinationLiteral', + 'definitionDestinationLiteralMarker', + 'definitionDestinationRaw', + 'definitionDestinationString' + ) + ) + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('definition'); + + if (!self.parser.defined.includes(identifier)) { + self.parser.defined.push(identifier); + } + + return ok(code) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeTitle(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, before)(code) + : nok(code) + } + /** @type {State} */ + + function before(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + factorySpace(effects, after, 'whitespace'), + nok, + 'definitionTitle', + 'definitionTitleMarker', + 'definitionTitleString' + )(code) + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + return code === null || markdownLineEnding(code) ? ok(code) : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const hardBreakEscape = { + name: 'hardBreakEscape', + tokenize: tokenizeHardBreakEscape +}; +/** @type {Tokenizer} */ + +function tokenizeHardBreakEscape(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('hardBreakEscape'); + effects.enter('escapeMarker'); + effects.consume(code); + return open + } + /** @type {State} */ + + function open(code) { + if (markdownLineEnding(code)) { + effects.exit('escapeMarker'); + effects.exit('hardBreakEscape'); + return ok(code) + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const headingAtx = { + name: 'headingAtx', + tokenize: tokenizeHeadingAtx, + resolve: resolveHeadingAtx +}; +/** @type {Resolver} */ + +function resolveHeadingAtx(events, context) { + let contentEnd = events.length - 2; + let contentStart = 3; + /** @type {Token} */ + + let content; + /** @type {Token} */ + + let text; // Prefix whitespace, part of the opening. + + if (events[contentStart][1].type === 'whitespace') { + contentStart += 2; + } // Suffix whitespace, part of the closing. + + if ( + contentEnd - 2 > contentStart && + events[contentEnd][1].type === 'whitespace' + ) { + contentEnd -= 2; + } + + if ( + events[contentEnd][1].type === 'atxHeadingSequence' && + (contentStart === contentEnd - 1 || + (contentEnd - 4 > contentStart && + events[contentEnd - 2][1].type === 'whitespace')) + ) { + contentEnd -= contentStart + 1 === contentEnd ? 2 : 4; + } + + if (contentEnd > contentStart) { + content = { + type: 'atxHeadingText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end + }; + text = { + type: 'chunkText', + start: events[contentStart][1].start, + end: events[contentEnd][1].end, + // @ts-expect-error Constants are fine to assign. + contentType: 'text' + }; + splice(events, contentStart, contentEnd - contentStart + 1, [ + ['enter', content, context], + ['enter', text, context], + ['exit', text, context], + ['exit', content, context] + ]); + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeHeadingAtx(effects, ok, nok) { + const self = this; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + effects.enter('atxHeading'); + effects.enter('atxHeadingSequence'); + return fenceOpenInside(code) + } + /** @type {State} */ + + function fenceOpenInside(code) { + if (code === 35 && size++ < 6) { + effects.consume(code); + return fenceOpenInside + } + + if (code === null || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingSequence'); + return self.interrupt ? ok(code) : headingBreak(code) + } + + return nok(code) + } + /** @type {State} */ + + function headingBreak(code) { + if (code === 35) { + effects.enter('atxHeadingSequence'); + return sequence(code) + } + + if (code === null || markdownLineEnding(code)) { + effects.exit('atxHeading'); + return ok(code) + } + + if (markdownSpace(code)) { + return factorySpace(effects, headingBreak, 'whitespace')(code) + } + + effects.enter('atxHeadingText'); + return data(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === 35) { + effects.consume(code); + return sequence + } + + effects.exit('atxHeadingSequence'); + return headingBreak(code) + } + /** @type {State} */ + + function data(code) { + if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { + effects.exit('atxHeadingText'); + return headingBreak(code) + } + + effects.consume(code); + return data + } +} + +/** + * List of lowercase HTML tag names which when parsing HTML (flow), result + * in more relaxed rules (condition 6): because they are known blocks, the + * HTML-like syntax doesn’t have to be strictly parsed. + * For tag names not in this list, a more strict algorithm (condition 7) is used + * to detect whether the HTML-like syntax is seen as HTML (flow) or not. + * + * This is copied from: + * . + */ +const htmlBlockNames = [ + 'address', + 'article', + 'aside', + 'base', + 'basefont', + 'blockquote', + 'body', + 'caption', + 'center', + 'col', + 'colgroup', + 'dd', + 'details', + 'dialog', + 'dir', + 'div', + 'dl', + 'dt', + 'fieldset', + 'figcaption', + 'figure', + 'footer', + 'form', + 'frame', + 'frameset', + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'head', + 'header', + 'hr', + 'html', + 'iframe', + 'legend', + 'li', + 'link', + 'main', + 'menu', + 'menuitem', + 'nav', + 'noframes', + 'ol', + 'optgroup', + 'option', + 'p', + 'param', + 'section', + 'source', + 'summary', + 'table', + 'tbody', + 'td', + 'tfoot', + 'th', + 'thead', + 'title', + 'tr', + 'track', + 'ul' +]; + +/** + * List of lowercase HTML tag names which when parsing HTML (flow), result in + * HTML that can include lines w/o exiting, until a closing tag also in this + * list is found (condition 1). + * + * This module is copied from: + * . + * + * Note that `textarea` is not available in `CommonMark@0.29` but has been + * merged to the primary branch and is slated to be released in the next release + * of CommonMark. + */ +const htmlRawNames = ['pre', 'script', 'style', 'textarea']; + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ +/** @type {Construct} */ + +const htmlFlow = { + name: 'htmlFlow', + tokenize: tokenizeHtmlFlow, + resolveTo: resolveToHtmlFlow, + concrete: true +}; +/** @type {Construct} */ + +const nextBlankConstruct = { + tokenize: tokenizeNextBlank, + partial: true +}; +/** @type {Resolver} */ + +function resolveToHtmlFlow(events) { + let index = events.length; + + while (index--) { + if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { + break + } + } + + if (index > 1 && events[index - 2][1].type === 'linePrefix') { + // Add the prefix start to the HTML token. + events[index][1].start = events[index - 2][1].start; // Add the prefix start to the HTML line token. + + events[index + 1][1].start = events[index - 2][1].start; // Remove the line prefix. + + events.splice(index - 2, 2); + } + + return events +} +/** @type {Tokenizer} */ + +function tokenizeHtmlFlow(effects, ok, nok) { + const self = this; + /** @type {number} */ + + let kind; + /** @type {boolean} */ + + let startTag; + /** @type {string} */ + + let buffer; + /** @type {number} */ + + let index; + /** @type {Code} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('htmlFlow'); + effects.enter('htmlFlowData'); + effects.consume(code); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 33) { + effects.consume(code); + return declarationStart + } + + if (code === 47) { + effects.consume(code); + return tagCloseStart + } + + if (code === 63) { + effects.consume(code); + kind = 3; // While we’re in an instruction instead of a declaration, we’re on a `?` + // right now, so we do need to search for `>`, similar to declarations. + + return self.interrupt ? ok : continuationDeclarationInside + } + + if (asciiAlpha(code)) { + effects.consume(code); + buffer = String.fromCharCode(code); + startTag = true; + return tagName + } + + return nok(code) + } + /** @type {State} */ + + function declarationStart(code) { + if (code === 45) { + effects.consume(code); + kind = 2; + return commentOpenInside + } + + if (code === 91) { + effects.consume(code); + kind = 5; + buffer = 'CDATA['; + index = 0; + return cdataOpenInside + } + + if (asciiAlpha(code)) { + effects.consume(code); + kind = 4; + return self.interrupt ? ok : continuationDeclarationInside + } + + return nok(code) + } + /** @type {State} */ + + function commentOpenInside(code) { + if (code === 45) { + effects.consume(code); + return self.interrupt ? ok : continuationDeclarationInside + } + + return nok(code) + } + /** @type {State} */ + + function cdataOpenInside(code) { + if (code === buffer.charCodeAt(index++)) { + effects.consume(code); + return index === buffer.length + ? self.interrupt + ? ok + : continuation + : cdataOpenInside + } + + return nok(code) + } + /** @type {State} */ + + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code); + buffer = String.fromCharCode(code); + return tagName + } + + return nok(code) + } + /** @type {State} */ + + function tagName(code) { + if ( + code === null || + code === 47 || + code === 62 || + markdownLineEndingOrSpace(code) + ) { + if ( + code !== 47 && + startTag && + htmlRawNames.includes(buffer.toLowerCase()) + ) { + kind = 1; + return self.interrupt ? ok(code) : continuation(code) + } + + if (htmlBlockNames.includes(buffer.toLowerCase())) { + kind = 6; + + if (code === 47) { + effects.consume(code); + return basicSelfClosing + } + + return self.interrupt ? ok(code) : continuation(code) + } + + kind = 7; // Do not support complete HTML when interrupting + + return self.interrupt && !self.parser.lazy[self.now().line] + ? nok(code) + : startTag + ? completeAttributeNameBefore(code) + : completeClosingTagAfter(code) + } + + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code); + buffer += String.fromCharCode(code); + return tagName + } + + return nok(code) + } + /** @type {State} */ + + function basicSelfClosing(code) { + if (code === 62) { + effects.consume(code); + return self.interrupt ? ok : continuation + } + + return nok(code) + } + /** @type {State} */ + + function completeClosingTagAfter(code) { + if (markdownSpace(code)) { + effects.consume(code); + return completeClosingTagAfter + } + + return completeEnd(code) + } + /** @type {State} */ + + function completeAttributeNameBefore(code) { + if (code === 47) { + effects.consume(code); + return completeEnd + } + + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code); + return completeAttributeName + } + + if (markdownSpace(code)) { + effects.consume(code); + return completeAttributeNameBefore + } + + return completeEnd(code) + } + /** @type {State} */ + + function completeAttributeName(code) { + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code); + return completeAttributeName + } + + return completeAttributeNameAfter(code) + } + /** @type {State} */ + + function completeAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code); + return completeAttributeValueBefore + } + + if (markdownSpace(code)) { + effects.consume(code); + return completeAttributeNameAfter + } + + return completeAttributeNameBefore(code) + } + /** @type {State} */ + + function completeAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + + if (code === 34 || code === 39) { + effects.consume(code); + marker = code; + return completeAttributeValueQuoted + } + + if (markdownSpace(code)) { + effects.consume(code); + return completeAttributeValueBefore + } + + marker = null; + return completeAttributeValueUnquoted(code) + } + /** @type {State} */ + + function completeAttributeValueQuoted(code) { + if (code === null || markdownLineEnding(code)) { + return nok(code) + } + + if (code === marker) { + effects.consume(code); + return completeAttributeValueQuotedAfter + } + + effects.consume(code); + return completeAttributeValueQuoted + } + /** @type {State} */ + + function completeAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 62 || + code === 96 || + markdownLineEndingOrSpace(code) + ) { + return completeAttributeNameAfter(code) + } + + effects.consume(code); + return completeAttributeValueUnquoted + } + /** @type {State} */ + + function completeAttributeValueQuotedAfter(code) { + if (code === 47 || code === 62 || markdownSpace(code)) { + return completeAttributeNameBefore(code) + } + + return nok(code) + } + /** @type {State} */ + + function completeEnd(code) { + if (code === 62) { + effects.consume(code); + return completeAfter + } + + return nok(code) + } + /** @type {State} */ + + function completeAfter(code) { + if (markdownSpace(code)) { + effects.consume(code); + return completeAfter + } + + return code === null || markdownLineEnding(code) + ? continuation(code) + : nok(code) + } + /** @type {State} */ + + function continuation(code) { + if (code === 45 && kind === 2) { + effects.consume(code); + return continuationCommentInside + } + + if (code === 60 && kind === 1) { + effects.consume(code); + return continuationRawTagOpen + } + + if (code === 62 && kind === 4) { + effects.consume(code); + return continuationClose + } + + if (code === 63 && kind === 3) { + effects.consume(code); + return continuationDeclarationInside + } + + if (code === 93 && kind === 5) { + effects.consume(code); + return continuationCharacterDataInside + } + + if (markdownLineEnding(code) && (kind === 6 || kind === 7)) { + return effects.check( + nextBlankConstruct, + continuationClose, + continuationAtLineEnding + )(code) + } + + if (code === null || markdownLineEnding(code)) { + return continuationAtLineEnding(code) + } + + effects.consume(code); + return continuation + } + /** @type {State} */ + + function continuationAtLineEnding(code) { + effects.exit('htmlFlowData'); + return htmlContinueStart(code) + } + /** @type {State} */ + + function htmlContinueStart(code) { + if (code === null) { + return done(code) + } + + if (markdownLineEnding(code)) { + return effects.attempt( + { + tokenize: htmlLineEnd, + partial: true + }, + htmlContinueStart, + done + )(code) + } + + effects.enter('htmlFlowData'); + return continuation(code) + } + /** @type {Tokenizer} */ + + function htmlLineEnd(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return lineStart + } + /** @type {State} */ + + function lineStart(code) { + return self.parser.lazy[self.now().line] ? nok(code) : ok(code) + } + } + /** @type {State} */ + + function continuationCommentInside(code) { + if (code === 45) { + effects.consume(code); + return continuationDeclarationInside + } + + return continuation(code) + } + /** @type {State} */ + + function continuationRawTagOpen(code) { + if (code === 47) { + effects.consume(code); + buffer = ''; + return continuationRawEndTag + } + + return continuation(code) + } + /** @type {State} */ + + function continuationRawEndTag(code) { + if (code === 62 && htmlRawNames.includes(buffer.toLowerCase())) { + effects.consume(code); + return continuationClose + } + + if (asciiAlpha(code) && buffer.length < 8) { + effects.consume(code); + buffer += String.fromCharCode(code); + return continuationRawEndTag + } + + return continuation(code) + } + /** @type {State} */ + + function continuationCharacterDataInside(code) { + if (code === 93) { + effects.consume(code); + return continuationDeclarationInside + } + + return continuation(code) + } + /** @type {State} */ + + function continuationDeclarationInside(code) { + if (code === 62) { + effects.consume(code); + return continuationClose + } + + return continuation(code) + } + /** @type {State} */ + + function continuationClose(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('htmlFlowData'); + return done(code) + } + + effects.consume(code); + return continuationClose + } + /** @type {State} */ + + function done(code) { + effects.exit('htmlFlow'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeNextBlank(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.exit('htmlFlowData'); + effects.enter('lineEndingBlank'); + effects.consume(code); + effects.exit('lineEndingBlank'); + return effects.attempt(blankLine, ok, nok) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const htmlText = { + name: 'htmlText', + tokenize: tokenizeHtmlText +}; +/** @type {Tokenizer} */ + +function tokenizeHtmlText(effects, ok, nok) { + const self = this; + /** @type {NonNullable|undefined} */ + + let marker; + /** @type {string} */ + + let buffer; + /** @type {number} */ + + let index; + /** @type {State} */ + + let returnState; + return start + /** @type {State} */ + + function start(code) { + effects.enter('htmlText'); + effects.enter('htmlTextData'); + effects.consume(code); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 33) { + effects.consume(code); + return declarationOpen + } + + if (code === 47) { + effects.consume(code); + return tagCloseStart + } + + if (code === 63) { + effects.consume(code); + return instruction + } + + if (asciiAlpha(code)) { + effects.consume(code); + return tagOpen + } + + return nok(code) + } + /** @type {State} */ + + function declarationOpen(code) { + if (code === 45) { + effects.consume(code); + return commentOpen + } + + if (code === 91) { + effects.consume(code); + buffer = 'CDATA['; + index = 0; + return cdataOpen + } + + if (asciiAlpha(code)) { + effects.consume(code); + return declaration + } + + return nok(code) + } + /** @type {State} */ + + function commentOpen(code) { + if (code === 45) { + effects.consume(code); + return commentStart + } + + return nok(code) + } + /** @type {State} */ + + function commentStart(code) { + if (code === null || code === 62) { + return nok(code) + } + + if (code === 45) { + effects.consume(code); + return commentStartDash + } + + return comment(code) + } + /** @type {State} */ + + function commentStartDash(code) { + if (code === null || code === 62) { + return nok(code) + } + + return comment(code) + } + /** @type {State} */ + + function comment(code) { + if (code === null) { + return nok(code) + } + + if (code === 45) { + effects.consume(code); + return commentClose + } + + if (markdownLineEnding(code)) { + returnState = comment; + return atLineEnding(code) + } + + effects.consume(code); + return comment + } + /** @type {State} */ + + function commentClose(code) { + if (code === 45) { + effects.consume(code); + return end + } + + return comment(code) + } + /** @type {State} */ + + function cdataOpen(code) { + if (code === buffer.charCodeAt(index++)) { + effects.consume(code); + return index === buffer.length ? cdata : cdataOpen + } + + return nok(code) + } + /** @type {State} */ + + function cdata(code) { + if (code === null) { + return nok(code) + } + + if (code === 93) { + effects.consume(code); + return cdataClose + } + + if (markdownLineEnding(code)) { + returnState = cdata; + return atLineEnding(code) + } + + effects.consume(code); + return cdata + } + /** @type {State} */ + + function cdataClose(code) { + if (code === 93) { + effects.consume(code); + return cdataEnd + } + + return cdata(code) + } + /** @type {State} */ + + function cdataEnd(code) { + if (code === 62) { + return end(code) + } + + if (code === 93) { + effects.consume(code); + return cdataEnd + } + + return cdata(code) + } + /** @type {State} */ + + function declaration(code) { + if (code === null || code === 62) { + return end(code) + } + + if (markdownLineEnding(code)) { + returnState = declaration; + return atLineEnding(code) + } + + effects.consume(code); + return declaration + } + /** @type {State} */ + + function instruction(code) { + if (code === null) { + return nok(code) + } + + if (code === 63) { + effects.consume(code); + return instructionClose + } + + if (markdownLineEnding(code)) { + returnState = instruction; + return atLineEnding(code) + } + + effects.consume(code); + return instruction + } + /** @type {State} */ + + function instructionClose(code) { + return code === 62 ? end(code) : instruction(code) + } + /** @type {State} */ + + function tagCloseStart(code) { + if (asciiAlpha(code)) { + effects.consume(code); + return tagClose + } + + return nok(code) + } + /** @type {State} */ + + function tagClose(code) { + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code); + return tagClose + } + + return tagCloseBetween(code) + } + /** @type {State} */ + + function tagCloseBetween(code) { + if (markdownLineEnding(code)) { + returnState = tagCloseBetween; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagCloseBetween + } + + return end(code) + } + /** @type {State} */ + + function tagOpen(code) { + if (code === 45 || asciiAlphanumeric(code)) { + effects.consume(code); + return tagOpen + } + + if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + + return nok(code) + } + /** @type {State} */ + + function tagOpenBetween(code) { + if (code === 47) { + effects.consume(code); + return end + } + + if (code === 58 || code === 95 || asciiAlpha(code)) { + effects.consume(code); + return tagOpenAttributeName + } + + if (markdownLineEnding(code)) { + returnState = tagOpenBetween; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagOpenBetween + } + + return end(code) + } + /** @type {State} */ + + function tagOpenAttributeName(code) { + if ( + code === 45 || + code === 46 || + code === 58 || + code === 95 || + asciiAlphanumeric(code) + ) { + effects.consume(code); + return tagOpenAttributeName + } + + return tagOpenAttributeNameAfter(code) + } + /** @type {State} */ + + function tagOpenAttributeNameAfter(code) { + if (code === 61) { + effects.consume(code); + return tagOpenAttributeValueBefore + } + + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeNameAfter; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagOpenAttributeNameAfter + } + + return tagOpenBetween(code) + } + /** @type {State} */ + + function tagOpenAttributeValueBefore(code) { + if ( + code === null || + code === 60 || + code === 61 || + code === 62 || + code === 96 + ) { + return nok(code) + } + + if (code === 34 || code === 39) { + effects.consume(code); + marker = code; + return tagOpenAttributeValueQuoted + } + + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueBefore; + return atLineEnding(code) + } + + if (markdownSpace(code)) { + effects.consume(code); + return tagOpenAttributeValueBefore + } + + effects.consume(code); + marker = undefined; + return tagOpenAttributeValueUnquoted + } + /** @type {State} */ + + function tagOpenAttributeValueQuoted(code) { + if (code === marker) { + effects.consume(code); + return tagOpenAttributeValueQuotedAfter + } + + if (code === null) { + return nok(code) + } + + if (markdownLineEnding(code)) { + returnState = tagOpenAttributeValueQuoted; + return atLineEnding(code) + } + + effects.consume(code); + return tagOpenAttributeValueQuoted + } + /** @type {State} */ + + function tagOpenAttributeValueQuotedAfter(code) { + if (code === 62 || code === 47 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + + return nok(code) + } + /** @type {State} */ + + function tagOpenAttributeValueUnquoted(code) { + if ( + code === null || + code === 34 || + code === 39 || + code === 60 || + code === 61 || + code === 96 + ) { + return nok(code) + } + + if (code === 62 || markdownLineEndingOrSpace(code)) { + return tagOpenBetween(code) + } + + effects.consume(code); + return tagOpenAttributeValueUnquoted + } // We can’t have blank lines in content, so no need to worry about empty + // tokens. + + /** @type {State} */ + + function atLineEnding(code) { + effects.exit('htmlTextData'); + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace( + effects, + afterPrefix, + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + ) + } + /** @type {State} */ + + function afterPrefix(code) { + effects.enter('htmlTextData'); + return returnState(code) + } + /** @type {State} */ + + function end(code) { + if (code === 62) { + effects.consume(code); + effects.exit('htmlTextData'); + effects.exit('htmlText'); + return ok + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const labelEnd = { + name: 'labelEnd', + tokenize: tokenizeLabelEnd, + resolveTo: resolveToLabelEnd, + resolveAll: resolveAllLabelEnd +}; +/** @type {Construct} */ + +const resourceConstruct = { + tokenize: tokenizeResource +}; +/** @type {Construct} */ + +const fullReferenceConstruct = { + tokenize: tokenizeFullReference +}; +/** @type {Construct} */ + +const collapsedReferenceConstruct = { + tokenize: tokenizeCollapsedReference +}; +/** @type {Resolver} */ + +function resolveAllLabelEnd(events) { + let index = -1; + /** @type {Token} */ + + let token; + + while (++index < events.length) { + token = events[index][1]; + + if ( + token.type === 'labelImage' || + token.type === 'labelLink' || + token.type === 'labelEnd' + ) { + // Remove the marker. + events.splice(index + 1, token.type === 'labelImage' ? 4 : 2); + token.type = 'data'; + index++; + } + } + + return events +} +/** @type {Resolver} */ + +function resolveToLabelEnd(events, context) { + let index = events.length; + let offset = 0; + /** @type {Token} */ + + let token; + /** @type {number|undefined} */ + + let open; + /** @type {number|undefined} */ + + let close; + /** @type {Event[]} */ + + let media; // Find an opening. + + while (index--) { + token = events[index][1]; + + if (open) { + // If we see another link, or inactive link label, we’ve been here before. + if ( + token.type === 'link' || + (token.type === 'labelLink' && token._inactive) + ) { + break + } // Mark other link openings as inactive, as we can’t have links in + // links. + + if (events[index][0] === 'enter' && token.type === 'labelLink') { + token._inactive = true; + } + } else if (close) { + if ( + events[index][0] === 'enter' && + (token.type === 'labelImage' || token.type === 'labelLink') && + !token._balanced + ) { + open = index; + + if (token.type !== 'labelLink') { + offset = 2; + break + } + } + } else if (token.type === 'labelEnd') { + close = index; + } + } + + const group = { + type: events[open][1].type === 'labelLink' ? 'link' : 'image', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + }; + const label = { + type: 'label', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[close][1].end) + }; + const text = { + type: 'labelText', + start: Object.assign({}, events[open + offset + 2][1].end), + end: Object.assign({}, events[close - 2][1].start) + }; + media = [ + ['enter', group, context], + ['enter', label, context] + ]; // Opening marker. + + media = push(media, events.slice(open + 1, open + offset + 3)); // Text open. + + media = push(media, [['enter', text, context]]); // Between. + + media = push( + media, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + offset + 4, close - 3), + context + ) + ); // Text close, marker close, label close. + + media = push(media, [ + ['exit', text, context], + events[close - 2], + events[close - 1], + ['exit', label, context] + ]); // Reference, resource, or so. + + media = push(media, events.slice(close + 1)); // Media close. + + media = push(media, [['exit', group, context]]); + splice(events, open, events.length, media); + return events +} +/** @type {Tokenizer} */ + +function tokenizeLabelEnd(effects, ok, nok) { + const self = this; + let index = self.events.length; + /** @type {Token} */ + + let labelStart; + /** @type {boolean} */ + + let defined; // Find an opening. + + while (index--) { + if ( + (self.events[index][1].type === 'labelImage' || + self.events[index][1].type === 'labelLink') && + !self.events[index][1]._balanced + ) { + labelStart = self.events[index][1]; + break + } + } + + return start + /** @type {State} */ + + function start(code) { + if (!labelStart) { + return nok(code) + } // It’s a balanced bracket, but contains a link. + + if (labelStart._inactive) return balanced(code) + defined = self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize({ + start: labelStart.end, + end: self.now() + }) + ) + ); + effects.enter('labelEnd'); + effects.enter('labelMarker'); + effects.consume(code); + effects.exit('labelMarker'); + effects.exit('labelEnd'); + return afterLabelEnd + } + /** @type {State} */ + + function afterLabelEnd(code) { + // Resource: `[asd](fgh)`. + if (code === 40) { + return effects.attempt( + resourceConstruct, + ok, + defined ? ok : balanced + )(code) + } // Collapsed (`[asd][]`) or full (`[asd][fgh]`) reference? + + if (code === 91) { + return effects.attempt( + fullReferenceConstruct, + ok, + defined + ? effects.attempt(collapsedReferenceConstruct, ok, balanced) + : balanced + )(code) + } // Shortcut reference: `[asd]`? + + return defined ? ok(code) : balanced(code) + } + /** @type {State} */ + + function balanced(code) { + labelStart._balanced = true; + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeResource(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('resource'); + effects.enter('resourceMarker'); + effects.consume(code); + effects.exit('resourceMarker'); + return factoryWhitespace(effects, open) + } + /** @type {State} */ + + function open(code) { + if (code === 41) { + return end(code) + } + + return factoryDestination( + effects, + destinationAfter, + nok, + 'resourceDestination', + 'resourceDestinationLiteral', + 'resourceDestinationLiteralMarker', + 'resourceDestinationRaw', + 'resourceDestinationString', + 3 + )(code) + } + /** @type {State} */ + + function destinationAfter(code) { + return markdownLineEndingOrSpace(code) + ? factoryWhitespace(effects, between)(code) + : end(code) + } + /** @type {State} */ + + function between(code) { + if (code === 34 || code === 39 || code === 40) { + return factoryTitle( + effects, + factoryWhitespace(effects, end), + nok, + 'resourceTitle', + 'resourceTitleMarker', + 'resourceTitleString' + )(code) + } + + return end(code) + } + /** @type {State} */ + + function end(code) { + if (code === 41) { + effects.enter('resourceMarker'); + effects.consume(code); + effects.exit('resourceMarker'); + effects.exit('resource'); + return ok + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeFullReference(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + return factoryLabel.call( + self, + effects, + afterLabel, + nok, + 'reference', + 'referenceMarker', + 'referenceString' + )(code) + } + /** @type {State} */ + + function afterLabel(code) { + return self.parser.defined.includes( + normalizeIdentifier( + self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) + ) + ) + ? ok(code) + : nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeCollapsedReference(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('reference'); + effects.enter('referenceMarker'); + effects.consume(code); + effects.exit('referenceMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 93) { + effects.enter('referenceMarker'); + effects.consume(code); + effects.exit('referenceMarker'); + effects.exit('reference'); + return ok + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ +/** @type {Construct} */ + +const labelStartImage = { + name: 'labelStartImage', + tokenize: tokenizeLabelStartImage, + resolveAll: labelEnd.resolveAll +}; +/** @type {Tokenizer} */ + +function tokenizeLabelStartImage(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('labelImage'); + effects.enter('labelImageMarker'); + effects.consume(code); + effects.exit('labelImageMarker'); + return open + } + /** @type {State} */ + + function open(code) { + if (code === 91) { + effects.enter('labelMarker'); + effects.consume(code); + effects.exit('labelMarker'); + effects.exit('labelImage'); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + /* Hidden footnotes hook */ + + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ +/** @type {Construct} */ + +const labelStartLink = { + name: 'labelStartLink', + tokenize: tokenizeLabelStartLink, + resolveAll: labelEnd.resolveAll +}; +/** @type {Tokenizer} */ + +function tokenizeLabelStartLink(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + effects.enter('labelLink'); + effects.enter('labelMarker'); + effects.consume(code); + effects.exit('labelMarker'); + effects.exit('labelLink'); + return after + } + /** @type {State} */ + + function after(code) { + /* Hidden footnotes hook. */ + + /* c8 ignore next 3 */ + return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs + ? nok(code) + : ok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {Construct} */ +const lineEnding = { + name: 'lineEnding', + tokenize: tokenizeLineEnding +}; +/** @type {Tokenizer} */ + +function tokenizeLineEnding(effects, ok) { + return start + /** @type {State} */ + + function start(code) { + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + return factorySpace(effects, ok, 'linePrefix') + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const thematicBreak$1 = { + name: 'thematicBreak', + tokenize: tokenizeThematicBreak +}; +/** @type {Tokenizer} */ + +function tokenizeThematicBreak(effects, ok, nok) { + let size = 0; + /** @type {NonNullable} */ + + let marker; + return start + /** @type {State} */ + + function start(code) { + effects.enter('thematicBreak'); + marker = code; + return atBreak(code) + } + /** @type {State} */ + + function atBreak(code) { + if (code === marker) { + effects.enter('thematicBreakSequence'); + return sequence(code) + } + + if (markdownSpace(code)) { + return factorySpace(effects, atBreak, 'whitespace')(code) + } + + if (size < 3 || (code !== null && !markdownLineEnding(code))) { + return nok(code) + } + + effects.exit('thematicBreak'); + return ok(code) + } + /** @type {State} */ + + function sequence(code) { + if (code === marker) { + effects.consume(code); + size++; + return sequence + } + + effects.exit('thematicBreakSequence'); + return atBreak(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Exiter} Exiter + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ +/** @type {Construct} */ + +const list$1 = { + name: 'list', + tokenize: tokenizeListStart, + continuation: { + tokenize: tokenizeListContinuation + }, + exit: tokenizeListEnd +}; +/** @type {Construct} */ + +const listItemPrefixWhitespaceConstruct = { + tokenize: tokenizeListItemPrefixWhitespace, + partial: true +}; +/** @type {Construct} */ + +const indentConstruct = { + tokenize: tokenizeIndent, + partial: true +}; +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeListStart(effects, ok, nok) { + const self = this; + const tail = self.events[self.events.length - 1]; + let initialSize = + tail && tail[1].type === 'linePrefix' + ? tail[2].sliceSerialize(tail[1], true).length + : 0; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + const kind = + self.containerState.type || + (code === 42 || code === 43 || code === 45 + ? 'listUnordered' + : 'listOrdered'); + + if ( + kind === 'listUnordered' + ? !self.containerState.marker || code === self.containerState.marker + : asciiDigit(code) + ) { + if (!self.containerState.type) { + self.containerState.type = kind; + effects.enter(kind, { + _container: true + }); + } + + if (kind === 'listUnordered') { + effects.enter('listItemPrefix'); + return code === 42 || code === 45 + ? effects.check(thematicBreak$1, nok, atMarker)(code) + : atMarker(code) + } + + if (!self.interrupt || code === 49) { + effects.enter('listItemPrefix'); + effects.enter('listItemValue'); + return inside(code) + } + } + + return nok(code) + } + /** @type {State} */ + + function inside(code) { + if (asciiDigit(code) && ++size < 10) { + effects.consume(code); + return inside + } + + if ( + (!self.interrupt || size < 2) && + (self.containerState.marker + ? code === self.containerState.marker + : code === 41 || code === 46) + ) { + effects.exit('listItemValue'); + return atMarker(code) + } + + return nok(code) + } + /** + * @type {State} + **/ + + function atMarker(code) { + effects.enter('listItemMarker'); + effects.consume(code); + effects.exit('listItemMarker'); + self.containerState.marker = self.containerState.marker || code; + return effects.check( + blankLine, // Can’t be empty when interrupting. + self.interrupt ? nok : onBlank, + effects.attempt( + listItemPrefixWhitespaceConstruct, + endOfPrefix, + otherPrefix + ) + ) + } + /** @type {State} */ + + function onBlank(code) { + self.containerState.initialBlankLine = true; + initialSize++; + return endOfPrefix(code) + } + /** @type {State} */ + + function otherPrefix(code) { + if (markdownSpace(code)) { + effects.enter('listItemPrefixWhitespace'); + effects.consume(code); + effects.exit('listItemPrefixWhitespace'); + return endOfPrefix + } + + return nok(code) + } + /** @type {State} */ + + function endOfPrefix(code) { + self.containerState.size = + initialSize + + self.sliceSerialize(effects.exit('listItemPrefix'), true).length; + return ok(code) + } +} +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeListContinuation(effects, ok, nok) { + const self = this; + self.containerState._closeFlow = undefined; + return effects.check(blankLine, onBlank, notBlank) + /** @type {State} */ + + function onBlank(code) { + self.containerState.furtherBlankLines = + self.containerState.furtherBlankLines || + self.containerState.initialBlankLine; // We have a blank line. + // Still, try to consume at most the items size. + + return factorySpace( + effects, + ok, + 'listItemIndent', + self.containerState.size + 1 + )(code) + } + /** @type {State} */ + + function notBlank(code) { + if (self.containerState.furtherBlankLines || !markdownSpace(code)) { + self.containerState.furtherBlankLines = undefined; + self.containerState.initialBlankLine = undefined; + return notInCurrentItem(code) + } + + self.containerState.furtherBlankLines = undefined; + self.containerState.initialBlankLine = undefined; + return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) + } + /** @type {State} */ + + function notInCurrentItem(code) { + // While we do continue, we signal that the flow should be closed. + self.containerState._closeFlow = true; // As we’re closing flow, we’re no longer interrupting. + + self.interrupt = undefined; + return factorySpace( + effects, + effects.attempt(list$1, ok, nok), + 'linePrefix', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + )(code) + } +} +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeIndent(effects, ok, nok) { + const self = this; + return factorySpace( + effects, + afterPrefix, + 'listItemIndent', + self.containerState.size + 1 + ) + /** @type {State} */ + + function afterPrefix(code) { + const tail = self.events[self.events.length - 1]; + return tail && + tail[1].type === 'listItemIndent' && + tail[2].sliceSerialize(tail[1], true).length === self.containerState.size + ? ok(code) + : nok(code) + } +} +/** + * @type {Exiter} + * @this {TokenizeContextWithState} + */ + +function tokenizeListEnd(effects) { + effects.exit(this.containerState.type); +} +/** + * @type {Tokenizer} + * @this {TokenizeContextWithState} + */ + +function tokenizeListItemPrefixWhitespace(effects, ok, nok) { + const self = this; + return factorySpace( + effects, + afterPrefix, + 'listItemPrefixWhitespace', + self.parser.constructs.disable.null.includes('codeIndented') + ? undefined + : 4 + 1 + ) + /** @type {State} */ + + function afterPrefix(code) { + const tail = self.events[self.events.length - 1]; + return !markdownSpace(code) && + tail && + tail[1].type === 'listItemPrefixWhitespace' + ? ok(code) + : nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ + +/** @type {Construct} */ +const setextUnderline = { + name: 'setextUnderline', + tokenize: tokenizeSetextUnderline, + resolveTo: resolveToSetextUnderline +}; +/** @type {Resolver} */ + +function resolveToSetextUnderline(events, context) { + let index = events.length; + /** @type {number|undefined} */ + + let content; + /** @type {number|undefined} */ + + let text; + /** @type {number|undefined} */ + + let definition; // Find the opening of the content. + // It’ll always exist: we don’t tokenize if it isn’t there. + + while (index--) { + if (events[index][0] === 'enter') { + if (events[index][1].type === 'content') { + content = index; + break + } + + if (events[index][1].type === 'paragraph') { + text = index; + } + } // Exit + else { + if (events[index][1].type === 'content') { + // Remove the content end (if needed we’ll add it later) + events.splice(index, 1); + } + + if (!definition && events[index][1].type === 'definition') { + definition = index; + } + } + } + + const heading = { + type: 'setextHeading', + start: Object.assign({}, events[text][1].start), + end: Object.assign({}, events[events.length - 1][1].end) + }; // Change the paragraph to setext heading text. + + events[text][1].type = 'setextHeadingText'; // If we have definitions in the content, we’ll keep on having content, + // but we need move it. + + if (definition) { + events.splice(text, 0, ['enter', heading, context]); + events.splice(definition + 1, 0, ['exit', events[content][1], context]); + events[content][1].end = Object.assign({}, events[definition][1].end); + } else { + events[content][1] = heading; + } // Add the heading exit at the end. + + events.push(['exit', heading, context]); + return events +} +/** @type {Tokenizer} */ + +function tokenizeSetextUnderline(effects, ok, nok) { + const self = this; + let index = self.events.length; + /** @type {NonNullable} */ + + let marker; + /** @type {boolean} */ + + let paragraph; // Find an opening. + + while (index--) { + // Skip enter/exit of line ending, line prefix, and content. + // We can now either have a definition or a paragraph. + if ( + self.events[index][1].type !== 'lineEnding' && + self.events[index][1].type !== 'linePrefix' && + self.events[index][1].type !== 'content' + ) { + paragraph = self.events[index][1].type === 'paragraph'; + break + } + } + + return start + /** @type {State} */ + + function start(code) { + if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { + effects.enter('setextHeadingLine'); + effects.enter('setextHeadingLineSequence'); + marker = code; + return closingSequence(code) + } + + return nok(code) + } + /** @type {State} */ + + function closingSequence(code) { + if (code === marker) { + effects.consume(code); + return closingSequence + } + + effects.exit('setextHeadingLineSequence'); + return factorySpace(effects, closingSequenceEnd, 'lineSuffix')(code) + } + /** @type {State} */ + + function closingSequenceEnd(code) { + if (code === null || markdownLineEnding(code)) { + effects.exit('setextHeadingLine'); + return ok(code) + } + + return nok(code) + } +} + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').State} State + */ + +/** @type {InitialConstruct} */ +const flow$1 = { + tokenize: initializeFlow +}; +/** @type {Initializer} */ + +function initializeFlow(effects) { + const self = this; + const initial = effects.attempt( + // Try to parse a blank line. + blankLine, + atBlankEnding, // Try to parse initial flow (essentially, only code). + effects.attempt( + this.parser.constructs.flowInitial, + afterConstruct, + factorySpace( + effects, + effects.attempt( + this.parser.constructs.flow, + afterConstruct, + effects.attempt(content, afterConstruct) + ), + 'linePrefix' + ) + ) + ); + return initial + /** @type {State} */ + + function atBlankEnding(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('lineEndingBlank'); + effects.consume(code); + effects.exit('lineEndingBlank'); + self.currentConstruct = undefined; + return initial + } + /** @type {State} */ + + function afterConstruct(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('lineEnding'); + effects.consume(code); + effects.exit('lineEnding'); + self.currentConstruct = undefined; + return initial + } +} + +/** + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Initializer} Initializer + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Code} Code + */ +const resolver = { + resolveAll: createResolver() +}; +const string$1 = initializeFactory('string'); +const text$3 = initializeFactory('text'); +/** + * @param {'string'|'text'} field + * @returns {InitialConstruct} + */ + +function initializeFactory(field) { + return { + tokenize: initializeText, + resolveAll: createResolver( + field === 'text' ? resolveAllLineSuffixes : undefined + ) + } + /** @type {Initializer} */ + + function initializeText(effects) { + const self = this; + const constructs = this.parser.constructs[field]; + const text = effects.attempt(constructs, start, notText); + return start + /** @type {State} */ + + function start(code) { + return atBreak(code) ? text(code) : notText(code) + } + /** @type {State} */ + + function notText(code) { + if (code === null) { + effects.consume(code); + return + } + + effects.enter('data'); + effects.consume(code); + return data + } + /** @type {State} */ + + function data(code) { + if (atBreak(code)) { + effects.exit('data'); + return text(code) + } // Data. + + effects.consume(code); + return data + } + /** + * @param {Code} code + * @returns {boolean} + */ + + function atBreak(code) { + if (code === null) { + return true + } + + const list = constructs[code]; + let index = -1; + + if (list) { + while (++index < list.length) { + const item = list[index]; + + if (!item.previous || item.previous.call(self, self.previous)) { + return true + } + } + } + + return false + } + } +} +/** + * @param {Resolver} [extraResolver] + * @returns {Resolver} + */ + +function createResolver(extraResolver) { + return resolveAllText + /** @type {Resolver} */ + + function resolveAllText(events, context) { + let index = -1; + /** @type {number|undefined} */ + + let enter; // A rather boring computation (to merge adjacent `data` events) which + // improves mm performance by 29%. + + while (++index <= events.length) { + if (enter === undefined) { + if (events[index] && events[index][1].type === 'data') { + enter = index; + index++; + } + } else if (!events[index] || events[index][1].type !== 'data') { + // Don’t do anything if there is one data token. + if (index !== enter + 2) { + events[enter][1].end = events[index - 1][1].end; + events.splice(enter + 2, index - enter - 2); + index = enter + 2; + } + + enter = undefined; + } + } + + return extraResolver ? extraResolver(events, context) : events + } +} +/** + * A rather ugly set of instructions which again looks at chunks in the input + * stream. + * The reason to do this here is that it is *much* faster to parse in reverse. + * And that we can’t hook into `null` to split the line suffix before an EOF. + * To do: figure out if we can make this into a clean utility, or even in core. + * As it will be useful for GFMs literal autolink extension (and maybe even + * tables?) + * + * @type {Resolver} + */ + +function resolveAllLineSuffixes(events, context) { + let eventIndex = -1; + + while (++eventIndex <= events.length) { + if ( + (eventIndex === events.length || + events[eventIndex][1].type === 'lineEnding') && + events[eventIndex - 1][1].type === 'data' + ) { + const data = events[eventIndex - 1][1]; + const chunks = context.sliceStream(data); + let index = chunks.length; + let bufferIndex = -1; + let size = 0; + /** @type {boolean|undefined} */ + + let tabs; + + while (index--) { + const chunk = chunks[index]; + + if (typeof chunk === 'string') { + bufferIndex = chunk.length; + + while (chunk.charCodeAt(bufferIndex - 1) === 32) { + size++; + bufferIndex--; + } + + if (bufferIndex) break + bufferIndex = -1; + } // Number + else if (chunk === -2) { + tabs = true; + size++; + } else if (chunk === -1) ; else { + // Replacement character, exit. + index++; + break + } + } + + if (size) { + const token = { + type: + eventIndex === events.length || tabs || size < 2 + ? 'lineSuffix' + : 'hardBreakTrailing', + start: { + line: data.end.line, + column: data.end.column - size, + offset: data.end.offset - size, + _index: data.start._index + index, + _bufferIndex: index + ? bufferIndex + : data.start._bufferIndex + bufferIndex + }, + end: Object.assign({}, data.end) + }; + data.end = Object.assign({}, token.start); + + if (data.start.offset === data.end.offset) { + Object.assign(data, token); + } else { + events.splice( + eventIndex, + 0, + ['enter', token, context], + ['exit', token, context] + ); + eventIndex += 2; + } + } + + eventIndex++; + } + } + + return events +} + +/** + * @typedef {import('micromark-util-types').Code} Code + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Point} Point + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Effects} Effects + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Construct} Construct + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').ParseContext} ParseContext + */ + +/** + * Create a tokenizer. + * Tokenizers deal with one type of data (e.g., containers, flow, text). + * The parser is the object dealing with it all. + * `initialize` works like other constructs, except that only its `tokenize` + * function is used, in which case it doesn’t receive an `ok` or `nok`. + * `from` can be given to set the point before the first character, although + * when further lines are indented, they must be set with `defineSkip`. + * + * @param {ParseContext} parser + * @param {InitialConstruct} initialize + * @param {Omit} [from] + * @returns {TokenizeContext} + */ +function createTokenizer(parser, initialize, from) { + /** @type {Point} */ + let point = Object.assign( + from + ? Object.assign({}, from) + : { + line: 1, + column: 1, + offset: 0 + }, + { + _index: 0, + _bufferIndex: -1 + } + ); + /** @type {Record} */ + + const columnStart = {}; + /** @type {Construct[]} */ + + const resolveAllConstructs = []; + /** @type {Chunk[]} */ + + let chunks = []; + /** @type {Token[]} */ + + let stack = []; + /** + * Tools used for tokenizing. + * + * @type {Effects} + */ + + const effects = { + consume, + enter, + exit, + attempt: constructFactory(onsuccessfulconstruct), + check: constructFactory(onsuccessfulcheck), + interrupt: constructFactory(onsuccessfulcheck, { + interrupt: true + }) + }; + /** + * State and tools for resolving and serializing. + * + * @type {TokenizeContext} + */ + + const context = { + previous: null, + code: null, + containerState: {}, + events: [], + parser, + sliceStream, + sliceSerialize, + now, + defineSkip, + write + }; + /** + * The state function. + * + * @type {State|void} + */ + + let state = initialize.tokenize.call(context, effects); + + if (initialize.resolveAll) { + resolveAllConstructs.push(initialize); + } + + return context + /** @type {TokenizeContext['write']} */ + + function write(slice) { + chunks = push(chunks, slice); + main(); // Exit if we’re not done, resolve might change stuff. + + if (chunks[chunks.length - 1] !== null) { + return [] + } + + addResult(initialize, 0); // Otherwise, resolve, and exit. + + context.events = resolveAll(resolveAllConstructs, context.events, context); + return context.events + } // + // Tools. + // + + /** @type {TokenizeContext['sliceSerialize']} */ + + function sliceSerialize(token, expandTabs) { + return serializeChunks(sliceStream(token), expandTabs) + } + /** @type {TokenizeContext['sliceStream']} */ + + function sliceStream(token) { + return sliceChunks(chunks, token) + } + /** @type {TokenizeContext['now']} */ + + function now() { + return Object.assign({}, point) + } + /** @type {TokenizeContext['defineSkip']} */ + + function defineSkip(value) { + columnStart[value.line] = value.column; + accountForPotentialSkip(); + } // + // State management. + // + + /** + * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by + * `consume`). + * Here is where we walk through the chunks, which either include strings of + * several characters, or numerical character codes. + * The reason to do this in a loop instead of a call is so the stack can + * drain. + * + * @returns {void} + */ + + function main() { + /** @type {number} */ + let chunkIndex; + + while (point._index < chunks.length) { + const chunk = chunks[point._index]; // If we’re in a buffer chunk, loop through it. + + if (typeof chunk === 'string') { + chunkIndex = point._index; + + if (point._bufferIndex < 0) { + point._bufferIndex = 0; + } + + while ( + point._index === chunkIndex && + point._bufferIndex < chunk.length + ) { + go(chunk.charCodeAt(point._bufferIndex)); + } + } else { + go(chunk); + } + } + } + /** + * Deal with one code. + * + * @param {Code} code + * @returns {void} + */ + + function go(code) { + state = state(code); + } + /** @type {Effects['consume']} */ + + function consume(code) { + if (markdownLineEnding(code)) { + point.line++; + point.column = 1; + point.offset += code === -3 ? 2 : 1; + accountForPotentialSkip(); + } else if (code !== -1) { + point.column++; + point.offset++; + } // Not in a string chunk. + + if (point._bufferIndex < 0) { + point._index++; + } else { + point._bufferIndex++; // At end of string chunk. + // @ts-expect-error Points w/ non-negative `_bufferIndex` reference + // strings. + + if (point._bufferIndex === chunks[point._index].length) { + point._bufferIndex = -1; + point._index++; + } + } // Expose the previous character. + + context.previous = code; // Mark as consumed. + } + /** @type {Effects['enter']} */ + + function enter(type, fields) { + /** @type {Token} */ + // @ts-expect-error Patch instead of assign required fields to help GC. + const token = fields || {}; + token.type = type; + token.start = now(); + context.events.push(['enter', token, context]); + stack.push(token); + return token + } + /** @type {Effects['exit']} */ + + function exit(type) { + const token = stack.pop(); + token.end = now(); + context.events.push(['exit', token, context]); + return token + } + /** + * Use results. + * + * @type {ReturnHandle} + */ + + function onsuccessfulconstruct(construct, info) { + addResult(construct, info.from); + } + /** + * Discard results. + * + * @type {ReturnHandle} + */ + + function onsuccessfulcheck(_, info) { + info.restore(); + } + /** + * Factory to attempt/check/interrupt. + * + * @param {ReturnHandle} onreturn + * @param {Record} [fields] + */ + + function constructFactory(onreturn, fields) { + return hook + /** + * Handle either an object mapping codes to constructs, a list of + * constructs, or a single construct. + * + * @param {Construct|Construct[]|ConstructRecord} constructs + * @param {State} returnState + * @param {State} [bogusState] + * @returns {State} + */ + + function hook(constructs, returnState, bogusState) { + /** @type {Construct[]} */ + let listOfConstructs; + /** @type {number} */ + + let constructIndex; + /** @type {Construct} */ + + let currentConstruct; + /** @type {Info} */ + + let info; + return Array.isArray(constructs) + ? /* c8 ignore next 1 */ + handleListOfConstructs(constructs) + : 'tokenize' in constructs // @ts-expect-error Looks like a construct. + ? handleListOfConstructs([constructs]) + : handleMapOfConstructs(constructs) + /** + * Handle a list of construct. + * + * @param {ConstructRecord} map + * @returns {State} + */ + + function handleMapOfConstructs(map) { + return start + /** @type {State} */ + + function start(code) { + const def = code !== null && map[code]; + const all = code !== null && map.null; + const list = [ + // To do: add more extension tests. + + /* c8 ignore next 2 */ + ...(Array.isArray(def) ? def : def ? [def] : []), + ...(Array.isArray(all) ? all : all ? [all] : []) + ]; + return handleListOfConstructs(list)(code) + } + } + /** + * Handle a list of construct. + * + * @param {Construct[]} list + * @returns {State} + */ + + function handleListOfConstructs(list) { + listOfConstructs = list; + constructIndex = 0; + + if (list.length === 0) { + return bogusState + } + + return handleConstruct(list[constructIndex]) + } + /** + * Handle a single construct. + * + * @param {Construct} construct + * @returns {State} + */ + + function handleConstruct(construct) { + return start + /** @type {State} */ + + function start(code) { + // To do: not needed to store if there is no bogus state, probably? + // Currently doesn’t work because `inspect` in document does a check + // w/o a bogus, which doesn’t make sense. But it does seem to help perf + // by not storing. + info = store(); + currentConstruct = construct; + + if (!construct.partial) { + context.currentConstruct = construct; + } + + if ( + construct.name && + context.parser.constructs.disable.null.includes(construct.name) + ) { + return nok() + } + + return construct.tokenize.call( + // If we do have fields, create an object w/ `context` as its + // prototype. + // This allows a “live binding”, which is needed for `interrupt`. + fields ? Object.assign(Object.create(context), fields) : context, + effects, + ok, + nok + )(code) + } + } + /** @type {State} */ + + function ok(code) { + onreturn(currentConstruct, info); + return returnState + } + /** @type {State} */ + + function nok(code) { + info.restore(); + + if (++constructIndex < listOfConstructs.length) { + return handleConstruct(listOfConstructs[constructIndex]) + } + + return bogusState + } + } + } + /** + * @param {Construct} construct + * @param {number} from + * @returns {void} + */ + + function addResult(construct, from) { + if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { + resolveAllConstructs.push(construct); + } + + if (construct.resolve) { + splice( + context.events, + from, + context.events.length - from, + construct.resolve(context.events.slice(from), context) + ); + } + + if (construct.resolveTo) { + context.events = construct.resolveTo(context.events, context); + } + } + /** + * Store state. + * + * @returns {Info} + */ + + function store() { + const startPoint = now(); + const startPrevious = context.previous; + const startCurrentConstruct = context.currentConstruct; + const startEventsIndex = context.events.length; + const startStack = Array.from(stack); + return { + restore, + from: startEventsIndex + } + /** + * Restore state. + * + * @returns {void} + */ + + function restore() { + point = startPoint; + context.previous = startPrevious; + context.currentConstruct = startCurrentConstruct; + context.events.length = startEventsIndex; + stack = startStack; + accountForPotentialSkip(); + } + } + /** + * Move the current point a bit forward in the line when it’s on a column + * skip. + * + * @returns {void} + */ + + function accountForPotentialSkip() { + if (point.line in columnStart && point.column < 2) { + point.column = columnStart[point.line]; + point.offset += columnStart[point.line] - 1; + } + } +} +/** + * Get the chunks from a slice of chunks in the range of a token. + * + * @param {Chunk[]} chunks + * @param {Pick} token + * @returns {Chunk[]} + */ + +function sliceChunks(chunks, token) { + const startIndex = token.start._index; + const startBufferIndex = token.start._bufferIndex; + const endIndex = token.end._index; + const endBufferIndex = token.end._bufferIndex; + /** @type {Chunk[]} */ + + let view; + + if (startIndex === endIndex) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)]; + } else { + view = chunks.slice(startIndex, endIndex); + + if (startBufferIndex > -1) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view[0] = view[0].slice(startBufferIndex); + } + + if (endBufferIndex > 0) { + // @ts-expect-error `_bufferIndex` is used on string chunks. + view.push(chunks[endIndex].slice(0, endBufferIndex)); + } + } + + return view +} +/** + * Get the string value of a slice of chunks. + * + * @param {Chunk[]} chunks + * @param {boolean} [expandTabs=false] + * @returns {string} + */ + +function serializeChunks(chunks, expandTabs) { + let index = -1; + /** @type {string[]} */ + + const result = []; + /** @type {boolean|undefined} */ + + let atTab; + + while (++index < chunks.length) { + const chunk = chunks[index]; + /** @type {string} */ + + let value; + + if (typeof chunk === 'string') { + value = chunk; + } else + switch (chunk) { + case -5: { + value = '\r'; + break + } + + case -4: { + value = '\n'; + break + } + + case -3: { + value = '\r' + '\n'; + break + } + + case -2: { + value = expandTabs ? ' ' : '\t'; + break + } + + case -1: { + if (!expandTabs && atTab) continue + value = ' '; + break + } + + default: { + // Currently only replacement character. + value = String.fromCharCode(chunk); + } + } + + atTab = chunk === -2; + result.push(value); + } + + return result.join('') +} + +/** + * @typedef {import('micromark-util-types').Extension} Extension + */ +/** @type {Extension['document']} */ + +const document = { + [42]: list$1, + [43]: list$1, + [45]: list$1, + [48]: list$1, + [49]: list$1, + [50]: list$1, + [51]: list$1, + [52]: list$1, + [53]: list$1, + [54]: list$1, + [55]: list$1, + [56]: list$1, + [57]: list$1, + [62]: blockQuote +}; +/** @type {Extension['contentInitial']} */ + +const contentInitial = { + [91]: definition$1 +}; +/** @type {Extension['flowInitial']} */ + +const flowInitial = { + [-2]: codeIndented, + [-1]: codeIndented, + [32]: codeIndented +}; +/** @type {Extension['flow']} */ + +const flow = { + [35]: headingAtx, + [42]: thematicBreak$1, + [45]: [setextUnderline, thematicBreak$1], + [60]: htmlFlow, + [61]: setextUnderline, + [95]: thematicBreak$1, + [96]: codeFenced, + [126]: codeFenced +}; +/** @type {Extension['string']} */ + +const string = { + [38]: characterReference, + [92]: characterEscape +}; +/** @type {Extension['text']} */ + +const text$2 = { + [-5]: lineEnding, + [-4]: lineEnding, + [-3]: lineEnding, + [33]: labelStartImage, + [38]: characterReference, + [42]: attention, + [60]: [autolink, htmlText], + [91]: labelStartLink, + [92]: [hardBreakEscape, characterEscape], + [93]: labelEnd, + [95]: attention, + [96]: codeText +}; +/** @type {Extension['insideSpan']} */ + +const insideSpan = { + null: [attention, resolver] +}; +/** @type {Extension['attentionMarkers']} */ + +const attentionMarkers = { + null: [42, 95] +}; +/** @type {Extension['disable']} */ + +const disable = { + null: [] +}; + +var defaultConstructs = /*#__PURE__*/Object.freeze({ + __proto__: null, + document: document, + contentInitial: contentInitial, + flowInitial: flowInitial, + flow: flow, + string: string, + text: text$2, + insideSpan: insideSpan, + attentionMarkers: attentionMarkers, + disable: disable +}); + +/** + * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct + * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').ParseContext} ParseContext + * @typedef {import('micromark-util-types').Create} Create + */ +/** + * @param {ParseOptions} [options] + * @returns {ParseContext} + */ + +function parse$1(options = {}) { + /** @type {FullNormalizedExtension} */ + // @ts-expect-error `defaultConstructs` is full, so the result will be too. + const constructs = combineExtensions( + // @ts-expect-error Same as above. + [defaultConstructs].concat(options.extensions || []) + ); + /** @type {ParseContext} */ + + const parser = { + defined: [], + lazy: {}, + constructs, + content: create(content$1), + document: create(document$1), + flow: create(flow$1), + string: create(string$1), + text: create(text$3) + }; + return parser + /** + * @param {InitialConstruct} initial + */ + + function create(initial) { + return creator + /** @type {Create} */ + + function creator(from) { + return createTokenizer(parser, initial, from) + } + } +} + +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Value} Value + * @typedef {import('micromark-util-types').Chunk} Chunk + * @typedef {import('micromark-util-types').Code} Code + */ + +/** + * @callback Preprocessor + * @param {Value} value + * @param {Encoding} [encoding] + * @param {boolean} [end=false] + * @returns {Chunk[]} + */ +const search = /[\0\t\n\r]/g; +/** + * @returns {Preprocessor} + */ + +function preprocess() { + let column = 1; + let buffer = ''; + /** @type {boolean|undefined} */ + + let start = true; + /** @type {boolean|undefined} */ + + let atCarriageReturn; + return preprocessor + /** @type {Preprocessor} */ + + function preprocessor(value, encoding, end) { + /** @type {Chunk[]} */ + const chunks = []; + /** @type {RegExpMatchArray|null} */ + + let match; + /** @type {number} */ + + let next; + /** @type {number} */ + + let startPosition; + /** @type {number} */ + + let endPosition; + /** @type {Code} */ + + let code; // @ts-expect-error `Buffer` does allow an encoding. + + value = buffer + value.toString(encoding); + startPosition = 0; + buffer = ''; + + if (start) { + if (value.charCodeAt(0) === 65279) { + startPosition++; + } + + start = undefined; + } + + while (startPosition < value.length) { + search.lastIndex = startPosition; + match = search.exec(value); + endPosition = + match && match.index !== undefined ? match.index : value.length; + code = value.charCodeAt(endPosition); + + if (!match) { + buffer = value.slice(startPosition); + break + } + + if (code === 10 && startPosition === endPosition && atCarriageReturn) { + chunks.push(-3); + atCarriageReturn = undefined; + } else { + if (atCarriageReturn) { + chunks.push(-5); + atCarriageReturn = undefined; + } + + if (startPosition < endPosition) { + chunks.push(value.slice(startPosition, endPosition)); + column += endPosition - startPosition; + } + + switch (code) { + case 0: { + chunks.push(65533); + column++; + break + } + + case 9: { + next = Math.ceil(column / 4) * 4; + chunks.push(-2); + + while (column++ < next) chunks.push(-1); + + break + } + + case 10: { + chunks.push(-4); + column = 1; + break + } + + default: { + atCarriageReturn = true; + column = 1; + } + } + } + + startPosition = endPosition + 1; + } + + if (end) { + if (atCarriageReturn) chunks.push(-5); + if (buffer) chunks.push(buffer); + chunks.push(null); + } + + return chunks + } +} + +/** + * @typedef {import('micromark-util-types').Event} Event + */ +/** + * @param {Event[]} events + * @returns {Event[]} + */ + +function postprocess(events) { + while (!subtokenize(events)) { + // Empty + } + + return events +} + +/** + * Turn the number (in string form as either hexa- or plain decimal) coming from + * a numeric character reference into a character. + * + * @param {string} value + * Value to decode. + * @param {number} base + * Numeric base. + * @returns {string} + */ +function decodeNumericCharacterReference(value, base) { + const code = Number.parseInt(value, base); + + if ( + // C0 except for HT, LF, FF, CR, space + code < 9 || + code === 11 || + (code > 13 && code < 32) || // Control character (DEL) of the basic block and C1 controls. + (code > 126 && code < 160) || // Lone high surrogates and low surrogates. + (code > 55295 && code < 57344) || // Noncharacters. + (code > 64975 && code < 65008) || + (code & 65535) === 65535 || + (code & 65535) === 65534 || // Out of range + code > 1114111 + ) { + return '\uFFFD' + } + + return String.fromCharCode(code) +} + +const characterEscapeOrReference = + /\\([!-/:-@[-`{-~])|&(#(?:\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi; +/** + * Utility to decode markdown strings (which occur in places such as fenced + * code info strings, destinations, labels, and titles). + * The “string” content type allows character escapes and -references. + * This decodes those. + * + * @param {string} value + * @returns {string} + */ + +function decodeString(value) { + return value.replace(characterEscapeOrReference, decode) +} +/** + * @param {string} $0 + * @param {string} $1 + * @param {string} $2 + * @returns {string} + */ + +function decode($0, $1, $2) { + if ($1) { + // Escape. + return $1 + } // Reference. + + const head = $2.charCodeAt(0); + + if (head === 35) { + const head = $2.charCodeAt(1); + const hex = head === 120 || head === 88; + return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10) + } + + return decodeEntity($2) || $0 +} + +/** + * @typedef {import('micromark-util-types').Encoding} Encoding + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').ParseOptions} ParseOptions + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext + * @typedef {import('micromark-util-types').Value} Value + * @typedef {import('unist').Parent} UnistParent + * @typedef {import('unist').Point} Point + * @typedef {import('mdast').PhrasingContent} PhrasingContent + * @typedef {import('mdast').Content} Content + * @typedef {Root|Content} Node + * @typedef {Extract} Parent + * @typedef {import('mdast').Break} Break + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('mdast').Code} Code + * @typedef {import('mdast').Definition} Definition + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('mdast').Heading} Heading + * @typedef {import('mdast').HTML} HTML + * @typedef {import('mdast').Image} Image + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('mdast').Link} Link + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('mdast').List} List + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast').Strong} Strong + * @typedef {import('mdast').Text} Text + * @typedef {import('mdast').ThematicBreak} ThematicBreak + * + * @typedef {UnistParent & {type: 'fragment', children: PhrasingContent[]}} Fragment + */ +const own$5 = {}.hasOwnProperty; +/** + * @param value Markdown to parse (`string` or `Buffer`). + * @param [encoding] Character encoding to understand `value` as when it’s a `Buffer` (`string`, default: `'utf8'`). + * @param [options] Configuration + */ + +const fromMarkdown = + /** + * @param {Value} value + * @param {Encoding} [encoding] + * @param {Options} [options] + * @returns {Root} + */ + function (value, encoding, options) { + if (typeof encoding !== 'string') { + options = encoding; + encoding = undefined; + } + + return compiler(options)( + postprocess( + parse$1(options).document().write(preprocess()(value, encoding, true)) + ) + ) + }; +/** + * Note this compiler only understand complete buffering, not streaming. + * + * @param {Options} [options] + */ + +function compiler(options = {}) { + /** @type {NormalizedExtension} */ + // @ts-expect-error: our base has all required fields, so the result will too. + const config = configure$1( + { + transforms: [], + canContainEols: [ + 'emphasis', + 'fragment', + 'heading', + 'paragraph', + 'strong' + ], + enter: { + autolink: opener(link), + autolinkProtocol: onenterdata, + autolinkEmail: onenterdata, + atxHeading: opener(heading), + blockQuote: opener(blockQuote), + characterEscape: onenterdata, + characterReference: onenterdata, + codeFenced: opener(codeFlow), + codeFencedFenceInfo: buffer, + codeFencedFenceMeta: buffer, + codeIndented: opener(codeFlow, buffer), + codeText: opener(codeText, buffer), + codeTextData: onenterdata, + data: onenterdata, + codeFlowValue: onenterdata, + definition: opener(definition), + definitionDestinationString: buffer, + definitionLabelString: buffer, + definitionTitleString: buffer, + emphasis: opener(emphasis), + hardBreakEscape: opener(hardBreak), + hardBreakTrailing: opener(hardBreak), + htmlFlow: opener(html, buffer), + htmlFlowData: onenterdata, + htmlText: opener(html, buffer), + htmlTextData: onenterdata, + image: opener(image), + label: buffer, + link: opener(link), + listItem: opener(listItem), + listItemValue: onenterlistitemvalue, + listOrdered: opener(list, onenterlistordered), + listUnordered: opener(list), + paragraph: opener(paragraph), + reference: onenterreference, + referenceString: buffer, + resourceDestinationString: buffer, + resourceTitleString: buffer, + setextHeading: opener(heading), + strong: opener(strong), + thematicBreak: opener(thematicBreak) + }, + exit: { + atxHeading: closer(), + atxHeadingSequence: onexitatxheadingsequence, + autolink: closer(), + autolinkEmail: onexitautolinkemail, + autolinkProtocol: onexitautolinkprotocol, + blockQuote: closer(), + characterEscapeValue: onexitdata, + characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, + characterReferenceMarkerNumeric: onexitcharacterreferencemarker, + characterReferenceValue: onexitcharacterreferencevalue, + codeFenced: closer(onexitcodefenced), + codeFencedFence: onexitcodefencedfence, + codeFencedFenceInfo: onexitcodefencedfenceinfo, + codeFencedFenceMeta: onexitcodefencedfencemeta, + codeFlowValue: onexitdata, + codeIndented: closer(onexitcodeindented), + codeText: closer(onexitcodetext), + codeTextData: onexitdata, + data: onexitdata, + definition: closer(), + definitionDestinationString: onexitdefinitiondestinationstring, + definitionLabelString: onexitdefinitionlabelstring, + definitionTitleString: onexitdefinitiontitlestring, + emphasis: closer(), + hardBreakEscape: closer(onexithardbreak), + hardBreakTrailing: closer(onexithardbreak), + htmlFlow: closer(onexithtmlflow), + htmlFlowData: onexitdata, + htmlText: closer(onexithtmltext), + htmlTextData: onexitdata, + image: closer(onexitimage), + label: onexitlabel, + labelText: onexitlabeltext, + lineEnding: onexitlineending, + link: closer(onexitlink), + listItem: closer(), + listOrdered: closer(), + listUnordered: closer(), + paragraph: closer(), + referenceString: onexitreferencestring, + resourceDestinationString: onexitresourcedestinationstring, + resourceTitleString: onexitresourcetitlestring, + resource: onexitresource, + setextHeading: closer(onexitsetextheading), + setextHeadingLineSequence: onexitsetextheadinglinesequence, + setextHeadingText: onexitsetextheadingtext, + strong: closer(), + thematicBreak: closer() + } + }, + options.mdastExtensions || [] + ); + /** @type {CompileData} */ + + const data = {}; + return compile + /** + * @param {Array.} events + * @returns {Root} + */ + + function compile(events) { + /** @type {Root} */ + let tree = { + type: 'root', + children: [] + }; + /** @type {CompileContext['stack']} */ + + const stack = [tree]; + /** @type {CompileContext['tokenStack']} */ + + const tokenStack = []; + /** @type {Array.} */ + + const listStack = []; + /** @type {Omit} */ + + const context = { + stack, + tokenStack, + config, + enter, + exit, + buffer, + resume, + setData, + getData + }; + let index = -1; + + while (++index < events.length) { + // We preprocess lists to add `listItem` tokens, and to infer whether + // items the list itself are spread out. + if ( + events[index][1].type === 'listOrdered' || + events[index][1].type === 'listUnordered' + ) { + if (events[index][0] === 'enter') { + listStack.push(index); + } else { + const tail = listStack.pop(); + index = prepareList(events, tail, index); + } + } + } + + index = -1; + + while (++index < events.length) { + const handler = config[events[index][0]]; + + if (own$5.call(handler, events[index][1].type)) { + handler[events[index][1].type].call( + Object.assign( + { + sliceSerialize: events[index][2].sliceSerialize + }, + context + ), + events[index][1] + ); + } + } + + if (tokenStack.length > 0) { + throw new Error( + 'Cannot close document, a token (`' + + tokenStack[tokenStack.length - 1].type + + '`, ' + + stringifyPosition({ + start: tokenStack[tokenStack.length - 1].start, + end: tokenStack[tokenStack.length - 1].end + }) + + ') is still open' + ) + } // Figure out `root` position. + + tree.position = { + start: point( + events.length > 0 + ? events[0][1].start + : { + line: 1, + column: 1, + offset: 0 + } + ), + end: point( + events.length > 0 + ? events[events.length - 2][1].end + : { + line: 1, + column: 1, + offset: 0 + } + ) + }; + index = -1; + + while (++index < config.transforms.length) { + tree = config.transforms[index](tree) || tree; + } + + return tree + } + /** + * @param {Array.} events + * @param {number} start + * @param {number} length + * @returns {number} + */ + + function prepareList(events, start, length) { + let index = start - 1; + let containerBalance = -1; + let listSpread = false; + /** @type {Token|undefined} */ + + let listItem; + /** @type {number|undefined} */ + + let lineIndex; + /** @type {number|undefined} */ + + let firstBlankLineIndex; + /** @type {boolean|undefined} */ + + let atMarker; + + while (++index <= length) { + const event = events[index]; + + if ( + event[1].type === 'listUnordered' || + event[1].type === 'listOrdered' || + event[1].type === 'blockQuote' + ) { + if (event[0] === 'enter') { + containerBalance++; + } else { + containerBalance--; + } + + atMarker = undefined; + } else if (event[1].type === 'lineEndingBlank') { + if (event[0] === 'enter') { + if ( + listItem && + !atMarker && + !containerBalance && + !firstBlankLineIndex + ) { + firstBlankLineIndex = index; + } + + atMarker = undefined; + } + } else if ( + event[1].type === 'linePrefix' || + event[1].type === 'listItemValue' || + event[1].type === 'listItemMarker' || + event[1].type === 'listItemPrefix' || + event[1].type === 'listItemPrefixWhitespace' + ) ; else { + atMarker = undefined; + } + + if ( + (!containerBalance && + event[0] === 'enter' && + event[1].type === 'listItemPrefix') || + (containerBalance === -1 && + event[0] === 'exit' && + (event[1].type === 'listUnordered' || + event[1].type === 'listOrdered')) + ) { + if (listItem) { + let tailIndex = index; + lineIndex = undefined; + + while (tailIndex--) { + const tailEvent = events[tailIndex]; + + if ( + tailEvent[1].type === 'lineEnding' || + tailEvent[1].type === 'lineEndingBlank' + ) { + if (tailEvent[0] === 'exit') continue + + if (lineIndex) { + events[lineIndex][1].type = 'lineEndingBlank'; + listSpread = true; + } + + tailEvent[1].type = 'lineEnding'; + lineIndex = tailIndex; + } else if ( + tailEvent[1].type === 'linePrefix' || + tailEvent[1].type === 'blockQuotePrefix' || + tailEvent[1].type === 'blockQuotePrefixWhitespace' || + tailEvent[1].type === 'blockQuoteMarker' || + tailEvent[1].type === 'listItemIndent' + ) ; else { + break + } + } + + if ( + firstBlankLineIndex && + (!lineIndex || firstBlankLineIndex < lineIndex) + ) { + // @ts-expect-error Patched. + listItem._spread = true; + } // Fix position. + + listItem.end = Object.assign( + {}, + lineIndex ? events[lineIndex][1].start : event[1].end + ); + events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]); + index++; + length++; + } // Create a new list item. + + if (event[1].type === 'listItemPrefix') { + listItem = { + type: 'listItem', + // @ts-expect-error Patched + _spread: false, + start: Object.assign({}, event[1].start) + }; // @ts-expect-error: `listItem` is most definitely defined, TS... + + events.splice(index, 0, ['enter', listItem, event[2]]); + index++; + length++; + firstBlankLineIndex = undefined; + atMarker = true; + } + } + } // @ts-expect-error Patched. + + events[start][1]._spread = listSpread; + return length + } + /** + * @type {CompileContext['setData']} + * @param [value] + */ + + function setData(key, value) { + data[key] = value; + } + /** + * @type {CompileContext['getData']} + * @template {string} K + * @param {K} key + * @returns {CompileData[K]} + */ + + function getData(key) { + return data[key] + } + /** + * @param {Point} d + * @returns {Point} + */ + + function point(d) { + return { + line: d.line, + column: d.column, + offset: d.offset + } + } + /** + * @param {(token: Token) => Node} create + * @param {Handle} [and] + * @returns {Handle} + */ + + function opener(create, and) { + return open + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + + function open(token) { + enter.call(this, create(token), token); + if (and) and.call(this, token); + } + } + /** @type {CompileContext['buffer']} */ + + function buffer() { + this.stack.push({ + type: 'fragment', + children: [] + }); + } + /** + * @type {CompileContext['enter']} + * @template {Node} N + * @this {CompileContext} + * @param {N} node + * @param {Token} token + * @returns {N} + */ + + function enter(node, token) { + const parent = this.stack[this.stack.length - 1]; + // @ts-expect-error: Assume `Node` can exist as a child of `parent`. + parent.children.push(node); + this.stack.push(node); + this.tokenStack.push(token); // @ts-expect-error: `end` will be patched later. + + node.position = { + start: point(token.start) + }; + return node + } + /** + * @param {Handle} [and] + * @returns {Handle} + */ + + function closer(and) { + return close + /** + * @this {CompileContext} + * @param {Token} token + * @returns {void} + */ + + function close(token) { + if (and) and.call(this, token); + exit.call(this, token); + } + } + /** @type {CompileContext['exit']} */ + + function exit(token) { + const node = this.stack.pop(); + const open = this.tokenStack.pop(); + + if (!open) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): it’s not open' + ) + } else if (open.type !== token.type) { + throw new Error( + 'Cannot close `' + + token.type + + '` (' + + stringifyPosition({ + start: token.start, + end: token.end + }) + + '): a different token (`' + + open.type + + '`, ' + + stringifyPosition({ + start: open.start, + end: open.end + }) + + ') is open' + ) + } + + node.position.end = point(token.end); + return node + } + /** + * @this {CompileContext} + * @returns {string} + */ + + function resume() { + return toString(this.stack.pop()) + } // + // Handlers. + // + + /** @type {Handle} */ + + function onenterlistordered() { + setData('expectingFirstListItemValue', true); + } + /** @type {Handle} */ + + function onenterlistitemvalue(token) { + if (getData('expectingFirstListItemValue')) { + const ancestor = this.stack[this.stack.length - 2]; + ancestor.start = Number.parseInt(this.sliceSerialize(token), 10); + setData('expectingFirstListItemValue'); + } + } + /** @type {Handle} */ + + function onexitcodefencedfenceinfo() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.lang = data; + } + /** @type {Handle} */ + + function onexitcodefencedfencemeta() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.meta = data; + } + /** @type {Handle} */ + + function onexitcodefencedfence() { + // Exit if this is the closing fence. + if (getData('flowCodeInside')) return + this.buffer(); + setData('flowCodeInside', true); + } + /** @type {Handle} */ + + function onexitcodefenced() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data.replace(/^(\r?\n|\r)|(\r?\n|\r)$/g, ''); + setData('flowCodeInside'); + } + /** @type {Handle} */ + + function onexitcodeindented() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data.replace(/(\r?\n|\r)$/g, ''); + } + /** @type {Handle} */ + + function onexitdefinitionlabelstring(token) { + // Discard label, use the source content instead. + const label = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.label = label; + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase(); + } + /** @type {Handle} */ + + function onexitdefinitiontitlestring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.title = data; + } + /** @type {Handle} */ + + function onexitdefinitiondestinationstring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.url = data; + } + /** @type {Handle} */ + + function onexitatxheadingsequence(token) { + const node = this.stack[this.stack.length - 1]; + + if (!node.depth) { + const depth = this.sliceSerialize(token).length; + node.depth = depth; + } + } + /** @type {Handle} */ + + function onexitsetextheadingtext() { + setData('setextHeadingSlurpLineEnding', true); + } + /** @type {Handle} */ + + function onexitsetextheadinglinesequence(token) { + const node = this.stack[this.stack.length - 1]; + node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2; + } + /** @type {Handle} */ + + function onexitsetextheading() { + setData('setextHeadingSlurpLineEnding'); + } + /** @type {Handle} */ + + function onenterdata(token) { + const parent = this.stack[this.stack.length - 1]; + /** @type {Node} */ + + let tail = parent.children[parent.children.length - 1]; + + if (!tail || tail.type !== 'text') { + // Add a new text node. + tail = text(); // @ts-expect-error: we’ll add `end` later. + + tail.position = { + start: point(token.start) + }; // @ts-expect-error: Assume `parent` accepts `text`. + + parent.children.push(tail); + } + + this.stack.push(tail); + } + /** @type {Handle} */ + + function onexitdata(token) { + const tail = this.stack.pop(); + tail.value += this.sliceSerialize(token); + tail.position.end = point(token.end); + } + /** @type {Handle} */ + + function onexitlineending(token) { + const context = this.stack[this.stack.length - 1]; + + // If we’re at a hard break, include the line ending in there. + if (getData('atHardBreak')) { + const tail = context.children[context.children.length - 1]; + tail.position.end = point(token.end); + setData('atHardBreak'); + return + } + + if ( + !getData('setextHeadingSlurpLineEnding') && + config.canContainEols.includes(context.type) + ) { + onenterdata.call(this, token); + onexitdata.call(this, token); + } + } + /** @type {Handle} */ + + function onexithardbreak() { + setData('atHardBreak', true); + } + /** @type {Handle} */ + + function onexithtmlflow() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data; + } + /** @type {Handle} */ + + function onexithtmltext() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data; + } + /** @type {Handle} */ + + function onexitcodetext() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.value = data; + } + /** @type {Handle} */ + + function onexitlink() { + const context = this.stack[this.stack.length - 1]; // To do: clean. + + if (getData('inReference')) { + context.type += 'Reference'; // @ts-expect-error: mutate. + + context.referenceType = getData('referenceType') || 'shortcut'; // @ts-expect-error: mutate. + + delete context.url; + delete context.title; + } else { + // @ts-expect-error: mutate. + delete context.identifier; // @ts-expect-error: mutate. + + delete context.label; + } + + setData('referenceType'); + } + /** @type {Handle} */ + + function onexitimage() { + const context = this.stack[this.stack.length - 1]; // To do: clean. + + if (getData('inReference')) { + context.type += 'Reference'; // @ts-expect-error: mutate. + + context.referenceType = getData('referenceType') || 'shortcut'; // @ts-expect-error: mutate. + + delete context.url; + delete context.title; + } else { + // @ts-expect-error: mutate. + delete context.identifier; // @ts-expect-error: mutate. + + delete context.label; + } + + setData('referenceType'); + } + /** @type {Handle} */ + + function onexitlabeltext(token) { + const ancestor = this.stack[this.stack.length - 2]; + const string = this.sliceSerialize(token); + ancestor.label = decodeString(string); + ancestor.identifier = normalizeIdentifier(string).toLowerCase(); + } + /** @type {Handle} */ + + function onexitlabel() { + const fragment = this.stack[this.stack.length - 1]; + const value = this.resume(); + const node = this.stack[this.stack.length - 1]; // Assume a reference. + + setData('inReference', true); + + if (node.type === 'link') { + // @ts-expect-error: Assume static phrasing content. + node.children = fragment.children; + } else { + node.alt = value; + } + } + /** @type {Handle} */ + + function onexitresourcedestinationstring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.url = data; + } + /** @type {Handle} */ + + function onexitresourcetitlestring() { + const data = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.title = data; + } + /** @type {Handle} */ + + function onexitresource() { + setData('inReference'); + } + /** @type {Handle} */ + + function onenterreference() { + setData('referenceType', 'collapsed'); + } + /** @type {Handle} */ + + function onexitreferencestring(token) { + const label = this.resume(); + const node = this.stack[this.stack.length - 1]; + node.label = label; + node.identifier = normalizeIdentifier( + this.sliceSerialize(token) + ).toLowerCase(); + setData('referenceType', 'full'); + } + /** @type {Handle} */ + + function onexitcharacterreferencemarker(token) { + setData('characterReferenceType', token.type); + } + /** @type {Handle} */ + + function onexitcharacterreferencevalue(token) { + const data = this.sliceSerialize(token); + const type = getData('characterReferenceType'); + /** @type {string} */ + + let value; + + if (type) { + value = decodeNumericCharacterReference( + data, + type === 'characterReferenceMarkerNumeric' ? 10 : 16 + ); + setData('characterReferenceType'); + } else { + // @ts-expect-error `decodeEntity` can return false for invalid named + // character references, but everything we’ve tokenized is valid. + value = decodeEntity(data); + } + + const tail = this.stack.pop(); + tail.value += value; + tail.position.end = point(token.end); + } + /** @type {Handle} */ + + function onexitautolinkprotocol(token) { + onexitdata.call(this, token); + const node = this.stack[this.stack.length - 1]; + node.url = this.sliceSerialize(token); + } + /** @type {Handle} */ + + function onexitautolinkemail(token) { + onexitdata.call(this, token); + const node = this.stack[this.stack.length - 1]; + node.url = 'mailto:' + this.sliceSerialize(token); + } // + // Creaters. + // + + /** @returns {Blockquote} */ + + function blockQuote() { + return { + type: 'blockquote', + children: [] + } + } + /** @returns {Code} */ + + function codeFlow() { + return { + type: 'code', + lang: null, + meta: null, + value: '' + } + } + /** @returns {InlineCode} */ + + function codeText() { + return { + type: 'inlineCode', + value: '' + } + } + /** @returns {Definition} */ + + function definition() { + return { + type: 'definition', + identifier: '', + label: null, + title: null, + url: '' + } + } + /** @returns {Emphasis} */ + + function emphasis() { + return { + type: 'emphasis', + children: [] + } + } + /** @returns {Heading} */ + + function heading() { + // @ts-expect-error `depth` will be set later. + return { + type: 'heading', + depth: undefined, + children: [] + } + } + /** @returns {Break} */ + + function hardBreak() { + return { + type: 'break' + } + } + /** @returns {HTML} */ + + function html() { + return { + type: 'html', + value: '' + } + } + /** @returns {Image} */ + + function image() { + return { + type: 'image', + title: null, + url: '', + alt: null + } + } + /** @returns {Link} */ + + function link() { + return { + type: 'link', + title: null, + url: '', + children: [] + } + } + /** + * @param {Token} token + * @returns {List} + */ + + function list(token) { + return { + type: 'list', + ordered: token.type === 'listOrdered', + start: null, + // @ts-expect-error Patched. + spread: token._spread, + children: [] + } + } + /** + * @param {Token} token + * @returns {ListItem} + */ + + function listItem(token) { + return { + type: 'listItem', + // @ts-expect-error Patched. + spread: token._spread, + checked: null, + children: [] + } + } + /** @returns {Paragraph} */ + + function paragraph() { + return { + type: 'paragraph', + children: [] + } + } + /** @returns {Strong} */ + + function strong() { + return { + type: 'strong', + children: [] + } + } + /** @returns {Text} */ + + function text() { + return { + type: 'text', + value: '' + } + } + /** @returns {ThematicBreak} */ + + function thematicBreak() { + return { + type: 'thematicBreak' + } + } +} +/** + * @param {Extension} combined + * @param {Array.>} extensions + * @returns {Extension} + */ + +function configure$1(combined, extensions) { + let index = -1; + + while (++index < extensions.length) { + const value = extensions[index]; + + if (Array.isArray(value)) { + configure$1(combined, value); + } else { + extension(combined, value); + } + } + + return combined +} +/** + * @param {Extension} combined + * @param {Extension} extension + * @returns {void} + */ + +function extension(combined, extension) { + /** @type {string} */ + let key; + + for (key in extension) { + if (own$5.call(extension, key)) { + const list = key === 'canContainEols' || key === 'transforms'; + const maybe = own$5.call(combined, key) ? combined[key] : undefined; + /* c8 ignore next */ + + const left = maybe || (combined[key] = list ? [] : {}); + const right = extension[key]; + + if (right) { + if (list) { + // @ts-expect-error: `left` is an array. + combined[key] = [...left, ...right]; + } else { + Object.assign(left, right); + } + } + } + } +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('mdast-util-from-markdown').Options} Options + */ + +/** @type {import('unified').Plugin<[Options?] | void[], string, Root>} */ +function remarkParse(options) { + /** @type {import('unified').ParserFunction} */ + const parser = (doc) => { + // Assume options. + const settings = /** @type {Options} */ (this.data('settings')); + + return fromMarkdown( + doc, + Object.assign({}, settings, options, { + // Note: these options are not in the readme. + // The goal is for them to be set by plugins on `data` instead of being + // passed by users. + extensions: this.data('micromarkExtensions') || [], + mdastExtensions: this.data('fromMarkdownExtensions') || [] + }) + ) + }; + + Object.assign(this, {Parser: parser}); +} + +var own$4 = {}.hasOwnProperty; + +/** + * @callback Handler + * @param {...unknown} value + * @return {unknown} + * + * @typedef {Record} Handlers + * + * @typedef {Object} Options + * @property {Handler} [unknown] + * @property {Handler} [invalid] + * @property {Handlers} [handlers] + */ + +/** + * Handle values based on a property. + * + * @param {string} key + * @param {Options} [options] + */ +function zwitch(key, options) { + var settings = options || {}; + + /** + * Handle one value. + * Based on the bound `key`, a respective handler will be called. + * If `value` is not an object, or doesn’t have a `key` property, the special + * “invalid” handler will be called. + * If `value` has an unknown `key`, the special “unknown” handler will be + * called. + * + * All arguments, and the context object, are passed through to the handler, + * and it’s result is returned. + * + * @param {...unknown} [value] + * @this {unknown} + * @returns {unknown} + * @property {Handler} invalid + * @property {Handler} unknown + * @property {Handlers} handlers + */ + function one(value) { + var fn = one.invalid; + var handlers = one.handlers; + + if (value && own$4.call(value, key)) { + fn = own$4.call(handlers, value[key]) ? handlers[value[key]] : one.unknown; + } + + if (fn) { + return fn.apply(this, arguments) + } + } + + one.handlers = settings.handlers || {}; + one.invalid = settings.invalid; + one.unknown = settings.unknown; + + return one +} + +/** + * @typedef {import('./types.js').Options} Options + * @typedef {import('./types.js').Context} Context + */ + +/** + * @param {Context} base + * @param {Options} extension + * @returns {Context} + */ +function configure(base, extension) { + let index = -1; + /** @type {string} */ + let key; + + // First do subextensions. + if (extension.extensions) { + while (++index < extension.extensions.length) { + configure(base, extension.extensions[index]); + } + } + + for (key in extension) { + if (key === 'extensions') ; else if (key === 'unsafe' || key === 'join') { + /* c8 ignore next 2 */ + // @ts-expect-error: hush. + base[key] = [...(base[key] || []), ...(extension[key] || [])]; + } else if (key === 'handlers') { + base[key] = Object.assign(base[key], extension[key] || {}); + } else { + // @ts-expect-error: hush. + base.options[key] = extension[key]; + } + } + + return base +} + +/** + * @typedef {import('../types.js').Node} Node + * @typedef {import('../types.js').Parent} Parent + * @typedef {import('../types.js').Join} Join + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Parent} parent + * @param {Context} context + * @returns {string} + */ +function containerFlow(parent, context) { + const indexStack = context.indexStack; + const children = parent.children || []; + /** @type {Array.} */ + const results = []; + let index = -1; + + indexStack.push(-1); + + while (++index < children.length) { + const child = children[index]; + + indexStack[indexStack.length - 1] = index; + + results.push( + context.handle(child, parent, context, {before: '\n', after: '\n'}) + ); + + if (child.type !== 'list') { + context.bulletLastUsed = undefined; + } + + if (index < children.length - 1) { + results.push(between(child, children[index + 1])); + } + } + + indexStack.pop(); + + return results.join('') + + /** + * @param {Node} left + * @param {Node} right + * @returns {string} + */ + function between(left, right) { + let index = context.join.length; + + while (index--) { + const result = context.join[index](left, right, parent, context); + + if (result === true || result === 1) { + break + } + + if (typeof result === 'number') { + return '\n'.repeat(1 + result) + } + + if (result === false) { + return '\n\n\n\n' + } + } + + return '\n\n' + } +} + +/** + * @callback Map + * @param {string} value + * @param {number} line + * @param {boolean} blank + * @returns {string} + */ + +const eol = /\r?\n|\r/g; + +/** + * @param {string} value + * @param {Map} map + * @returns {string} + */ +function indentLines(value, map) { + /** @type {Array.} */ + const result = []; + let start = 0; + let line = 0; + /** @type {RegExpExecArray|null} */ + let match; + + while ((match = eol.exec(value))) { + one(value.slice(start, match.index)); + result.push(match[0]); + start = match.index + match[0].length; + line++; + } + + one(value.slice(start)); + + return result.join('') + + /** + * @param {string} value + */ + function one(value) { + result.push(map(value, line, !value)); + } +} + +/** + * @typedef {import('mdast').Blockquote} Blockquote + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../util/indent-lines.js').Map} Map + */ + +/** + * @type {Handle} + * @param {Blockquote} node + */ +function blockquote(node, _, context) { + const exit = context.enter('blockquote'); + const value = indentLines(containerFlow(node, context), map$2); + exit(); + return value +} + +/** @type {Map} */ +function map$2(line, _, blank) { + return '>' + (blank ? '' : ' ') + line +} + +/** + * @typedef {import('../types.js').Unsafe} Unsafe + */ + +/** + * @param {Array.} stack + * @param {Unsafe} pattern + * @returns {boolean} + */ +function patternInScope(stack, pattern) { + return ( + listInScope(stack, pattern.inConstruct, true) && + !listInScope(stack, pattern.notInConstruct, false) + ) +} + +/** + * @param {Array.} stack + * @param {Unsafe['inConstruct']} list + * @param {boolean} none + * @returns {boolean} + */ +function listInScope(stack, list, none) { + if (!list) { + return none + } + + if (typeof list === 'string') { + list = [list]; + } + + let index = -1; + + while (++index < list.length) { + if (stack.includes(list[index])) { + return true + } + } + + return false +} + +/** + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('mdast').Break} Break + */ + +/** + * @type {Handle} + * @param {Break} _ + */ +function hardBreak(_, _1, context, safe) { + let index = -1; + + while (++index < context.unsafe.length) { + // If we can’t put eols in this construct (setext headings, tables), use a + // space instead. + if ( + context.unsafe[index].character === '\n' && + patternInScope(context.stack, context.unsafe[index]) + ) { + return /[ \t]/.test(safe.before) ? '' : ' ' + } + } + + return '\\\n' +} + +/** + * Get the count of the longest repeating streak of `character` in `value`. + * + * @param {string} value Content. + * @param {string} character Single character to look for + * @returns {number} Count of most frequent adjacent `character`s in `value` + */ +function longestStreak(value, character) { + var source = String(value); + var index = source.indexOf(character); + var expected = index; + var count = 0; + var max = 0; + + if (typeof character !== 'string' || character.length !== 1) { + throw new Error('Expected character') + } + + while (index !== -1) { + if (index === expected) { + if (++count > max) { + max = count; + } + } else { + count = 1; + } + + expected = index + 1; + index = source.indexOf(character, expected); + } + + return max +} + +/** + * @typedef {import('mdast').Code} Code + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Code} node + * @param {Context} context + * @returns {boolean} + */ +function formatCodeAsIndented(node, context) { + return Boolean( + !context.options.fences && + node.value && + // If there’s no info… + !node.lang && + // And there’s a non-whitespace character… + /[^ \r\n]/.test(node.value) && + // And the value doesn’t start or end in a blank… + !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node.value) + ) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkFence(context) { + const marker = context.options.fence || '`'; + + if (marker !== '`' && marker !== '~') { + throw new Error( + 'Cannot serialize code with `' + + marker + + '` for `options.fence`, expected `` ` `` or `~`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Unsafe} Unsafe + */ + +/** + * @param {Unsafe} pattern + * @returns {RegExp} + */ +function patternCompile(pattern) { + if (!pattern._compiled) { + const before = + (pattern.atBreak ? '[\\r\\n][\\t ]*' : '') + + (pattern.before ? '(?:' + pattern.before + ')' : ''); + + pattern._compiled = new RegExp( + (before ? '(' + before + ')' : '') + + (/[|\\{}()[\]^$+*?.-]/.test(pattern.character) ? '\\' : '') + + pattern.character + + (pattern.after ? '(?:' + pattern.after + ')' : ''), + 'g' + ); + } + + return pattern._compiled +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').SafeOptions} SafeOptions + */ + +/** + * @param {Context} context + * @param {string|null|undefined} input + * @param {SafeOptions & {encode?: Array.}} config + * @returns {string} + */ +function safe(context, input, config) { + const value = (config.before || '') + (input || '') + (config.after || ''); + /** @type {Array.} */ + const positions = []; + /** @type {Array.} */ + const result = []; + /** @type {Record} */ + const infos = {}; + let index = -1; + + while (++index < context.unsafe.length) { + const pattern = context.unsafe[index]; + + if (!patternInScope(context.stack, pattern)) { + continue + } + + const expression = patternCompile(pattern); + /** @type {RegExpExecArray|null} */ + let match; + + while ((match = expression.exec(value))) { + const before = 'before' in pattern || Boolean(pattern.atBreak); + const after = 'after' in pattern; + const position = match.index + (before ? match[1].length : 0); + + if (positions.includes(position)) { + if (infos[position].before && !before) { + infos[position].before = false; + } + + if (infos[position].after && !after) { + infos[position].after = false; + } + } else { + positions.push(position); + infos[position] = {before, after}; + } + } + } + + positions.sort(numerical); + + let start = config.before ? config.before.length : 0; + const end = value.length - (config.after ? config.after.length : 0); + index = -1; + + while (++index < positions.length) { + const position = positions[index]; + + // Character before or after matched: + if (position < start || position >= end) { + continue + } + + // If this character is supposed to be escaped because it has a condition on + // the next character, and the next character is definitly being escaped, + // then skip this escape. + if ( + (position + 1 < end && + positions[index + 1] === position + 1 && + infos[position].after && + !infos[position + 1].before && + !infos[position + 1].after) || + (positions[index - 1] === position - 1 && + infos[position].before && + !infos[position - 1].before && + !infos[position - 1].after) + ) { + continue + } + + if (start !== position) { + // If we have to use a character reference, an ampersand would be more + // correct, but as backslashes only care about punctuation, either will + // do the trick + result.push(escapeBackslashes(value.slice(start, position), '\\')); + } + + start = position; + + if ( + /[!-/:-@[-`{-~]/.test(value.charAt(position)) && + (!config.encode || !config.encode.includes(value.charAt(position))) + ) { + // Character escape. + result.push('\\'); + } else { + // Character reference. + result.push( + '&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';' + ); + start++; + } + } + + result.push(escapeBackslashes(value.slice(start, end), config.after)); + + return result.join('') +} + +/** + * @param {number} a + * @param {number} b + * @returns {number} + */ +function numerical(a, b) { + return a - b +} + +/** + * @param {string} value + * @param {string} after + * @returns {string} + */ +function escapeBackslashes(value, after) { + const expression = /\\(?=[!-/:-@[-`{-~])/g; + /** @type {Array.} */ + const positions = []; + /** @type {Array.} */ + const results = []; + const whole = value + after; + let index = -1; + let start = 0; + /** @type {RegExpExecArray|null} */ + let match; + + while ((match = expression.exec(whole))) { + positions.push(match.index); + } + + while (++index < positions.length) { + if (start !== positions[index]) { + results.push(value.slice(start, positions[index])); + } + + results.push('\\'); + start = positions[index]; + } + + results.push(value.slice(start)); + + return results.join('') +} + +/** + * @typedef {import('mdast').Code} Code + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../types.js').Exit} Exit + * @typedef {import('../util/indent-lines.js').Map} Map + */ + +/** + * @type {Handle} + * @param {Code} node + */ +function code$1(node, _, context) { + const marker = checkFence(context); + const raw = node.value || ''; + const suffix = marker === '`' ? 'GraveAccent' : 'Tilde'; + /** @type {string} */ + let value; + /** @type {Exit} */ + let exit; + + if (formatCodeAsIndented(node, context)) { + exit = context.enter('codeIndented'); + value = indentLines(raw, map$1); + } else { + const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3)); + /** @type {Exit} */ + let subexit; + exit = context.enter('codeFenced'); + value = sequence; + + if (node.lang) { + subexit = context.enter('codeFencedLang' + suffix); + value += safe(context, node.lang, { + before: '`', + after: ' ', + encode: ['`'] + }); + subexit(); + } + + if (node.lang && node.meta) { + subexit = context.enter('codeFencedMeta' + suffix); + value += + ' ' + + safe(context, node.meta, { + before: ' ', + after: '\n', + encode: ['`'] + }); + subexit(); + } + + value += '\n'; + + if (raw) { + value += raw + '\n'; + } + + value += sequence; + } + + exit(); + return value +} + +/** @type {Map} */ +function map$1(line, _, blank) { + return (blank ? '' : ' ') + line +} + +/** + * @typedef {import('mdast').Association} Association + */ + +/** + * The `label` of an association is the string value: character escapes and + * references work, and casing is intact. + * The `identifier` is used to match one association to another: controversially, + * character escapes and references don’t work in this matching: `©` does + * not match `©`, and `\+` does not match `+`. + * But casing is ignored (and whitespace) is trimmed and collapsed: ` A\nb` + * matches `a b`. + * So, we do prefer the label when figuring out how we’re going to serialize: + * it has whitespace, casing, and we can ignore most useless character escapes + * and all character references. + * + * @param {Association} node + * @returns {string} + */ +function association(node) { + if (node.label || !node.identifier) { + return node.label || '' + } + + return decodeString(node.identifier) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkQuote(context) { + const marker = context.options.quote || '"'; + + if (marker !== '"' && marker !== "'") { + throw new Error( + 'Cannot serialize title with `' + + marker + + '` for `options.quote`, expected `"`, or `\'`' + ) + } + + return marker +} + +/** + * @typedef {import('mdast').Definition} Definition + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Definition} node + */ +function definition(node, _, context) { + const marker = checkQuote(context); + const suffix = marker === '"' ? 'Quote' : 'Apostrophe'; + const exit = context.enter('definition'); + let subexit = context.enter('label'); + let value = + '[' + safe(context, association(node), {before: '[', after: ']'}) + ']: '; + + subexit(); + + if ( + // If there’s no url, or… + !node.url || + // If there’s whitespace, enclosed is prettier. + /[ \t\r\n]/.test(node.url) + ) { + subexit = context.enter('destinationLiteral'); + value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; + } else { + // No whitespace, raw is prettier. + subexit = context.enter('destinationRaw'); + value += safe(context, node.url, {before: ' ', after: ' '}); + } + + subexit(); + + if (node.title) { + subexit = context.enter('title' + suffix); + value += + ' ' + + marker + + safe(context, node.title, {before: marker, after: marker}) + + marker; + subexit(); + } + + exit(); + + return value +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkEmphasis(context) { + const marker = context.options.emphasis || '*'; + + if (marker !== '*' && marker !== '_') { + throw new Error( + 'Cannot serialize emphasis with `' + + marker + + '` for `options.emphasis`, expected `*`, or `_`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Node} Node + * @typedef {import('../types.js').Parent} Parent + * @typedef {import('../types.js').SafeOptions} SafeOptions + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Parent} parent + * @param {Context} context + * @param {SafeOptions} safeOptions + * @returns {string} + */ +function containerPhrasing(parent, context, safeOptions) { + const indexStack = context.indexStack; + const children = parent.children || []; + /** @type {Array.} */ + const results = []; + let index = -1; + let before = safeOptions.before; + + indexStack.push(-1); + + while (++index < children.length) { + const child = children[index]; + /** @type {string} */ + let after; + + indexStack[indexStack.length - 1] = index; + + if (index + 1 < children.length) { + // @ts-expect-error: hush, it’s actually a `zwitch`. + let handle = context.handle.handlers[children[index + 1].type]; + if (handle && handle.peek) handle = handle.peek; + after = handle + ? handle(children[index + 1], parent, context, { + before: '', + after: '' + }).charAt(0) + : ''; + } else { + after = safeOptions.after; + } + + // In some cases, html (text) can be found in phrasing right after an eol. + // When we’d serialize that, in most cases that would be seen as html + // (flow). + // As we can’t escape or so to prevent it from happening, we take a somewhat + // reasonable approach: replace that eol with a space. + // See: + if ( + results.length > 0 && + (before === '\r' || before === '\n') && + child.type === 'html' + ) { + results[results.length - 1] = results[results.length - 1].replace( + /(\r?\n|\r)$/, + ' ' + ); + before = ' '; + } + + results.push(context.handle(child, parent, context, {before, after})); + + before = results[results.length - 1].slice(-1); + } + + indexStack.pop(); + + return results.join('') +} + +/** + * @typedef {import('mdast').Emphasis} Emphasis + * @typedef {import('../types.js').Handle} Handle + */ + +emphasis.peek = emphasisPeek; + +// To do: there are cases where emphasis cannot “form” depending on the +// previous or next character of sequences. +// There’s no way around that though, except for injecting zero-width stuff. +// Do we need to safeguard against that? +/** + * @type {Handle} + * @param {Emphasis} node + */ +function emphasis(node, _, context) { + const marker = checkEmphasis(context); + const exit = context.enter('emphasis'); + const value = containerPhrasing(node, context, { + before: marker, + after: marker + }); + exit(); + return marker + value + marker +} + +/** + * @type {Handle} + * @param {Emphasis} _ + */ +function emphasisPeek(_, _1, context) { + return context.options.emphasis || '*' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * + * @typedef {string} Type + * @typedef {Object} Props + * + * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test + */ + +const convert = + /** + * @type {( + * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & + * ((test?: Test) => AssertAnything) + * )} + */ + ( + /** + * Generate an assertion from a check. + * @param {Test} [test] + * When nullish, checks if `node` is a `Node`. + * When `string`, works like passing `function (node) {return node.type === test}`. + * When `function` checks if function passed the node is true. + * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. + * When `array`, checks any one of the subtests pass. + * @returns {AssertAnything} + */ + function (test) { + if (test === undefined || test === null) { + return ok + } + + if (typeof test === 'string') { + return typeFactory(test) + } + + if (typeof test === 'object') { + return Array.isArray(test) ? anyFactory(test) : propsFactory(test) + } + + if (typeof test === 'function') { + return castFactory(test) + } + + throw new Error('Expected function, string, or object as test') + } + ); +/** + * @param {Array.} tests + * @returns {AssertAnything} + */ +function anyFactory(tests) { + /** @type {Array.} */ + const checks = []; + let index = -1; + + while (++index < tests.length) { + checks[index] = convert(tests[index]); + } + + return castFactory(any) + + /** + * @this {unknown} + * @param {unknown[]} parameters + * @returns {boolean} + */ + function any(...parameters) { + let index = -1; + + while (++index < checks.length) { + if (checks[index].call(this, ...parameters)) return true + } + + return false + } +} + +/** + * Utility to assert each property in `test` is represented in `node`, and each + * values are strictly equal. + * + * @param {Props} check + * @returns {AssertAnything} + */ +function propsFactory(check) { + return castFactory(all) + + /** + * @param {Node} node + * @returns {boolean} + */ + function all(node) { + /** @type {string} */ + let key; + + for (key in check) { + // @ts-expect-error: hush, it sure works as an index. + if (node[key] !== check[key]) return false + } + + return true + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * + * @param {Type} check + * @returns {AssertAnything} + */ +function typeFactory(check) { + return castFactory(type) + + /** + * @param {Node} node + */ + function type(node) { + return node && node.type === check + } +} + +/** + * Utility to convert a string into a function which checks a given node’s type + * for said string. + * @param {TestFunctionAnything} check + * @returns {AssertAnything} + */ +function castFactory(check) { + return assertion + + /** + * @this {unknown} + * @param {Array.} parameters + * @returns {boolean} + */ + function assertion(...parameters) { + // @ts-expect-error: spreading is fine. + return Boolean(check.call(this, ...parameters)) + } +} + +// Utility to return true. +function ok() { + return true +} + +/** + * @param {string} d + * @returns {string} + */ +function color$1(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('./complex-types').Action} Action + * @typedef {import('./complex-types').Index} Index + * @typedef {import('./complex-types').ActionTuple} ActionTuple + * @typedef {import('./complex-types').VisitorResult} VisitorResult + * @typedef {import('./complex-types').Visitor} Visitor + */ + +/** + * Continue traversing as normal + */ +const CONTINUE$1 = true; +/** + * Do not traverse this node’s children + */ +const SKIP$1 = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT$1 = false; + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test node, optional + * @param visitor Function to run for each node + * @param reverse Visit the tree in reverse order, defaults to false + */ +const visitParents$1 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: import('./complex-types').BuildVisitor, reverse?: boolean) => void) & + * ((tree: Tree, visitor: import('./complex-types').BuildVisitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {import('./complex-types').Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-expect-error no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + + const is = convert(test); + const step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + // @ts-expect-error: hush + const value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string|undefined} */ + let name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color$1(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + + return visit + + function visit() { + /** @type {ActionTuple} */ + let result = []; + /** @type {ActionTuple} */ + let subresult; + /** @type {number} */ + let offset; + /** @type {Array.} */ + let grandparents; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult$1(visitor(node, parents)); + + if (result[0] === EXIT$1) { + return result + } + } + + // @ts-expect-error looks like a parent. + if (node.children && result[0] !== SKIP$1) { + // @ts-expect-error looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-expect-error looks like a parent. + grandparents = parents.concat(node); + + // @ts-expect-error looks like a parent. + while (offset > -1 && offset < node.children.length) { + // @ts-expect-error looks like a parent. + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT$1) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } + + return result + } + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult$1(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$1, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +/** + * Visit children of tree which pass a test + * + * @param tree Abstract syntax tree to walk + * @param test Test, optional + * @param visitor Function to run for each node + * @param reverse Fisit the tree in reverse, defaults to false + */ +const visit$1 = + /** + * @type {( + * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & + * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) + * )} + */ + ( + /** + * @param {Node} tree + * @param {Test} test + * @param {Visitor} visitor + * @param {boolean} [reverse] + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents$1(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + const parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('mdast').Heading} Heading + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Heading} node + * @param {Context} context + * @returns {boolean} + */ +function formatHeadingAsSetext(node, context) { + let literalWithBreak = false; + + // Look for literals with a line break. + // Note that this also + visit$1(node, (node) => { + if ( + ('value' in node && /\r?\n|\r/.test(node.value)) || + node.type === 'break' + ) { + literalWithBreak = true; + return EXIT$1 + } + }); + + return Boolean( + (!node.depth || node.depth < 3) && + toString(node) && + (context.options.setext || literalWithBreak) + ) +} + +/** + * @typedef {import('mdast').Heading} Heading + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../types.js').Exit} Exit + */ + +/** + * @type {Handle} + * @param {Heading} node + */ +function heading(node, _, context) { + const rank = Math.max(Math.min(6, node.depth || 1), 1); + + if (formatHeadingAsSetext(node, context)) { + const exit = context.enter('headingSetext'); + const subexit = context.enter('phrasing'); + const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); + subexit(); + exit(); + + return ( + value + + '\n' + + (rank === 1 ? '=' : '-').repeat( + // The whole size… + value.length - + // Minus the position of the character after the last EOL (or + // 0 if there is none)… + (Math.max(value.lastIndexOf('\r'), value.lastIndexOf('\n')) + 1) + ) + ) + } + + const sequence = '#'.repeat(rank); + const exit = context.enter('headingAtx'); + const subexit = context.enter('phrasing'); + let value = containerPhrasing(node, context, {before: '# ', after: '\n'}); + + if (/^[\t ]/.test(value)) { + value = + '&#x' + + value.charCodeAt(0).toString(16).toUpperCase() + + ';' + + value.slice(1); + } + + value = value ? sequence + ' ' + value : sequence; + + if (context.options.closeAtx) { + value += ' ' + sequence; + } + + subexit(); + exit(); + + return value +} + +/** + * @typedef {import('mdast').HTML} HTML + * @typedef {import('../types.js').Handle} Handle + */ + +html.peek = htmlPeek; + +/** + * @type {Handle} + * @param {HTML} node + */ +function html(node) { + return node.value || '' +} + +/** + * @type {Handle} + */ +function htmlPeek() { + return '<' +} + +/** + * @typedef {import('mdast').Image} Image + * @typedef {import('../types.js').Handle} Handle + */ + +image.peek = imagePeek; + +/** + * @type {Handle} + * @param {Image} node + */ +function image(node, _, context) { + const quote = checkQuote(context); + const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; + const exit = context.enter('image'); + let subexit = context.enter('label'); + let value = '![' + safe(context, node.alt, {before: '[', after: ']'}) + ']('; + + subexit(); + + if ( + // If there’s no url but there is a title… + (!node.url && node.title) || + // Or if there’s markdown whitespace or an eol, enclose. + /[ \t\r\n]/.test(node.url) + ) { + subexit = context.enter('destinationLiteral'); + value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; + } else { + // No whitespace, raw is prettier. + subexit = context.enter('destinationRaw'); + value += safe(context, node.url, { + before: '(', + after: node.title ? ' ' : ')' + }); + } + + subexit(); + + if (node.title) { + subexit = context.enter('title' + suffix); + value += + ' ' + + quote + + safe(context, node.title, {before: quote, after: quote}) + + quote; + subexit(); + } + + value += ')'; + exit(); + + return value +} + +/** + * @type {Handle} + */ +function imagePeek() { + return '!' +} + +/** + * @typedef {import('mdast').ImageReference} ImageReference + * @typedef {import('../types.js').Handle} Handle + */ + +imageReference.peek = imageReferencePeek; + +/** + * @type {Handle} + * @param {ImageReference} node + */ +function imageReference(node, _, context) { + const type = node.referenceType; + const exit = context.enter('imageReference'); + let subexit = context.enter('label'); + const alt = safe(context, node.alt, {before: '[', after: ']'}); + let value = '![' + alt + ']'; + + subexit(); + // Hide the fact that we’re in phrasing, because escapes don’t work. + const stack = context.stack; + context.stack = []; + subexit = context.enter('reference'); + const reference = safe(context, association(node), {before: '[', after: ']'}); + subexit(); + context.stack = stack; + exit(); + + if (type === 'full' || !alt || alt !== reference) { + value += '[' + reference + ']'; + } else if (type !== 'shortcut') { + value += '[]'; + } + + return value +} + +/** + * @type {Handle} + */ +function imageReferencePeek() { + return '!' +} + +/** + * @typedef {import('mdast').InlineCode} InlineCode + * @typedef {import('../types.js').Handle} Handle + */ + +inlineCode.peek = inlineCodePeek; + +/** + * @type {Handle} + * @param {InlineCode} node + */ +function inlineCode(node, _, context) { + let value = node.value || ''; + let sequence = '`'; + let index = -1; + + // If there is a single grave accent on its own in the code, use a fence of + // two. + // If there are two in a row, use one. + while (new RegExp('(^|[^`])' + sequence + '([^`]|$)').test(value)) { + sequence += '`'; + } + + // If this is not just spaces or eols (tabs don’t count), and either the + // first or last character are a space, eol, or tick, then pad with spaces. + if ( + /[^ \r\n]/.test(value) && + ((/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value)) || /^`|`$/.test(value)) + ) { + value = ' ' + value + ' '; + } + + // We have a potential problem: certain characters after eols could result in + // blocks being seen. + // For example, if someone injected the string `'\n# b'`, then that would + // result in an ATX heading. + // We can’t escape characters in `inlineCode`, but because eols are + // transformed to spaces when going from markdown to HTML anyway, we can swap + // them out. + while (++index < context.unsafe.length) { + const pattern = context.unsafe[index]; + const expression = patternCompile(pattern); + /** @type {RegExpExecArray|null} */ + let match; + + // Only look for `atBreak`s. + // Btw: note that `atBreak` patterns will always start the regex at LF or + // CR. + if (!pattern.atBreak) continue + + while ((match = expression.exec(value))) { + let position = match.index; + + // Support CRLF (patterns only look for one of the characters). + if ( + value.charCodeAt(position) === 10 /* `\n` */ && + value.charCodeAt(position - 1) === 13 /* `\r` */ + ) { + position--; + } + + value = value.slice(0, position) + ' ' + value.slice(match.index + 1); + } + } + + return sequence + value + sequence +} + +/** + * @type {Handle} + */ +function inlineCodePeek() { + return '`' +} + +/** + * @typedef {import('mdast').Link} Link + * @typedef {import('../types.js').Context} Context + */ + +/** + * @param {Link} node + * @param {Context} context + * @returns {boolean} + */ +function formatLinkAsAutolink(node, context) { + const raw = toString(node); + + return Boolean( + !context.options.resourceLink && + // If there’s a url… + node.url && + // And there’s a no title… + !node.title && + // And the content of `node` is a single text node… + node.children && + node.children.length === 1 && + node.children[0].type === 'text' && + // And if the url is the same as the content… + (raw === node.url || 'mailto:' + raw === node.url) && + // And that starts w/ a protocol… + /^[a-z][a-z+.-]+:/i.test(node.url) && + // And that doesn’t contain ASCII control codes (character escapes and + // references don’t work) or angle brackets… + !/[\0- <>\u007F]/.test(node.url) + ) +} + +/** + * @typedef {import('mdast').Link} Link + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('../types.js').Exit} Exit + */ + +link.peek = linkPeek; + +/** + * @type {Handle} + * @param {Link} node + */ +function link(node, _, context) { + const quote = checkQuote(context); + const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; + /** @type {Exit} */ + let exit; + /** @type {Exit} */ + let subexit; + /** @type {string} */ + let value; + + if (formatLinkAsAutolink(node, context)) { + // Hide the fact that we’re in phrasing, because escapes don’t work. + const stack = context.stack; + context.stack = []; + exit = context.enter('autolink'); + value = + '<' + containerPhrasing(node, context, {before: '<', after: '>'}) + '>'; + exit(); + context.stack = stack; + return value + } + + exit = context.enter('link'); + subexit = context.enter('label'); + value = + '[' + containerPhrasing(node, context, {before: '[', after: ']'}) + ']('; + subexit(); + + if ( + // If there’s no url but there is a title… + (!node.url && node.title) || + // Or if there’s markdown whitespace or an eol, enclose. + /[ \t\r\n]/.test(node.url) + ) { + subexit = context.enter('destinationLiteral'); + value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; + } else { + // No whitespace, raw is prettier. + subexit = context.enter('destinationRaw'); + value += safe(context, node.url, { + before: '(', + after: node.title ? ' ' : ')' + }); + } + + subexit(); + + if (node.title) { + subexit = context.enter('title' + suffix); + value += + ' ' + + quote + + safe(context, node.title, {before: quote, after: quote}) + + quote; + subexit(); + } + + value += ')'; + + exit(); + return value +} + +/** + * @type {Handle} + * @param {Link} node + */ +function linkPeek(node, _, context) { + return formatLinkAsAutolink(node, context) ? '<' : '[' +} + +/** + * @typedef {import('mdast').LinkReference} LinkReference + * @typedef {import('../types.js').Handle} Handle + */ + +linkReference.peek = linkReferencePeek; + +/** + * @type {Handle} + * @param {LinkReference} node + */ +function linkReference(node, _, context) { + const type = node.referenceType; + const exit = context.enter('linkReference'); + let subexit = context.enter('label'); + const text = containerPhrasing(node, context, {before: '[', after: ']'}); + let value = '[' + text + ']'; + + subexit(); + // Hide the fact that we’re in phrasing, because escapes don’t work. + const stack = context.stack; + context.stack = []; + subexit = context.enter('reference'); + const reference = safe(context, association(node), {before: '[', after: ']'}); + subexit(); + context.stack = stack; + exit(); + + if (type === 'full' || !text || text !== reference) { + value += '[' + reference + ']'; + } else if (type !== 'shortcut') { + value += '[]'; + } + + return value +} + +/** + * @type {Handle} + */ +function linkReferencePeek() { + return '[' +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBullet(context) { + const marker = context.options.bullet || '*'; + + if (marker !== '*' && marker !== '+' && marker !== '-') { + throw new Error( + 'Cannot serialize items with `' + + marker + + '` for `options.bullet`, expected `*`, `+`, or `-`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBulletOther(context) { + const bullet = checkBullet(context); + const bulletOther = context.options.bulletOther; + + if (!bulletOther) { + return bullet === '*' ? '-' : '*' + } + + if (bulletOther !== '*' && bulletOther !== '+' && bulletOther !== '-') { + throw new Error( + 'Cannot serialize items with `' + + bulletOther + + '` for `options.bulletOther`, expected `*`, `+`, or `-`' + ) + } + + if (bulletOther === bullet) { + throw new Error( + 'Expected `bullet` (`' + + bullet + + '`) and `bulletOther` (`' + + bulletOther + + '`) to be different' + ) + } + + return bulletOther +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBulletOrdered(context) { + const marker = context.options.bulletOrdered || '.'; + + if (marker !== '.' && marker !== ')') { + throw new Error( + 'Cannot serialize items with `' + + marker + + '` for `options.bulletOrdered`, expected `.` or `)`' + ) + } + + return marker +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkBulletOrderedOther(context) { + const bulletOrdered = checkBulletOrdered(context); + const bulletOrderedOther = context.options.bulletOrderedOther; + + if (!bulletOrderedOther) { + return bulletOrdered === '.' ? ')' : '.' + } + + if (bulletOrderedOther !== '.' && bulletOrderedOther !== ')') { + throw new Error( + 'Cannot serialize items with `' + + bulletOrderedOther + + '` for `options.bulletOrderedOther`, expected `*`, `+`, or `-`' + ) + } + + if (bulletOrderedOther === bulletOrdered) { + throw new Error( + 'Expected `bulletOrdered` (`' + + bulletOrdered + + '`) and `bulletOrderedOther` (`' + + bulletOrderedOther + + '`) to be different' + ) + } + + return bulletOrderedOther +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkRule(context) { + const marker = context.options.rule || '*'; + + if (marker !== '*' && marker !== '-' && marker !== '_') { + throw new Error( + 'Cannot serialize rules with `' + + marker + + '` for `options.rule`, expected `*`, `-`, or `_`' + ) + } + + return marker +} + +/** + * @typedef {import('mdast').List} List + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {List} node + */ +function list(node, parent, context) { + const exit = context.enter('list'); + const bulletCurrent = context.bulletCurrent; + /** @type {string} */ + let bullet = node.ordered ? checkBulletOrdered(context) : checkBullet(context); + /** @type {string} */ + const bulletOther = node.ordered + ? checkBulletOrderedOther(context) + : checkBulletOther(context); + const bulletLastUsed = context.bulletLastUsed; + let useDifferentMarker = false; + + if ( + parent && + // Explicit `other` set. + (node.ordered + ? context.options.bulletOrderedOther + : context.options.bulletOther) && + bulletLastUsed && + bullet === bulletLastUsed + ) { + useDifferentMarker = true; + } + + if (!node.ordered) { + const firstListItem = node.children ? node.children[0] : undefined; + + // If there’s an empty first list item directly in two list items, + // we have to use a different bullet: + // + // ```markdown + // * - * + // ``` + // + // …because otherwise it would become one big thematic break. + if ( + // Bullet could be used as a thematic break marker: + (bullet === '*' || bullet === '-') && + // Empty first list item: + firstListItem && + (!firstListItem.children || !firstListItem.children[0]) && + // Directly in two other list items: + context.stack[context.stack.length - 1] === 'list' && + context.stack[context.stack.length - 2] === 'listItem' && + context.stack[context.stack.length - 3] === 'list' && + context.stack[context.stack.length - 4] === 'listItem' && + // That are each the first child. + context.indexStack[context.indexStack.length - 1] === 0 && + context.indexStack[context.indexStack.length - 2] === 0 && + context.indexStack[context.indexStack.length - 3] === 0 && + context.indexStack[context.indexStack.length - 4] === 0 + ) { + useDifferentMarker = true; + } + + // If there’s a thematic break at the start of the first list item, + // we have to use a different bullet: + // + // ```markdown + // * --- + // ``` + // + // …because otherwise it would become one big thematic break. + if (checkRule(context) === bullet && firstListItem) { + let index = -1; + + while (++index < node.children.length) { + const item = node.children[index]; + + if ( + item && + item.type === 'listItem' && + item.children && + item.children[0] && + item.children[0].type === 'thematicBreak' + ) { + useDifferentMarker = true; + break + } + } + } + } + + if (useDifferentMarker) { + bullet = bulletOther; + } + + context.bulletCurrent = bullet; + const value = containerFlow(node, context); + context.bulletLastUsed = bullet; + context.bulletCurrent = bulletCurrent; + exit(); + return value +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkListItemIndent(context) { + const style = context.options.listItemIndent || 'tab'; + + // To do: remove in a major. + // @ts-expect-error: deprecated. + if (style === 1 || style === '1') { + return 'one' + } + + if (style !== 'tab' && style !== 'one' && style !== 'mixed') { + throw new Error( + 'Cannot serialize items with `' + + style + + '` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`' + ) + } + + return style +} + +/** + * @typedef {import('mdast').ListItem} ListItem + * @typedef {import('mdast').List} List + * @typedef {import('../util/indent-lines.js').Map} Map + * @typedef {import('../types.js').Options} Options + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {ListItem} node + */ +function listItem(node, parent, context) { + const listItemIndent = checkListItemIndent(context); + let bullet = context.bulletCurrent || checkBullet(context); + + // Add the marker value for ordered lists. + if (parent && parent.type === 'list' && parent.ordered) { + bullet = + (typeof parent.start === 'number' && parent.start > -1 + ? parent.start + : 1) + + (context.options.incrementListMarker === false + ? 0 + : parent.children.indexOf(node)) + + bullet; + } + + let size = bullet.length + 1; + + if ( + listItemIndent === 'tab' || + (listItemIndent === 'mixed' && + ((parent && parent.type === 'list' && parent.spread) || node.spread)) + ) { + size = Math.ceil(size / 4) * 4; + } + + const exit = context.enter('listItem'); + const value = indentLines(containerFlow(node, context), map); + exit(); + + return value + + /** @type {Map} */ + function map(line, index, blank) { + if (index) { + return (blank ? '' : ' '.repeat(size)) + line + } + + return (blank ? bullet : bullet + ' '.repeat(size - bullet.length)) + line + } +} + +/** + * @typedef {import('mdast').Paragraph} Paragraph + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Paragraph} node + */ +function paragraph(node, _, context) { + const exit = context.enter('paragraph'); + const subexit = context.enter('phrasing'); + const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); + subexit(); + exit(); + return value +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Root} node + */ +function root(node, _, context) { + return containerFlow(node, context) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkStrong(context) { + const marker = context.options.strong || '*'; + + if (marker !== '*' && marker !== '_') { + throw new Error( + 'Cannot serialize strong with `' + + marker + + '` for `options.strong`, expected `*`, or `_`' + ) + } + + return marker +} + +/** + * @typedef {import('mdast').Strong} Strong + * @typedef {import('../types.js').Handle} Handle + */ + +strong.peek = strongPeek; + +// To do: there are cases where emphasis cannot “form” depending on the +// previous or next character of sequences. +// There’s no way around that though, except for injecting zero-width stuff. +// Do we need to safeguard against that? +/** + * @type {Handle} + * @param {Strong} node + */ +function strong(node, _, context) { + const marker = checkStrong(context); + const exit = context.enter('strong'); + const value = containerPhrasing(node, context, { + before: marker, + after: marker + }); + exit(); + return marker + marker + value + marker + marker +} + +/** + * @type {Handle} + * @param {Strong} _ + */ +function strongPeek(_, _1, context) { + return context.options.strong || '*' +} + +/** + * @typedef {import('mdast').Text} Text + * @typedef {import('../types.js').Handle} Handle + */ + +/** + * @type {Handle} + * @param {Text} node + */ +function text$1(node, _, context, safeOptions) { + return safe(context, node.value, safeOptions) +} + +/** + * @typedef {import('../types.js').Context} Context + * @typedef {import('../types.js').Options} Options + */ + +/** + * @param {Context} context + * @returns {Exclude} + */ +function checkRuleRepetition(context) { + const repetition = context.options.ruleRepetition || 3; + + if (repetition < 3) { + throw new Error( + 'Cannot serialize rules with repetition `' + + repetition + + '` for `options.ruleRepetition`, expected `3` or more' + ) + } + + return repetition +} + +/** + * @typedef {import('../types.js').Handle} Handle + * @typedef {import('mdast').ThematicBreak} ThematicBreak + */ + +/** + * @type {Handle} + * @param {ThematicBreak} _ + */ +function thematicBreak(_, _1, context) { + const value = ( + checkRule(context) + (context.options.ruleSpaces ? ' ' : '') + ).repeat(checkRuleRepetition(context)); + + return context.options.ruleSpaces ? value.slice(0, -1) : value +} + +const handle = { + blockquote, + break: hardBreak, + code: code$1, + definition, + emphasis, + hardBreak, + heading, + html, + image, + imageReference, + inlineCode, + link, + linkReference, + list, + listItem, + paragraph, + root, + strong, + text: text$1, + thematicBreak +}; + +/** + * @typedef {import('./types.js').Join} Join + */ + +/** @type {Array.} */ +const join = [joinDefaults]; + +/** @type {Join} */ +function joinDefaults(left, right, parent, context) { + // Indented code after list or another indented code. + if ( + right.type === 'code' && + formatCodeAsIndented(right, context) && + (left.type === 'list' || + (left.type === right.type && formatCodeAsIndented(left, context))) + ) { + return false + } + + // Two lists with the same marker. + if ( + left.type === 'list' && + left.type === right.type && + Boolean(left.ordered) === Boolean(right.ordered) && + !(left.ordered + ? context.options.bulletOrderedOther + : context.options.bulletOther) + ) { + return false + } + + // Join children of a list or an item. + // In which case, `parent` has a `spread` field. + if ('spread' in parent && typeof parent.spread === 'boolean') { + if ( + left.type === 'paragraph' && + // Two paragraphs. + (left.type === right.type || + right.type === 'definition' || + // Paragraph followed by a setext heading. + (right.type === 'heading' && formatHeadingAsSetext(right, context))) + ) { + return + } + + return parent.spread ? 1 : 0 + } +} + +/** + * @typedef {import('./types.js').Unsafe} Unsafe + */ + +/** @type {Array.} */ +const unsafe = [ + {character: '\t', after: '[\\r\\n]', inConstruct: 'phrasing'}, + {character: '\t', before: '[\\r\\n]', inConstruct: 'phrasing'}, + { + character: '\t', + inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] + }, + { + character: '\r', + inConstruct: [ + 'codeFencedLangGraveAccent', + 'codeFencedLangTilde', + 'codeFencedMetaGraveAccent', + 'codeFencedMetaTilde', + 'destinationLiteral', + 'headingAtx' + ] + }, + { + character: '\n', + inConstruct: [ + 'codeFencedLangGraveAccent', + 'codeFencedLangTilde', + 'codeFencedMetaGraveAccent', + 'codeFencedMetaTilde', + 'destinationLiteral', + 'headingAtx' + ] + }, + {character: ' ', after: '[\\r\\n]', inConstruct: 'phrasing'}, + {character: ' ', before: '[\\r\\n]', inConstruct: 'phrasing'}, + { + character: ' ', + inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] + }, + // An exclamation mark can start an image, if it is followed by a link or + // a link reference. + {character: '!', after: '\\[', inConstruct: 'phrasing'}, + // A quote can break out of a title. + {character: '"', inConstruct: 'titleQuote'}, + // A number sign could start an ATX heading if it starts a line. + {atBreak: true, character: '#'}, + {character: '#', inConstruct: 'headingAtx', after: '(?:[\r\n]|$)'}, + // Dollar sign and percentage are not used in markdown. + // An ampersand could start a character reference. + {character: '&', after: '[#A-Za-z]', inConstruct: 'phrasing'}, + // An apostrophe can break out of a title. + {character: "'", inConstruct: 'titleApostrophe'}, + // A left paren could break out of a destination raw. + {character: '(', inConstruct: 'destinationRaw'}, + {before: '\\]', character: '(', inConstruct: 'phrasing'}, + // A right paren could start a list item or break out of a destination + // raw. + {atBreak: true, before: '\\d+', character: ')'}, + {character: ')', inConstruct: 'destinationRaw'}, + // An asterisk can start thematic breaks, list items, emphasis, strong. + {atBreak: true, character: '*'}, + {character: '*', inConstruct: 'phrasing'}, + // A plus sign could start a list item. + {atBreak: true, character: '+'}, + // A dash can start thematic breaks, list items, and setext heading + // underlines. + {atBreak: true, character: '-'}, + // A dot could start a list item. + {atBreak: true, before: '\\d+', character: '.', after: '(?:[ \t\r\n]|$)'}, + // Slash, colon, and semicolon are not used in markdown for constructs. + // A less than can start html (flow or text) or an autolink. + // HTML could start with an exclamation mark (declaration, cdata, comment), + // slash (closing tag), question mark (instruction), or a letter (tag). + // An autolink also starts with a letter. + // Finally, it could break out of a destination literal. + {atBreak: true, character: '<', after: '[!/?A-Za-z]'}, + {character: '<', after: '[!/?A-Za-z]', inConstruct: 'phrasing'}, + {character: '<', inConstruct: 'destinationLiteral'}, + // An equals to can start setext heading underlines. + {atBreak: true, character: '='}, + // A greater than can start block quotes and it can break out of a + // destination literal. + {atBreak: true, character: '>'}, + {character: '>', inConstruct: 'destinationLiteral'}, + // Question mark and at sign are not used in markdown for constructs. + // A left bracket can start definitions, references, labels, + {atBreak: true, character: '['}, + {character: '[', inConstruct: ['phrasing', 'label', 'reference']}, + // A backslash can start an escape (when followed by punctuation) or a + // hard break (when followed by an eol). + // Note: typical escapes are handled in `safe`! + {character: '\\', after: '[\\r\\n]', inConstruct: 'phrasing'}, + // A right bracket can exit labels. + {character: ']', inConstruct: ['label', 'reference']}, + // Caret is not used in markdown for constructs. + // An underscore can start emphasis, strong, or a thematic break. + {atBreak: true, character: '_'}, + {character: '_', inConstruct: 'phrasing'}, + // A grave accent can start code (fenced or text), or it can break out of + // a grave accent code fence. + {atBreak: true, character: '`'}, + { + character: '`', + inConstruct: [ + 'codeFencedLangGraveAccent', + 'codeFencedMetaGraveAccent', + 'phrasing' + ] + }, + // Left brace, vertical bar, right brace are not used in markdown for + // constructs. + // A tilde can start code (fenced). + {atBreak: true, character: '~'} +]; + +/** + * @typedef {import('./types.js').Node} Node + * @typedef {import('./types.js').Options} Options + * @typedef {import('./types.js').Context} Context + * @typedef {import('./types.js').Handle} Handle + * @typedef {import('./types.js').Join} Join + * @typedef {import('./types.js').Unsafe} Unsafe + */ + +/** + * @param {Node} tree + * @param {Options} [options] + * @returns {string} + */ +function toMarkdown(tree, options = {}) { + /** @type {Context} */ + // @ts-expect-error: we’ll add `handle` later. + const context = { + enter, + stack: [], + unsafe: [], + join: [], + handlers: {}, + options: {}, + indexStack: [] + }; + + configure(context, {unsafe, join, handlers: handle}); + configure(context, options); + + if (context.options.tightDefinitions) { + configure(context, {join: [joinDefinition]}); + } + + /** @type {Handle} */ + context.handle = zwitch('type', { + invalid, + // @ts-expect-error: hush. + unknown, + // @ts-expect-error: hush. + handlers: context.handlers + }); + + let result = context.handle(tree, null, context, {before: '\n', after: '\n'}); + + if ( + result && + result.charCodeAt(result.length - 1) !== 10 && + result.charCodeAt(result.length - 1) !== 13 + ) { + result += '\n'; + } + + return result + + /** @type {Context['enter']} */ + function enter(name) { + context.stack.push(name); + return exit + + function exit() { + context.stack.pop(); + } + } +} + +/** + * @type {Handle} + * @param {unknown} value + */ +function invalid(value) { + throw new Error('Cannot handle value `' + value + '`, expected node') +} + +/** + * @type {Handle} + * @param {Node} node + */ +function unknown(node) { + throw new Error('Cannot handle unknown node `' + node.type + '`') +} + +/** @type {Join} */ +function joinDefinition(left, right) { + // No blank line between adjacent definitions. + if (left.type === 'definition' && left.type === right.type) { + return 0 + } +} + +/** + * @typedef {import('mdast').Root|import('mdast').Content} Node + * @typedef {import('mdast-util-to-markdown').Options} Options + */ + +/** @type {import('unified').Plugin<[Options]|void[], Node, string>} */ +function remarkStringify(options) { + /** @type {import('unified').CompilerFunction} */ + const compiler = (tree) => { + // Assume options. + const settings = /** @type {Options} */ (this.data('settings')); + + return toMarkdown( + tree, + Object.assign({}, settings, options, { + // Note: this option is not in the readme. + // The goal is for it to be set by plugins on `data` instead of being + // passed by users. + extensions: this.data('toMarkdownExtensions') || [] + }) + ) + }; + + Object.assign(this, {Compiler: compiler}); +} + +/** + * @typedef {import('unist').Point} Point + * @typedef {import('vfile').VFile} VFile + * + * @typedef {Pick} PositionalPoint + * @typedef {Required} FullPoint + * @typedef {NonNullable} Offset + */ + +/** + * Get transform functions for the given `document`. + * + * @param {string|Uint8Array|VFile} file + */ +function location(file) { + var value = String(file); + /** @type {Array.} */ + var indices = []; + var search = /\r?\n|\r/g; + + while (search.test(value)) { + indices.push(search.lastIndex); + } + + indices.push(value.length + 1); + + return {toPoint, toOffset} + + /** + * Get the line and column-based `point` for `offset` in the bound indices. + * Returns a point with `undefined` values when given invalid or out of bounds + * input. + * + * @param {Offset} offset + * @returns {FullPoint} + */ + function toPoint(offset) { + var index = -1; + + if (offset > -1 && offset < indices[indices.length - 1]) { + while (++index < indices.length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset + } + } + } + } + + return {line: undefined, column: undefined, offset: undefined} + } + + /** + * Get the `offset` for a line and column-based `point` in the bound indices. + * Returns `-1` when given invalid or out of bounds input. + * + * @param {PositionalPoint} point + * @returns {Offset} + */ + function toOffset(point) { + var line = point && point.line; + var column = point && point.column; + /** @type {number} */ + var offset; + + if ( + typeof line === 'number' && + typeof column === 'number' && + !Number.isNaN(line) && + !Number.isNaN(column) && + line - 1 in indices + ) { + offset = (indices[line - 2] || 0) + column - 1 || 0; + } + + return offset > -1 && offset < indices[indices.length - 1] ? offset : -1 + } +} + +/** + * @param {string} d + * @returns {string} + */ +function color(d) { + return '\u001B[33m' + d + '\u001B[39m' +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + */ + +/** + * Continue traversing as normal + */ +const CONTINUE = true; +/** + * Do not traverse this node’s children + */ +const SKIP = 'skip'; +/** + * Stop traversing immediately + */ +const EXIT = false; + +const visitParents = + /** + * @type {( + * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * Visit children of tree which pass a test + * + * @param {Node} tree Abstract syntax tree to walk + * @param {Test} test test Test node + * @param {Visitor} visitor Function to run for each node + * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + // @ts-ignore no visitor given, so `visitor` is test. + visitor = test; + test = null; + } + + var is = convert(test); + var step = reverse ? -1 : 1; + + factory(tree, null, [])(); + + /** + * @param {Node} node + * @param {number?} index + * @param {Array.} parents + */ + function factory(node, index, parents) { + /** @type {Object.} */ + var value = typeof node === 'object' && node !== null ? node : {}; + /** @type {string} */ + var name; + + if (typeof value.type === 'string') { + name = + typeof value.tagName === 'string' + ? value.tagName + : typeof value.name === 'string' + ? value.name + : undefined; + + Object.defineProperty(visit, 'name', { + value: + 'node (' + + color(value.type + (name ? '<' + name + '>' : '')) + + ')' + }); + } + + return visit + + function visit() { + /** @type {ActionTuple} */ + var result = []; + /** @type {ActionTuple} */ + var subresult; + /** @type {number} */ + var offset; + /** @type {Array.} */ + var grandparents; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult(visitor(node, parents)); + + if (result[0] === EXIT) { + return result + } + } + + if (node.children && result[0] !== SKIP) { + // @ts-ignore looks like a parent. + offset = (reverse ? node.children.length : -1) + step; + // @ts-ignore looks like a parent. + grandparents = parents.concat(node); + + // @ts-ignore looks like a parent. + while (offset > -1 && offset < node.children.length) { + subresult = factory(node.children[offset], offset, grandparents)(); + + if (subresult[0] === EXIT) { + return subresult + } + + offset = + typeof subresult[1] === 'number' ? subresult[1] : offset + step; + } + } + + return result + } + } + } + ); + +/** + * @param {VisitorResult} value + * @returns {ActionTuple} + */ +function toResult(value) { + if (Array.isArray(value)) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE, value] + } + + return [value] +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult + */ + +const visit = + /** + * @type {( + * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & + * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) + * )} + */ + ( + /** + * Visit children of tree which pass a test + * + * @param {Node} tree Abstract syntax tree to walk + * @param {Test} test test Test node + * @param {Visitor} visitor Function to run for each node + * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false + */ + function (tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + visitParents(tree, test, overload, reverse); + + /** + * @param {Node} node + * @param {Array.} parents + */ + function overload(node, parents) { + var parent = parents[parents.length - 1]; + return visitor( + node, + parent ? parent.children.indexOf(node) : null, + parent + ) + } + } + ); + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('unist').Parent} Parent + * @typedef {import('unist').Point} Point + * @typedef {import('unist-util-is').Test} Test + * @typedef {import('vfile').VFile} VFile + * @typedef {import('vfile-message').VFileMessage} VFileMessage + * + * @typedef {OptionsWithoutReset|OptionsWithReset} Options + * @typedef {OptionsBaseFields & OptionsWithoutResetFields} OptionsWithoutReset + * @typedef {OptionsBaseFields & OptionsWithResetFields} OptionsWithReset + * + * @typedef OptionsWithoutResetFields + * @property {false} [reset] + * Whether to treat all messages as turned off initially. + * @property {string[]} [disable] + * List of `ruleId`s to turn off. + * + * @typedef OptionsWithResetFields + * @property {true} reset + * Whether to treat all messages as turned off initially. + * @property {string[]} [enable] + * List of `ruleId`s to initially turn on. + * + * @typedef OptionsBaseFields + * @property {string} name + * Name of markers that can control the message sources. + * + * For example, `{name: 'alpha'}` controls `alpha` markers: + * + * ```html + * + * ``` + * @property {MarkerParser} marker + * Parse a possible marker to a comment marker object (Marker). + * If the marker isn't a marker, should return `null`. + * @property {Test} [test] + * Test for possible markers + * @property {string[]} [known] + * List of allowed `ruleId`s. When given a warning is shown + * when someone tries to control an unknown rule. + * + * For example, `{name: 'alpha', known: ['bravo']}` results in a warning if + * `charlie` is configured: + * + * ```html + * + * ``` + * @property {string|string[]} [source] + * Sources that can be controlled with `name` markers. + * Defaults to `name`. + * + * @callback MarkerParser + * Parse a possible comment marker node to a Marker. + * @param {Node} node + * Node to parse + * + * @typedef Marker + * A comment marker. + * @property {string} name + * Name of marker. + * @property {string} attributes + * Value after name. + * @property {Record} parameters + * Parsed attributes. + * @property {Node} node + * Reference to given node. + * + * @typedef Mark + * @property {Point|undefined} point + * @property {boolean} state + */ + +const own$3 = {}.hasOwnProperty; + +/** + * @type {import('unified').Plugin<[Options]>} + * @returns {(tree: Node, file: VFile) => void} + */ +function messageControl(options) { + if (!options || typeof options !== 'object' || !options.name) { + throw new Error( + 'Expected `name` in `options`, got `' + (options || {}).name + '`' + ) + } + + if (!options.marker) { + throw new Error( + 'Expected `marker` in `options`, got `' + options.marker + '`' + ) + } + + const enable = 'enable' in options && options.enable ? options.enable : []; + const disable = 'disable' in options && options.disable ? options.disable : []; + let reset = options.reset; + const sources = + typeof options.source === 'string' + ? [options.source] + : options.source || [options.name]; + + return transformer + + /** + * @param {Node} tree + * @param {VFile} file + */ + function transformer(tree, file) { + const toOffset = location(file).toOffset; + const initial = !reset; + const gaps = detectGaps(tree, file); + /** @type {Record} */ + const scope = {}; + /** @type {Mark[]} */ + const globals = []; + + visit(tree, options.test, visitor); + + file.messages = file.messages.filter((m) => filter(m)); + + /** + * @param {Node} node + * @param {number|null} position + * @param {Parent|null} parent + */ + function visitor(node, position, parent) { + /** @type {Marker|null} */ + const mark = options.marker(node); + + if (!mark || mark.name !== options.name) { + return + } + + const ruleIds = mark.attributes.split(/\s/g); + const point = mark.node.position && mark.node.position.start; + const next = + (parent && position !== null && parent.children[position + 1]) || + undefined; + const tail = (next && next.position && next.position.end) || undefined; + let index = -1; + + /** @type {string} */ + // @ts-expect-error: we’ll check for unknown values next. + const verb = ruleIds.shift(); + + if (verb !== 'enable' && verb !== 'disable' && verb !== 'ignore') { + file.fail( + 'Unknown keyword `' + + verb + + '`: expected ' + + "`'enable'`, `'disable'`, or `'ignore'`", + mark.node + ); + } + + // Apply to all rules. + if (ruleIds.length > 0) { + while (++index < ruleIds.length) { + const ruleId = ruleIds[index]; + + if (isKnown(ruleId, verb, mark.node)) { + toggle(point, verb === 'enable', ruleId); + + if (verb === 'ignore') { + toggle(tail, true, ruleId); + } + } + } + } else if (verb === 'ignore') { + toggle(point, false); + toggle(tail, true); + } else { + toggle(point, verb === 'enable'); + reset = verb !== 'enable'; + } + } + + /** + * @param {VFileMessage} message + * @returns {boolean} + */ + function filter(message) { + let gapIndex = gaps.length; + + // Keep messages from a different source. + if (!message.source || !sources.includes(message.source)) { + return true + } + + // We only ignore messages if they‘re disabled, *not* when they’re not in + // the document. + if (!message.line) { + message.line = 1; + } + + if (!message.column) { + message.column = 1; + } + + // Check whether the warning is inside a gap. + // @ts-expect-error: we just normalized `null` to `number`s. + const offset = toOffset(message); + + while (gapIndex--) { + if (gaps[gapIndex][0] <= offset && gaps[gapIndex][1] > offset) { + return false + } + } + + // Check whether allowed by specific and global states. + return ( + (!message.ruleId || + check(message, scope[message.ruleId], message.ruleId)) && + check(message, globals) + ) + } + + /** + * Helper to check (and possibly warn) if a `ruleId` is unknown. + * + * @param {string} ruleId + * @param {string} verb + * @param {Node} node + * @returns {boolean} + */ + function isKnown(ruleId, verb, node) { + const result = options.known ? options.known.includes(ruleId) : true; + + if (!result) { + file.message( + 'Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", + node + ); + } + + return result + } + + /** + * Get the latest state of a rule. + * When without `ruleId`, gets global state. + * + * @param {string|undefined} ruleId + * @returns {boolean} + */ + function getState(ruleId) { + const ranges = ruleId ? scope[ruleId] : globals; + + if (ranges && ranges.length > 0) { + return ranges[ranges.length - 1].state + } + + if (!ruleId) { + return !reset + } + + return reset ? enable.includes(ruleId) : !disable.includes(ruleId) + } + + /** + * Handle a rule. + * + * @param {Point|undefined} point + * @param {boolean} state + * @param {string|undefined} [ruleId] + * @returns {void} + */ + function toggle(point, state, ruleId) { + let markers = ruleId ? scope[ruleId] : globals; + + if (!markers) { + markers = []; + scope[String(ruleId)] = markers; + } + + const previousState = getState(ruleId); + + if (state !== previousState) { + markers.push({state, point}); + } + + // Toggle all known rules. + if (!ruleId) { + for (ruleId in scope) { + if (own$3.call(scope, ruleId)) { + toggle(point, state, ruleId); + } + } + } + } + + /** + * Check all `ranges` for `message`. + * + * @param {VFileMessage} message + * @param {Mark[]|undefined} ranges + * @param {string|undefined} [ruleId] + * @returns {boolean} + */ + function check(message, ranges, ruleId) { + if (ranges && ranges.length > 0) { + // Check the state at the message’s position. + let index = ranges.length; + + while (index--) { + const range = ranges[index]; + + if ( + message.line && + message.column && + range.point && + range.point.line && + range.point.column && + (range.point.line < message.line || + (range.point.line === message.line && + range.point.column <= message.column)) + ) { + return range.state === true + } + } + } + + // The first marker ocurred after the first message, so we check the + // initial state. + if (!ruleId) { + return Boolean(initial || reset) + } + + return reset ? enable.includes(ruleId) : !disable.includes(ruleId) + } + } +} + +/** + * Detect gaps in `tree`. + * + * @param {Node} tree + * @param {VFile} file + */ +function detectGaps(tree, file) { + /** @type {Node[]} */ + // @ts-expect-error: fine. + const children = tree.children || []; + const lastNode = children[children.length - 1]; + /** @type {[number, number][]} */ + const gaps = []; + let offset = 0; + /** @type {boolean|undefined} */ + let gap; + + // Find all gaps. + visit(tree, one); + + // Get the end of the document. + // This detects if the last node was the last node. + // If not, there’s an extra gap between the last node and the end of the + // document. + if ( + lastNode && + lastNode.position && + lastNode.position.end && + offset === lastNode.position.end.offset && + file.toString().slice(offset).trim() !== '' + ) { + update(); + + update( + tree && + tree.position && + tree.position.end && + tree.position.end.offset && + tree.position.end.offset - 1 + ); + } + + return gaps + + /** + * @param {Node} node + */ + function one(node) { + update(node.position && node.position.start && node.position.start.offset); + + if (!('children' in node)) { + update(node.position && node.position.end && node.position.end.offset); + } + } + + /** + * Detect a new position. + * + * @param {number|undefined} [latest] + * @returns {void} + */ + function update(latest) { + if (latest === null || latest === undefined) { + gap = true; + } else if (offset < latest) { + if (gap) { + gaps.push([offset, latest]); + gap = undefined; + } + + offset = latest; + } + } +} + +/** + * @typedef {string|number|boolean} MarkerParameterValue + * @typedef {Object.} MarkerParameters + * + * @typedef HtmlNode + * @property {'html'} type + * @property {string} value + * + * @typedef CommentNode + * @property {'comment'} type + * @property {string} value + * + * @typedef Marker + * @property {string} name + * @property {string} attributes + * @property {MarkerParameters|null} parameters + * @property {HtmlNode|CommentNode} node + */ + +var commentExpression = /\s*([a-zA-Z\d-]+)(\s+([\s\S]*))?\s*/; + +var markerExpression = new RegExp( + '(\\s*\\s*)' +); + +/** + * Parse a comment marker. + * @param {unknown} node + * @returns {Marker|null} + */ +function commentMarker(node) { + /** @type {RegExpMatchArray} */ + var match; + /** @type {number} */ + var offset; + /** @type {MarkerParameters} */ + var parameters; + + if ( + node && + typeof node === 'object' && + // @ts-ignore hush + (node.type === 'html' || node.type === 'comment') + ) { + // @ts-ignore hush + match = node.value.match( + // @ts-ignore hush + node.type === 'comment' ? commentExpression : markerExpression + ); + + // @ts-ignore hush + if (match && match[0].length === node.value.length) { + // @ts-ignore hush + offset = node.type === 'comment' ? 1 : 2; + parameters = parseParameters(match[offset + 1] || ''); + + if (parameters) { + return { + name: match[offset], + attributes: match[offset + 2] || '', + parameters, + // @ts-ignore hush + node + } + } + } + } + + return null +} + +/** + * Parse `value` into an object. + * + * @param {string} value + * @returns {MarkerParameters|null} + */ +function parseParameters(value) { + /** @type {MarkerParameters} */ + var parameters = {}; + + return value + .replace( + /\s+([-\w]+)(?:=(?:"((?:\\[\s\S]|[^"])+)"|'((?:\\[\s\S]|[^'])+)'|((?:\\[\s\S]|[^"'\s])+)))?/gi, + replacer + ) + .replace(/\s+/g, '') + ? null + : parameters + + /** + * @param {string} _ + * @param {string} $1 + * @param {string} $2 + * @param {string} $3 + * @param {string} $4 + */ + // eslint-disable-next-line max-params + function replacer(_, $1, $2, $3, $4) { + /** @type {MarkerParameterValue} */ + var value = $2 || $3 || $4 || ''; + + if (value === 'true' || value === '') { + value = true; + } else if (value === 'false') { + value = false; + } else if (!Number.isNaN(Number(value))) { + value = Number(value); + } + + parameters[$1] = value; + + return '' + } +} + +/** + * @typedef {import('mdast').Root} Root + * @typedef {import('vfile').VFile} VFile + * @typedef {import('unified-message-control')} MessageControl + * @typedef {Omit|Omit} Options + */ + +const test = [ + 'html', // Comments are `html` nodes in mdast. + 'comment' // In MDX, comments have their own node. +]; + +/** + * Plugin to enable, disable, and ignore messages. + * + * @type {import('unified').Plugin<[Options], Root>} + * @returns {(node: Root, file: VFile) => void} + */ +function remarkMessageControl(options) { + return messageControl( + Object.assign({marker: commentMarker, test}, options) + ) +} + +/** + * @typedef {import('mdast').Root} Root + */ + +/** + * The core plugin for `remark-lint`. + * This adds support for ignoring stuff from messages (``). + * All rules are in their own packages and presets. + * + * @type {import('unified').Plugin} + */ +function remarkLint() { + this.use(lintMessageControl); +} + +/** @type {import('unified').Plugin} */ +function lintMessageControl() { + return remarkMessageControl({name: 'lint', source: 'remark-lint'}) +} + +/** + * @typedef {import('unist').Node} Node + * @typedef {import('vfile').VFile} VFile + * + * @typedef {0|1|2} Severity + * @typedef {'warn'|'on'|'off'|'error'} Label + * @typedef {[Severity, ...unknown[]]} SeverityTuple + * + * @typedef RuleMeta + * @property {string} origin name of the lint rule + * @property {string} [url] link to documentation + * + * @callback Rule + * @param {Node} tree + * @param {VFile} file + * @param {unknown} options + * @returns {void} + */ + +const primitives = new Set(['string', 'number', 'boolean']); + +/** + * @param {string|RuleMeta} meta + * @param {Rule} rule + */ +function lintRule(meta, rule) { + const id = typeof meta === 'string' ? meta : meta.origin; + const url = typeof meta === 'string' ? undefined : meta.url; + const parts = id.split(':'); + // Possibly useful if externalised later. + /* c8 ignore next */ + const source = parts[1] ? parts[0] : undefined; + const ruleId = parts[1]; + + Object.defineProperty(plugin, 'name', {value: id}); + + return plugin + + /** @type {import('unified').Plugin<[unknown]|void[]>} */ + function plugin(raw) { + const [severity, options] = coerce$1(ruleId, raw); + + if (!severity) return + + const fatal = severity === 2; + + return (tree, file, next) => { + let index = file.messages.length - 1; + + wrap(rule, (error) => { + const messages = file.messages; + + // Add the error, if not already properly added. + // Only happens for incorrect plugins. + /* c8 ignore next 6 */ + // @ts-expect-error: errors could be `messages`. + if (error && !messages.includes(error)) { + try { + file.fail(error); + } catch {} + } + + while (++index < messages.length) { + Object.assign(messages[index], {ruleId, source, fatal, url}); + } + + next(); + })(tree, file, options); + } + } +} + +/** + * Coerce a value to a severity--options tuple. + * + * @param {string} name + * @param {unknown} value + * @returns {SeverityTuple} + */ +function coerce$1(name, value) { + /** @type {unknown[]} */ + let result; + + if (typeof value === 'boolean') { + result = [value]; + } else if (value === null || value === undefined) { + result = [1]; + } else if ( + Array.isArray(value) && + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + primitives.has(typeof value[0]) + ) { + // `isArray(unknown)` is turned into `any[]`: + // type-coverage:ignore-next-line + result = [...value]; + } else { + result = [1, value]; + } + + let level = result[0]; + + if (typeof level === 'boolean') { + level = level ? 1 : 0; + } else if (typeof level === 'string') { + if (level === 'off') { + level = 0; + } else if (level === 'on' || level === 'warn') { + level = 1; + } else if (level === 'error') { + level = 2; + } else { + level = 1; + result = [level, result]; + } + } + + if (typeof level !== 'number' || level < 0 || level > 2) { + throw new Error( + 'Incorrect severity `' + + level + + '` for `' + + name + + '`, ' + + 'expected 0, 1, or 2' + ) + } + + result[0] = level; + + // @ts-expect-error: it’s now a valid tuple. + return result +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module final-newline + * @fileoverview + * Warn when a line feed at the end of a file is missing. + * Empty files are allowed. + * + * See [StackExchange](https://unix.stackexchange.com/questions/18743) for why. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * always adds a final line feed to files. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * ## Example + * + * ##### `ok.md` + * + * ###### In + * + * Note: `␊` represents LF. + * + * ```markdown + * Alpha␊ + * ``` + * + * ###### Out + * + * No messages. + * + * ##### `not-ok.md` + * + * ###### In + * + * Note: The below file does not have a final newline. + * + * ```markdown + * Bravo + * ``` + * + * ###### Out + * + * ```text + * 1:1: Missing newline character at end of file + * ``` + */ + +const remarkLintFinalNewline = lintRule( + { + origin: 'remark-lint:final-newline', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-final-newline#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (_, file) => { + const value = String(file); + const last = value.length - 1; + + if (last > -1 && value.charAt(last) !== '\n') { + file.message('Missing newline character at end of file'); + } + } +); + +var remarkLintFinalNewline$1 = remarkLintFinalNewline; + +var pluralize = {exports: {}}; + +/* global define */ + +(function (module, exports) { +(function (root, pluralize) { + /* istanbul ignore else */ + if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { + // Node. + module.exports = pluralize(); + } else { + // Browser global. + root.pluralize = pluralize(); + } +})(commonjsGlobal, function () { + // Rule storage - pluralize and singularize need to be run sequentially, + // while other rules can be optimized using an object for instant lookups. + var pluralRules = []; + var singularRules = []; + var uncountables = {}; + var irregularPlurals = {}; + var irregularSingles = {}; + + /** + * Sanitize a pluralization rule to a usable regular expression. + * + * @param {(RegExp|string)} rule + * @return {RegExp} + */ + function sanitizeRule (rule) { + if (typeof rule === 'string') { + return new RegExp('^' + rule + '$', 'i'); + } + + return rule; + } + + /** + * Pass in a word token to produce a function that can replicate the case on + * another word. + * + * @param {string} word + * @param {string} token + * @return {Function} + */ + function restoreCase (word, token) { + // Tokens are an exact match. + if (word === token) return token; + + // Lower cased words. E.g. "hello". + if (word === word.toLowerCase()) return token.toLowerCase(); + + // Upper cased words. E.g. "WHISKY". + if (word === word.toUpperCase()) return token.toUpperCase(); + + // Title cased words. E.g. "Title". + if (word[0] === word[0].toUpperCase()) { + return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase(); + } + + // Lower cased words. E.g. "test". + return token.toLowerCase(); + } + + /** + * Interpolate a regexp string. + * + * @param {string} str + * @param {Array} args + * @return {string} + */ + function interpolate (str, args) { + return str.replace(/\$(\d{1,2})/g, function (match, index) { + return args[index] || ''; + }); + } + + /** + * Replace a word using a rule. + * + * @param {string} word + * @param {Array} rule + * @return {string} + */ + function replace (word, rule) { + return word.replace(rule[0], function (match, index) { + var result = interpolate(rule[1], arguments); + + if (match === '') { + return restoreCase(word[index - 1], result); + } + + return restoreCase(match, result); + }); + } + + /** + * Sanitize a word by passing in the word and sanitization rules. + * + * @param {string} token + * @param {string} word + * @param {Array} rules + * @return {string} + */ + function sanitizeWord (token, word, rules) { + // Empty string or doesn't need fixing. + if (!token.length || uncountables.hasOwnProperty(token)) { + return word; + } + + var len = rules.length; + + // Iterate over the sanitization rules and use the first one to match. + while (len--) { + var rule = rules[len]; + + if (rule[0].test(word)) return replace(word, rule); + } + + return word; + } + + /** + * Replace a word with the updated word. + * + * @param {Object} replaceMap + * @param {Object} keepMap + * @param {Array} rules + * @return {Function} + */ + function replaceWord (replaceMap, keepMap, rules) { + return function (word) { + // Get the correct token and case restoration functions. + var token = word.toLowerCase(); + + // Check against the keep object map. + if (keepMap.hasOwnProperty(token)) { + return restoreCase(word, token); + } + + // Check against the replacement map for a direct word replacement. + if (replaceMap.hasOwnProperty(token)) { + return restoreCase(word, replaceMap[token]); + } + + // Run all the rules against the word. + return sanitizeWord(token, word, rules); + }; + } + + /** + * Check if a word is part of the map. + */ + function checkWord (replaceMap, keepMap, rules, bool) { + return function (word) { + var token = word.toLowerCase(); + + if (keepMap.hasOwnProperty(token)) return true; + if (replaceMap.hasOwnProperty(token)) return false; + + return sanitizeWord(token, token, rules) === token; + }; + } + + /** + * Pluralize or singularize a word based on the passed in count. + * + * @param {string} word The word to pluralize + * @param {number} count How many of the word exist + * @param {boolean} inclusive Whether to prefix with the number (e.g. 3 ducks) + * @return {string} + */ + function pluralize (word, count, inclusive) { + var pluralized = count === 1 + ? pluralize.singular(word) : pluralize.plural(word); + + return (inclusive ? count + ' ' : '') + pluralized; + } + + /** + * Pluralize a word. + * + * @type {Function} + */ + pluralize.plural = replaceWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Check if a word is plural. + * + * @type {Function} + */ + pluralize.isPlural = checkWord( + irregularSingles, irregularPlurals, pluralRules + ); + + /** + * Singularize a word. + * + * @type {Function} + */ + pluralize.singular = replaceWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Check if a word is singular. + * + * @type {Function} + */ + pluralize.isSingular = checkWord( + irregularPlurals, irregularSingles, singularRules + ); + + /** + * Add a pluralization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addPluralRule = function (rule, replacement) { + pluralRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add a singularization rule to the collection. + * + * @param {(string|RegExp)} rule + * @param {string} replacement + */ + pluralize.addSingularRule = function (rule, replacement) { + singularRules.push([sanitizeRule(rule), replacement]); + }; + + /** + * Add an uncountable word rule. + * + * @param {(string|RegExp)} word + */ + pluralize.addUncountableRule = function (word) { + if (typeof word === 'string') { + uncountables[word.toLowerCase()] = true; + return; + } + + // Set singular and plural references for the word. + pluralize.addPluralRule(word, '$0'); + pluralize.addSingularRule(word, '$0'); + }; + + /** + * Add an irregular word definition. + * + * @param {string} single + * @param {string} plural + */ + pluralize.addIrregularRule = function (single, plural) { + plural = plural.toLowerCase(); + single = single.toLowerCase(); + + irregularSingles[single] = plural; + irregularPlurals[plural] = single; + }; + + /** + * Irregular rules. + */ + [ + // Pronouns. + ['I', 'we'], + ['me', 'us'], + ['he', 'they'], + ['she', 'they'], + ['them', 'them'], + ['myself', 'ourselves'], + ['yourself', 'yourselves'], + ['itself', 'themselves'], + ['herself', 'themselves'], + ['himself', 'themselves'], + ['themself', 'themselves'], + ['is', 'are'], + ['was', 'were'], + ['has', 'have'], + ['this', 'these'], + ['that', 'those'], + // Words ending in with a consonant and `o`. + ['echo', 'echoes'], + ['dingo', 'dingoes'], + ['volcano', 'volcanoes'], + ['tornado', 'tornadoes'], + ['torpedo', 'torpedoes'], + // Ends with `us`. + ['genus', 'genera'], + ['viscus', 'viscera'], + // Ends with `ma`. + ['stigma', 'stigmata'], + ['stoma', 'stomata'], + ['dogma', 'dogmata'], + ['lemma', 'lemmata'], + ['schema', 'schemata'], + ['anathema', 'anathemata'], + // Other irregular rules. + ['ox', 'oxen'], + ['axe', 'axes'], + ['die', 'dice'], + ['yes', 'yeses'], + ['foot', 'feet'], + ['eave', 'eaves'], + ['goose', 'geese'], + ['tooth', 'teeth'], + ['quiz', 'quizzes'], + ['human', 'humans'], + ['proof', 'proofs'], + ['carve', 'carves'], + ['valve', 'valves'], + ['looey', 'looies'], + ['thief', 'thieves'], + ['groove', 'grooves'], + ['pickaxe', 'pickaxes'], + ['passerby', 'passersby'] + ].forEach(function (rule) { + return pluralize.addIrregularRule(rule[0], rule[1]); + }); + + /** + * Pluralization rules. + */ + [ + [/s?$/i, 's'], + [/[^\u0000-\u007F]$/i, '$0'], + [/([^aeiou]ese)$/i, '$1'], + [/(ax|test)is$/i, '$1es'], + [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'], + [/(e[mn]u)s?$/i, '$1s'], + [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'], + [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'], + [/(seraph|cherub)(?:im)?$/i, '$1im'], + [/(her|at|gr)o$/i, '$1oes'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'], + [/sis$/i, 'ses'], + [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'], + [/([^aeiouy]|qu)y$/i, '$1ies'], + [/([^ch][ieo][ln])ey$/i, '$1ies'], + [/(x|ch|ss|sh|zz)$/i, '$1es'], + [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'], + [/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'], + [/(pe)(?:rson|ople)$/i, '$1ople'], + [/(child)(?:ren)?$/i, '$1ren'], + [/eaux$/i, '$0'], + [/m[ae]n$/i, 'men'], + ['thou', 'you'] + ].forEach(function (rule) { + return pluralize.addPluralRule(rule[0], rule[1]); + }); + + /** + * Singularization rules. + */ + [ + [/s$/i, ''], + [/(ss)$/i, '$1'], + [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'], + [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'], + [/ies$/i, 'y'], + [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'], + [/\b(mon|smil)ies$/i, '$1ey'], + [/\b((?:tit)?m|l)ice$/i, '$1ouse'], + [/(seraph|cherub)im$/i, '$1'], + [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'], + [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'], + [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'], + [/(test)(?:is|es)$/i, '$1is'], + [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'], + [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'], + [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'], + [/(alumn|alg|vertebr)ae$/i, '$1a'], + [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'], + [/(matr|append)ices$/i, '$1ix'], + [/(pe)(rson|ople)$/i, '$1rson'], + [/(child)ren$/i, '$1'], + [/(eau)x?$/i, '$1'], + [/men$/i, 'man'] + ].forEach(function (rule) { + return pluralize.addSingularRule(rule[0], rule[1]); + }); + + /** + * Uncountable rules. + */ + [ + // Singular words with no plurals. + 'adulthood', + 'advice', + 'agenda', + 'aid', + 'aircraft', + 'alcohol', + 'ammo', + 'analytics', + 'anime', + 'athletics', + 'audio', + 'bison', + 'blood', + 'bream', + 'buffalo', + 'butter', + 'carp', + 'cash', + 'chassis', + 'chess', + 'clothing', + 'cod', + 'commerce', + 'cooperation', + 'corps', + 'debris', + 'diabetes', + 'digestion', + 'elk', + 'energy', + 'equipment', + 'excretion', + 'expertise', + 'firmware', + 'flounder', + 'fun', + 'gallows', + 'garbage', + 'graffiti', + 'hardware', + 'headquarters', + 'health', + 'herpes', + 'highjinks', + 'homework', + 'housework', + 'information', + 'jeans', + 'justice', + 'kudos', + 'labour', + 'literature', + 'machinery', + 'mackerel', + 'mail', + 'media', + 'mews', + 'moose', + 'music', + 'mud', + 'manga', + 'news', + 'only', + 'personnel', + 'pike', + 'plankton', + 'pliers', + 'police', + 'pollution', + 'premises', + 'rain', + 'research', + 'rice', + 'salmon', + 'scissors', + 'series', + 'sewage', + 'shambles', + 'shrimp', + 'software', + 'species', + 'staff', + 'swine', + 'tennis', + 'traffic', + 'transportation', + 'trout', + 'tuna', + 'wealth', + 'welfare', + 'whiting', + 'wildebeest', + 'wildlife', + 'you', + /pok[eé]mon$/i, + // Regexes. + /[^aeiou]ese$/i, // "chinese", "japanese" + /deer$/i, // "deer", "reindeer" + /fish$/i, // "fish", "blowfish", "angelfish" + /measles$/i, + /o[iu]s$/i, // "carnivorous" + /pox$/i, // "chickpox", "smallpox" + /sheep$/i + ].forEach(pluralize.addUncountableRule); + + return pluralize; +}); +}(pluralize)); + +var plural = pluralize.exports; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module list-item-bullet-indent + * @fileoverview + * Warn when list item bullets are indented. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * removes all indentation before bullets. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * Paragraph. + * + * * List item + * * List item + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Paragraph. + * + * ·* List item + * ·* List item + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:2: Incorrect indentation before bullet: remove 1 space + * 4:2: Incorrect indentation before bullet: remove 1 space + */ + +const remarkLintListItemBulletIndent = lintRule( + { + origin: 'remark-lint:list-item-bullet-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-list-item-bullet-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'list', (list, _, grandparent) => { + let index = -1; + + while (++index < list.children.length) { + const item = list.children[index]; + + if ( + grandparent && + grandparent.type === 'root' && + grandparent.position && + typeof grandparent.position.start.column === 'number' && + item.position && + typeof item.position.start.column === 'number' + ) { + const indent = + item.position.start.column - grandparent.position.start.column; + + if (indent) { + file.message( + 'Incorrect indentation before bullet: remove ' + + indent + + ' ' + + plural('space', indent), + item.position.start + ); + } + } + } + }); + } +); + +var remarkLintListItemBulletIndent$1 = remarkLintListItemBulletIndent; + +/** + * @typedef {import('unist').Position} Position + * @typedef {import('unist').Point} Point + * + * @typedef {Partial} PointLike + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +var pointStart = point('start'); +var pointEnd = point('end'); + +/** + * Get the positional info of `node`. + * + * @param {'start'|'end'} type + */ +function point(type) { + return point + + /** + * Get the positional info of `node`. + * + * @param {NodeLike} [node] + * @returns {Point} + */ + function point(node) { + /** @type {Point} */ + // @ts-ignore looks like a point + var point = (node && node.position && node.position[type]) || {}; + + return { + line: point.line || null, + column: point.column || null, + offset: point.offset > -1 ? point.offset : null + } + } +} + +/** + * @typedef {Object} PointLike + * @property {number} [line] + * @property {number} [column] + * @property {number} [offset] + * + * @typedef {Object} PositionLike + * @property {PointLike} [start] + * @property {PointLike} [end] + * + * @typedef {Object} NodeLike + * @property {PositionLike} [position] + */ + +/** + * Check if `node` is *generated*. + * + * @param {NodeLike} [node] + * @returns {boolean} + */ +function generated(node) { + return ( + !node || + !node.position || + !node.position.start || + !node.position.start.line || + !node.position.start.column || + !node.position.end || + !node.position.end.line || + !node.position.end.column + ) +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module list-item-indent + * @fileoverview + * Warn when the spacing between a list item’s bullet and its content violates + * a given style. + * + * Options: `'tab-size'`, `'mixed'`, or `'space'`, default: `'tab-size'`. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * uses `'tab-size'` (named `'tab'` there) by default to ensure Markdown is + * seen the same way across vendors. + * This can be configured with the + * [`listItemIndent`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionslistitemindent) + * option. + * This rule’s `'space'` option is named `'1'` there. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * *···List + * ····item. + * + * Paragraph. + * + * 11.·List + * ····item. + * + * Paragraph. + * + * *···List + * ····item. + * + * *···List + * ····item. + * + * @example + * {"name": "ok.md", "setting": "mixed"} + * + * *·List item. + * + * Paragraph. + * + * 11.·List item + * + * Paragraph. + * + * *···List + * ····item. + * + * *···List + * ····item. + * + * @example + * {"name": "ok.md", "setting": "space"} + * + * *·List item. + * + * Paragraph. + * + * 11.·List item + * + * Paragraph. + * + * *·List + * ··item. + * + * *·List + * ··item. + * + * @example + * {"name": "not-ok.md", "setting": "space", "label": "input"} + * + * *···List + * ····item. + * + * @example + * {"name": "not-ok.md", "setting": "space", "label": "output"} + * + * 1:5: Incorrect list-item indent: remove 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "tab-size", "label": "input"} + * + * *·List + * ··item. + * + * @example + * {"name": "not-ok.md", "setting": "tab-size", "label": "output"} + * + * 1:3: Incorrect list-item indent: add 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "mixed", "label": "input"} + * + * *···List item. + * + * @example + * {"name": "not-ok.md", "setting": "mixed", "label": "output"} + * + * 1:5: Incorrect list-item indent: remove 2 spaces + * + * @example + * {"name": "not-ok.md", "setting": "💩", "label": "output", "positionless": true} + * + * 1:1: Incorrect list-item indent style `💩`: use either `'tab-size'`, `'space'`, or `'mixed'` + */ + +const remarkLintListItemIndent = lintRule( + { + origin: 'remark-lint:list-item-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-list-item-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'tab-size') => { + const value = String(file); + + if (option !== 'tab-size' && option !== 'space' && option !== 'mixed') { + file.fail( + 'Incorrect list-item indent style `' + + option + + "`: use either `'tab-size'`, `'space'`, or `'mixed'`" + ); + } + + visit$1(tree, 'list', (node) => { + if (generated(node)) return + + const spread = node.spread; + let index = -1; + + while (++index < node.children.length) { + const item = node.children[index]; + const head = item.children[0]; + const final = pointStart(head); + + const marker = value + .slice(pointStart(item).offset, final.offset) + .replace(/\[[x ]?]\s*$/i, ''); + + const bulletSize = marker.replace(/\s+$/, '').length; + + const style = + option === 'tab-size' || (option === 'mixed' && spread) + ? Math.ceil(bulletSize / 4) * 4 + : bulletSize + 1; + + if (marker.length !== style) { + const diff = style - marker.length; + const abs = Math.abs(diff); + + file.message( + 'Incorrect list-item indent: ' + + (diff > 0 ? 'add' : 'remove') + + ' ' + + abs + + ' ' + + plural('space', abs), + final + ); + } + } + }); + } +); + +var remarkLintListItemIndent$1 = remarkLintListItemIndent; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-auto-link-without-protocol + * @fileoverview + * Warn for autolinks without protocol. + * Autolinks are URLs enclosed in `<` (less than) and `>` (greater than) + * characters. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * adds a protocol where needed. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * + * + * + * Most Markdown vendors don’t recognize the following as a link: + * + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:14: All automatic links must start with a protocol + */ + +// Protocol expression. +// See: . +const protocol = /^[a-z][a-z+.-]+:\/?/i; + +const remarkLintNoAutoLinkWithoutProtocol = lintRule( + { + origin: 'remark-lint:no-auto-link-without-protocol', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-auto-link-without-protocol#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'link', (node) => { + if ( + !generated(node) && + pointStart(node).column === pointStart(node.children[0]).column - 1 && + pointEnd(node).column === + pointEnd(node.children[node.children.length - 1]).column + 1 && + !protocol.test(toString(node)) + ) { + file.message('All automatic links must start with a protocol', node); + } + }); + } +); + +var remarkLintNoAutoLinkWithoutProtocol$1 = remarkLintNoAutoLinkWithoutProtocol; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-blockquote-without-marker + * @fileoverview + * Warn when blank lines without `>` (greater than) markers are found in a + * block quote. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * adds markers to every line in a block quote. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * > Foo… + * > …bar… + * > …baz. + * + * @example + * {"name": "ok-tabs.md"} + * + * >»Foo… + * >»…bar… + * >»…baz. + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * > Foo… + * …bar… + * > …baz. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 2:1: Missing marker in block quote + * + * @example + * {"name": "not-ok-tabs.md", "label": "input"} + * + * >»Foo… + * »…bar… + * …baz. + * + * @example + * {"name": "not-ok-tabs.md", "label": "output"} + * + * 2:1: Missing marker in block quote + * 3:1: Missing marker in block quote + */ + +const remarkLintNoBlockquoteWithoutMarker = lintRule( + { + origin: 'remark-lint:no-blockquote-without-marker', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-blockquote-without-marker#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + const loc = location(file); + + visit$1(tree, 'blockquote', (node) => { + let index = -1; + + while (++index < node.children.length) { + const child = node.children[index]; + + if (child.type === 'paragraph' && !generated(child)) { + const end = pointEnd(child).line; + const column = pointStart(child).column; + let line = pointStart(child).line; + + // Skip past the first line. + while (++line <= end) { + const offset = loc.toOffset({line, column}); + + if (/>[\t ]+$/.test(value.slice(offset - 5, offset))) { + continue + } + + // Roughly here. + file.message('Missing marker in block quote', { + line, + column: column - 2 + }); + } + } + } + }); + } +); + +var remarkLintNoBlockquoteWithoutMarker$1 = remarkLintNoBlockquoteWithoutMarker; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-literal-urls + * @fileoverview + * Warn for literal URLs in text. + * URLs are treated as links in some Markdown vendors, but not in others. + * To make sure they are always linked, wrap them in `<` (less than) and `>` + * (greater than). + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * never creates literal URLs and always uses `<` (less than) and `>` + * (greater than). + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * http://foo.bar/baz + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 1:1-1:19: Don’t use literal URLs without angle brackets + */ + +const remarkLintNoLiteralUrls = lintRule( + { + origin: 'remark-lint:no-literal-urls', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-literal-urls#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'link', (node) => { + const value = toString(node); + + if ( + !generated(node) && + pointStart(node).column === pointStart(node.children[0]).column && + pointEnd(node).column === + pointEnd(node.children[node.children.length - 1]).column && + (node.url === 'mailto:' + value || node.url === value) + ) { + file.message('Don’t use literal URLs without angle brackets', node); + } + }); + } +); + +var remarkLintNoLiteralUrls$1 = remarkLintNoLiteralUrls; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module ordered-list-marker-style + * @fileoverview + * Warn when the list item marker style of ordered lists violate a given style. + * + * Options: `'consistent'`, `'.'`, or `')'`, default: `'consistent'`. + * + * `'consistent'` detects the first used list style and warns when subsequent + * lists use different styles. + * + * @example + * {"name": "ok.md"} + * + * 1. Foo + * + * + * 1. Bar + * + * Unordered lists are not affected by this rule. + * + * * Foo + * + * @example + * {"name": "ok.md", "setting": "."} + * + * 1. Foo + * + * 2. Bar + * + * @example + * {"name": "ok.md", "setting": ")"} + * + * 1) Foo + * + * 2) Bar + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * 1. Foo + * + * 2) Bar + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:1-3:8: Marker style should be `.` + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect ordered list item marker style `💩`: use either `'.'` or `')'` + */ + +const remarkLintOrderedListMarkerStyle = lintRule( + { + origin: 'remark-lint:ordered-list-marker-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-ordered-list-marker-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && option !== '.' && option !== ')') { + file.fail( + 'Incorrect ordered list item marker style `' + + option + + "`: use either `'.'` or `')'`" + ); + } + + visit$1(tree, 'list', (node) => { + let index = -1; + + if (!node.ordered) return + + while (++index < node.children.length) { + const child = node.children[index]; + + if (!generated(child)) { + const marker = /** @type {Marker} */ ( + value + .slice( + pointStart(child).offset, + pointStart(child.children[0]).offset + ) + .replace(/\s|\d/g, '') + .replace(/\[[x ]?]\s*$/i, '') + ); + + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Marker style should be `' + option + '`', child); + } + } + } + }); + } +); + +var remarkLintOrderedListMarkerStyle$1 = remarkLintOrderedListMarkerStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module hard-break-spaces + * @fileoverview + * Warn when too many spaces are used to create a hard break. + * + * @example + * {"name": "ok.md"} + * + * Lorem ipsum·· + * dolor sit amet + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Lorem ipsum··· + * dolor sit amet. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:12-2:1: Use two spaces for hard line breaks + */ + +const remarkLintHardBreakSpaces = lintRule( + { + origin: 'remark-lint:hard-break-spaces', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-hard-break-spaces#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + + visit$1(tree, 'break', (node) => { + if (!generated(node)) { + const slice = value + .slice(pointStart(node).offset, pointEnd(node).offset) + .split('\n', 1)[0] + .replace(/\r$/, ''); + + if (slice.length > 2) { + file.message('Use two spaces for hard line breaks', node); + } + } + }); + } +); + +var remarkLintHardBreakSpaces$1 = remarkLintHardBreakSpaces; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-duplicate-definitions + * @fileoverview + * Warn when duplicate definitions are found. + * + * @example + * {"name": "ok.md"} + * + * [foo]: bar + * [baz]: qux + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [foo]: bar + * [foo]: qux + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 2:1-2:11: Do not use definitions with the same identifier (1:1) + */ + +const remarkLintNoDuplicateDefinitions = lintRule( + { + origin: 'remark-lint:no-duplicate-definitions', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-duplicate-definitions#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + /** @type {Record} */ + const map = Object.create(null); + + visit$1(tree, (node) => { + if ( + (node.type === 'definition' || node.type === 'footnoteDefinition') && + !generated(node) + ) { + const identifier = node.identifier; + const duplicate = map[identifier]; + + if (duplicate) { + file.message( + 'Do not use definitions with the same identifier (' + + duplicate + + ')', + node + ); + } + + map[identifier] = stringifyPosition(pointStart(node)); + } + }); + } +); + +var remarkLintNoDuplicateDefinitions$1 = remarkLintNoDuplicateDefinitions; + +/** + * @typedef {import('mdast').Heading} Heading + * @typedef {'atx'|'atx-closed'|'setext'} Style + */ + +/** + * @param {Heading} node + * @param {Style} [relative] + * @returns {Style|null} + */ +function headingStyle(node, relative) { + var last = node.children[node.children.length - 1]; + var depth = node.depth; + var pos = node && node.position && node.position.end; + var final = last && last.position && last.position.end; + + if (!pos) { + return null + } + + // This can only occur for `'atx'` and `'atx-closed'` headings. + // This might incorrectly match `'atx'` headings with lots of trailing white + // space as an `'atx-closed'` heading. + if (!last) { + if (pos.column - 1 <= depth * 2) { + return consolidate(depth, relative) + } + + return 'atx-closed' + } + + if (final.line + 1 === pos.line) { + return 'setext' + } + + if (final.column + depth < pos.column) { + return 'atx-closed' + } + + return consolidate(depth, relative) +} + +/** + * Get the probable style of an atx-heading, depending on preferred style. + * + * @param {number} depth + * @param {Style} relative + * @returns {Style|null} + */ +function consolidate(depth, relative) { + return depth < 3 + ? 'atx' + : relative === 'atx' || relative === 'setext' + ? relative + : null +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-heading-content-indent + * @fileoverview + * Warn when content of headings is indented. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * removes all unneeded padding around content in headings. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * #·Foo + * + * ## Bar·## + * + * ##·Baz + * + * Setext headings are not affected. + * + * Baz + * === + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * #··Foo + * + * ## Bar··## + * + * ##··Baz + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:4: Remove 1 space before this heading’s content + * 3:7: Remove 1 space after this heading’s content + * 5:7: Remove 1 space before this heading’s content + * + * @example + * {"name": "empty-heading.md"} + * + * #·· + */ + +const remarkLintNoHeadingContentIndent = lintRule( + { + origin: 'remark-lint:no-heading-content-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-heading-content-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'heading', (node) => { + if (generated(node)) { + return + } + + const type = headingStyle(node, 'atx'); + + if (type === 'atx' || type === 'atx-closed') { + const head = pointStart(node.children[0]).column; + + // Ignore empty headings. + if (!head) { + return + } + + const diff = head - pointStart(node).column - 1 - node.depth; + + if (diff) { + file.message( + 'Remove ' + + Math.abs(diff) + + ' ' + + plural('space', Math.abs(diff)) + + ' before this heading’s content', + pointStart(node.children[0]) + ); + } + } + + // Closed ATX headings always must have a space between their content and + // the final hashes, thus, there is no `add x spaces`. + if (type === 'atx-closed') { + const final = pointEnd(node.children[node.children.length - 1]); + const diff = pointEnd(node).column - final.column - 1 - node.depth; + + if (diff) { + file.message( + 'Remove ' + + diff + + ' ' + + plural('space', diff) + + ' after this heading’s content', + final + ); + } + } + }); + } +); + +var remarkLintNoHeadingContentIndent$1 = remarkLintNoHeadingContentIndent; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-inline-padding + * @fileoverview + * Warn when phrasing content is padded with spaces between their markers and + * content. + * + * Warns for emphasis, strong, delete, image, and link. + * + * @example + * {"name": "ok.md"} + * + * Alpha [bravo](http://echo.fox/trot) + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Alpha [ bravo ](http://echo.fox/trot) + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:7-1:38: Don’t pad `link` with inner spaces + */ + +const remarkLintNoInlinePadding = lintRule( + { + origin: 'remark-lint:no-inline-padding', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-inline-padding#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + // Note: `emphasis`, `strong`, `delete` (GFM) can’t have padding anymore + // since CM. + visit$1(tree, (node) => { + if ( + (node.type === 'link' || node.type === 'linkReference') && + !generated(node) + ) { + const value = toString(node); + + if (value.charAt(0) === ' ' || value.charAt(value.length - 1) === ' ') { + file.message('Don’t pad `' + node.type + '` with inner spaces', node); + } + } + }); + } +); + +var remarkLintNoInlinePadding$1 = remarkLintNoInlinePadding; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-shortcut-reference-image + * @fileoverview + * Warn when shortcut reference images are used. + * + * Shortcut references render as images when a definition is found, and as + * plain text without definition. + * Sometimes, you don’t intend to create an image from the reference, but this + * rule still warns anyway. + * In that case, you can escape the reference like so: `!\[foo]`. + * + * @example + * {"name": "ok.md"} + * + * ![foo][] + * + * [foo]: http://foo.bar/baz.png + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * ![foo] + * + * [foo]: http://foo.bar/baz.png + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:7: Use the trailing [] on reference images + */ + +const remarkLintNoShortcutReferenceImage = lintRule( + { + origin: 'remark-lint:no-shortcut-reference-image', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-shortcut-reference-image#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'imageReference', (node) => { + if (!generated(node) && node.referenceType === 'shortcut') { + file.message('Use the trailing [] on reference images', node); + } + }); + } +); + +var remarkLintNoShortcutReferenceImage$1 = remarkLintNoShortcutReferenceImage; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module no-shortcut-reference-link + * @fileoverview + * Warn when shortcut reference links are used. + * + * Shortcut references render as links when a definition is found, and as + * plain text without definition. + * Sometimes, you don’t intend to create a link from the reference, but this + * rule still warns anyway. + * In that case, you can escape the reference like so: `\[foo]`. + * + * @example + * {"name": "ok.md"} + * + * [foo][] + * + * [foo]: http://foo.bar/baz + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [foo] + * + * [foo]: http://foo.bar/baz + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:6: Use the trailing `[]` on reference links + */ + +const remarkLintNoShortcutReferenceLink = lintRule( + { + origin: 'remark-lint:no-shortcut-reference-link', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-shortcut-reference-link#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + visit$1(tree, 'linkReference', (node) => { + if (!generated(node) && node.referenceType === 'shortcut') { + file.message('Use the trailing `[]` on reference links', node); + } + }); + } +); + +var remarkLintNoShortcutReferenceLink$1 = remarkLintNoShortcutReferenceLink; + +/** + * @author Titus Wormer + * @copyright 2016 Titus Wormer + * @license MIT + * @module no-undefined-references + * @fileoverview + * Warn when references to undefined definitions are found. + * + * Options: `Object`, optional. + * + * The object can have an `allow` field, set to an array of strings that may + * appear between `[` and `]`, but that should not be treated as link + * identifiers. + * + * @example + * {"name": "ok.md"} + * + * [foo][] + * + * Just a [ bracket. + * + * Typically, you’d want to use escapes (with a backslash: \\) to escape what + * could turn into a \[reference otherwise]. + * + * Just two braces can’t link: []. + * + * [foo]: https://example.com + * + * @example + * {"name": "ok-allow.md", "setting": {"allow": ["...", "…"]}} + * + * > Eliding a portion of a quoted passage […] is acceptable. + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [bar] + * + * [baz][] + * + * [text][qux] + * + * Spread [over + * lines][] + * + * > in [a + * > block quote][] + * + * [asd][a + * + * Can include [*emphasis*]. + * + * Multiple pairs: [a][b][c]. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:6: Found reference to undefined definition + * 3:1-3:8: Found reference to undefined definition + * 5:1-5:12: Found reference to undefined definition + * 7:8-8:9: Found reference to undefined definition + * 10:6-11:17: Found reference to undefined definition + * 13:1-13:6: Found reference to undefined definition + * 15:13-15:25: Found reference to undefined definition + * 17:17-17:23: Found reference to undefined definition + * 17:23-17:26: Found reference to undefined definition + */ + +const remarkLintNoUndefinedReferences = lintRule( + { + origin: 'remark-lint:no-undefined-references', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-undefined-references#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = {}) => { + const contents = String(file); + const loc = location(file); + const lineEnding = /(\r?\n|\r)[\t ]*(>[\t ]*)*/g; + const allow = new Set( + (option.allow || []).map((d) => normalizeIdentifier(d)) + ); + /** @type {Record} */ + const map = Object.create(null); + + visit$1(tree, (node) => { + if ( + (node.type === 'definition' || node.type === 'footnoteDefinition') && + !generated(node) + ) { + map[normalizeIdentifier(node.identifier)] = true; + } + }); + + visit$1(tree, (node) => { + // CM specifiers that references only form when defined. + // Still, they could be added by plugins, so let’s keep it. + /* c8 ignore next 10 */ + if ( + (node.type === 'imageReference' || + node.type === 'linkReference' || + node.type === 'footnoteReference') && + !generated(node) && + !(normalizeIdentifier(node.identifier) in map) && + !allow.has(normalizeIdentifier(node.identifier)) + ) { + file.message('Found reference to undefined definition', node); + } + + if (node.type === 'paragraph' || node.type === 'heading') { + findInPhrasing(node); + } + }); + + /** + * @param {Heading|Paragraph} node + */ + function findInPhrasing(node) { + /** @type {Range[]} */ + let ranges = []; + + visit$1(node, (child) => { + // Ignore the node itself. + if (child === node) return + + // Can’t have links in links, so reset ranges. + if (child.type === 'link' || child.type === 'linkReference') { + ranges = []; + return SKIP$1 + } + + // Enter non-text. + if (child.type !== 'text') return + + const start = pointStart(child).offset; + const end = pointEnd(child).offset; + + // Bail if there’s no positional info. + if (typeof start !== 'number' || typeof end !== 'number') { + return EXIT$1 + } + + const source = contents.slice(start, end); + /** @type {Array.<[number, string]>} */ + const lines = [[start, '']]; + let last = 0; + + lineEnding.lastIndex = 0; + let match = lineEnding.exec(source); + + while (match) { + const index = match.index; + lines[lines.length - 1][1] = source.slice(last, index); + last = index + match[0].length; + lines.push([start + last, '']); + match = lineEnding.exec(source); + } + + lines[lines.length - 1][1] = source.slice(last); + let lineIndex = -1; + + while (++lineIndex < lines.length) { + const line = lines[lineIndex][1]; + let index = 0; + + while (index < line.length) { + const code = line.charCodeAt(index); + + // Skip past escaped brackets. + if (code === 92) { + const next = line.charCodeAt(index + 1); + index++; + + if (next === 91 || next === 93) { + index++; + } + } + // Opening bracket. + else if (code === 91) { + ranges.push([lines[lineIndex][0] + index]); + index++; + } + // Close bracket. + else if (code === 93) { + // No opening. + if (ranges.length === 0) { + index++; + } else if (line.charCodeAt(index + 1) === 91) { + index++; + + // Collapsed or full. + let range = ranges.pop(); + + // Range should always exist. + // eslint-disable-next-line max-depth + if (range) { + range.push(lines[lineIndex][0] + index); + + // This is the end of a reference already. + // eslint-disable-next-line max-depth + if (range.length === 4) { + handleRange(range); + range = []; + } + + range.push(lines[lineIndex][0] + index); + ranges.push(range); + index++; + } + } else { + index++; + + // Shortcut or typical end of a reference. + const range = ranges.pop(); + + // Range should always exist. + // eslint-disable-next-line max-depth + if (range) { + range.push(lines[lineIndex][0] + index); + handleRange(range); + } + } + } + // Anything else. + else { + index++; + } + } + } + }); + + let index = -1; + + while (++index < ranges.length) { + handleRange(ranges[index]); + } + + return SKIP$1 + + /** + * @param {Range} range + */ + function handleRange(range) { + if (range.length === 1) return + if (range.length === 3) range.length = 2; + + // No need to warn for just `[]`. + if (range.length === 2 && range[0] + 2 === range[1]) return + + const offset = range.length === 4 && range[2] + 2 !== range[3] ? 2 : 0; + const id = contents + .slice(range[0 + offset] + 1, range[1 + offset] - 1) + .replace(lineEnding, ' '); + const pos = { + start: loc.toPoint(range[0]), + end: loc.toPoint(range[range.length - 1]) + }; + + if ( + !generated({position: pos}) && + !(normalizeIdentifier(id) in map) && + !allow.has(normalizeIdentifier(id)) + ) { + file.message('Found reference to undefined definition', pos); + } + } + } + } +); + +var remarkLintNoUndefinedReferences$1 = remarkLintNoUndefinedReferences; + +/** + * @author Titus Wormer + * @copyright 2016 Titus Wormer + * @license MIT + * @module no-unused-definitions + * @fileoverview + * Warn when unused definitions are found. + * + * @example + * {"name": "ok.md"} + * + * [foo][] + * + * [foo]: https://example.com + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [bar]: https://example.com + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:27: Found unused definition + */ + +const own$2 = {}.hasOwnProperty; + +const remarkLintNoUnusedDefinitions = lintRule( + { + origin: 'remark-lint:no-unused-definitions', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-no-unused-definitions#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + /** @type {Record} */ + const map = Object.create(null); + + visit$1(tree, (node) => { + if ( + (node.type === 'definition' || node.type === 'footnoteDefinition') && + !generated(node) + ) { + map[node.identifier.toUpperCase()] = {node, used: false}; + } + }); + + visit$1(tree, (node) => { + if ( + node.type === 'imageReference' || + node.type === 'linkReference' || + node.type === 'footnoteReference' + ) { + const info = map[node.identifier.toUpperCase()]; + + if (!generated(node) && info) { + info.used = true; + } + } + }); + + /** @type {string} */ + let identifier; + + for (identifier in map) { + if (own$2.call(map, identifier)) { + const entry = map[identifier]; + + if (!entry.used) { + file.message('Found unused definition', entry.node); + } + } + } + } +); + +var remarkLintNoUnusedDefinitions$1 = remarkLintNoUnusedDefinitions; + +/** + * @fileoverview + * remark preset to configure `remark-lint` with settings that prevent + * mistakes or stuff that fails across vendors. + */ + +/** @type {Preset} */ +const remarkPresetLintRecommended = { + plugins: [ + remarkLint, + // Unix compatibility. + remarkLintFinalNewline$1, + // Rendering across vendors differs greatly if using other styles. + remarkLintListItemBulletIndent$1, + [remarkLintListItemIndent$1, 'tab-size'], + // Differs or unsupported across vendors. + remarkLintNoAutoLinkWithoutProtocol$1, + remarkLintNoBlockquoteWithoutMarker$1, + remarkLintNoLiteralUrls$1, + [remarkLintOrderedListMarkerStyle$1, '.'], + // Mistakes. + remarkLintHardBreakSpaces$1, + remarkLintNoDuplicateDefinitions$1, + remarkLintNoHeadingContentIndent$1, + remarkLintNoInlinePadding$1, + remarkLintNoShortcutReferenceImage$1, + remarkLintNoShortcutReferenceLink$1, + remarkLintNoUndefinedReferences$1, + remarkLintNoUnusedDefinitions$1 + ] +}; + +var remarkPresetLintRecommended$1 = remarkPresetLintRecommended; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module blockquote-indentation + * @fileoverview + * Warn when block quotes are indented too much or too little. + * + * Options: `number` or `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used indentation and will warn when + * other block quotes use a different indentation. + * + * @example + * {"name": "ok.md", "setting": 4} + * + * > Hello + * + * Paragraph. + * + * > World + * @example + * {"name": "ok.md", "setting": 2} + * + * > Hello + * + * Paragraph. + * + * > World + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * > Hello + * + * Paragraph. + * + * > World + * + * Paragraph. + * + * > World + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 5:5: Remove 1 space between block quote and content + * 9:3: Add 1 space between block quote and content + */ + +const remarkLintBlockquoteIndentation = lintRule( + { + origin: 'remark-lint:blockquote-indentation', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-blockquote-indentation#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + visit$1(tree, 'blockquote', (node) => { + if (generated(node) || node.children.length === 0) { + return + } + + if (option === 'consistent') { + option = check$1(node); + } else { + const diff = option - check$1(node); + + if (diff !== 0) { + const abs = Math.abs(diff); + + file.message( + (diff > 0 ? 'Add' : 'Remove') + + ' ' + + abs + + ' ' + + plural('space', abs) + + ' between block quote and content', + pointStart(node.children[0]) + ); + } + } + }); + } +); + +var remarkLintBlockquoteIndentation$1 = remarkLintBlockquoteIndentation; + +/** + * @param {Blockquote} node + * @returns {number} + */ +function check$1(node) { + return pointStart(node.children[0]).column - pointStart(node).column +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module checkbox-character-style + * @fileoverview + * Warn when list item checkboxes violate a given style. + * + * Options: `Object` or `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used checked and unchecked checkbox + * styles and warns when subsequent checkboxes use different styles. + * + * Styles can also be passed in like so: + * + * ```js + * {checked: 'x', unchecked: ' '} + * ``` + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats checked checkboxes using `x` (lowercase X) and unchecked checkboxes + * as `·` (a single space). + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": {"checked": "x"}, "gfm": true} + * + * - [x] List item + * - [x] List item + * + * @example + * {"name": "ok.md", "setting": {"checked": "X"}, "gfm": true} + * + * - [X] List item + * - [X] List item + * + * @example + * {"name": "ok.md", "setting": {"unchecked": " "}, "gfm": true} + * + * - [ ] List item + * - [ ] List item + * - [ ]·· + * - [ ] + * + * @example + * {"name": "ok.md", "setting": {"unchecked": "\t"}, "gfm": true} + * + * - [»] List item + * - [»] List item + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * - [x] List item + * - [X] List item + * - [ ] List item + * - [»] List item + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 2:5: Checked checkboxes should use `x` as a marker + * 4:5: Unchecked checkboxes should use ` ` as a marker + * + * @example + * {"setting": {"unchecked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} + * + * 1:1: Incorrect unchecked checkbox marker `💩`: use either `'\t'`, or `' '` + * + * @example + * {"setting": {"checked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} + * + * 1:1: Incorrect checked checkbox marker `💩`: use either `'x'`, or `'X'` + */ + +const remarkLintCheckboxCharacterStyle = lintRule( + { + origin: 'remark-lint:checkbox-character-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-character-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + /** @type {'x'|'X'|'consistent'} */ + let checked = 'consistent'; + /** @type {' '|'\x09'|'consistent'} */ + let unchecked = 'consistent'; + + if (typeof option === 'object') { + checked = option.checked || 'consistent'; + unchecked = option.unchecked || 'consistent'; + } + + if (unchecked !== 'consistent' && unchecked !== ' ' && unchecked !== '\t') { + file.fail( + 'Incorrect unchecked checkbox marker `' + + unchecked + + "`: use either `'\\t'`, or `' '`" + ); + } + + if (checked !== 'consistent' && checked !== 'x' && checked !== 'X') { + file.fail( + 'Incorrect checked checkbox marker `' + + checked + + "`: use either `'x'`, or `'X'`" + ); + } + + visit$1(tree, 'listItem', (node) => { + const head = node.children[0]; + const point = pointStart(head); + + // Exit early for items without checkbox. + // A list item cannot be checked and empty, according to GFM. + if ( + typeof node.checked !== 'boolean' || + !head || + typeof point.offset !== 'number' + ) { + return + } + + // Move back to before `] `. + point.offset -= 2; + point.column -= 2; + + // Assume we start with a checkbox, because well, `checked` is set. + const match = /\[([\t Xx])]/.exec( + value.slice(point.offset - 2, point.offset + 1) + ); + + // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. + /* c8 ignore next */ + if (!match) return + + const style = node.checked ? checked : unchecked; + + if (style === 'consistent') { + if (node.checked) { + // @ts-expect-error: valid marker. + checked = match[1]; + } else { + // @ts-expect-error: valid marker. + unchecked = match[1]; + } + } else if (match[1] !== style) { + file.message( + (node.checked ? 'Checked' : 'Unchecked') + + ' checkboxes should use `' + + style + + '` as a marker', + point + ); + } + }); + } +); + +var remarkLintCheckboxCharacterStyle$1 = remarkLintCheckboxCharacterStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module checkbox-content-indent + * @fileoverview + * Warn when list item checkboxes are followed by too much whitespace. + * + * @example + * {"name": "ok.md", "gfm": true} + * + * - [ ] List item + * + [x] List Item + * * [X] List item + * - [ ] List item + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * - [ ] List item + * + [x] List item + * * [X] List item + * - [ ] List item + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 2:7-2:8: Checkboxes should be followed by a single character + * 3:7-3:9: Checkboxes should be followed by a single character + * 4:7-4:10: Checkboxes should be followed by a single character + */ + +const remarkLintCheckboxContentIndent = lintRule( + { + origin: 'remark-lint:checkbox-content-indent', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-checkbox-content-indent#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + const loc = location(file); + + visit$1(tree, 'listItem', (node) => { + const head = node.children[0]; + const point = pointStart(head); + + // Exit early for items without checkbox. + // A list item cannot be checked and empty, according to GFM. + if ( + typeof node.checked !== 'boolean' || + !head || + typeof point.offset !== 'number' + ) { + return + } + + // Assume we start with a checkbox, because well, `checked` is set. + const match = /\[([\t xX])]/.exec( + value.slice(point.offset - 4, point.offset + 1) + ); + + // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. + /* c8 ignore next */ + if (!match) return + + // Move past checkbox. + const initial = point.offset; + let final = initial; + + while (/[\t ]/.test(value.charAt(final))) final++; + + if (final - initial > 0) { + file.message('Checkboxes should be followed by a single character', { + start: loc.toPoint(initial), + end: loc.toPoint(final) + }); + } + }); + } +); + +var remarkLintCheckboxContentIndent$1 = remarkLintCheckboxContentIndent; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module code-block-style + * @fileoverview + * Warn when code blocks do not adhere to a given style. + * + * Options: `'consistent'`, `'fenced'`, or `'indented'`, default: `'consistent'`. + * + * `'consistent'` detects the first used code block style and warns when + * subsequent code blocks uses different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats code blocks using a fence if they have a language flag and + * indentation if not. + * Pass + * [`fences: true`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfences) + * to always use fences for code blocks. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"setting": "indented", "name": "ok.md"} + * + * alpha() + * + * Paragraph. + * + * bravo() + * + * @example + * {"setting": "indented", "name": "not-ok.md", "label": "input"} + * + * ``` + * alpha() + * ``` + * + * Paragraph. + * + * ``` + * bravo() + * ``` + * + * @example + * {"setting": "indented", "name": "not-ok.md", "label": "output"} + * + * 1:1-3:4: Code blocks should be indented + * 7:1-9:4: Code blocks should be indented + * + * @example + * {"setting": "fenced", "name": "ok.md"} + * + * ``` + * alpha() + * ``` + * + * Paragraph. + * + * ``` + * bravo() + * ``` + * + * @example + * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "input"} + * + * alpha() + * + * Paragraph. + * + * bravo() + * + * @example + * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "output"} + * + * 1:1-1:12: Code blocks should be fenced + * 5:1-5:12: Code blocks should be fenced + * + * @example + * {"name": "not-ok-consistent.md", "label": "input"} + * + * alpha() + * + * Paragraph. + * + * ``` + * bravo() + * ``` + * + * @example + * {"name": "not-ok-consistent.md", "label": "output"} + * + * 5:1-7:4: Code blocks should be indented + * + * @example + * {"setting": "💩", "name": "not-ok-incorrect.md", "label": "output", "positionless": true} + * + * 1:1: Incorrect code block style `💩`: use either `'consistent'`, `'fenced'`, or `'indented'` + */ + +const remarkLintCodeBlockStyle = lintRule( + { + origin: 'remark-lint:code-block-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-code-block-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if ( + option !== 'consistent' && + option !== 'fenced' && + option !== 'indented' + ) { + file.fail( + 'Incorrect code block style `' + + option + + "`: use either `'consistent'`, `'fenced'`, or `'indented'`" + ); + } + + visit$1(tree, 'code', (node) => { + if (generated(node)) { + return + } + + const initial = pointStart(node).offset; + const final = pointEnd(node).offset; + + const current = + node.lang || /^\s*([~`])\1{2,}/.test(value.slice(initial, final)) + ? 'fenced' + : 'indented'; + + if (option === 'consistent') { + option = current; + } else if (option !== current) { + file.message('Code blocks should be ' + option, node); + } + }); + } +); + +var remarkLintCodeBlockStyle$1 = remarkLintCodeBlockStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module definition-spacing + * @fileoverview + * Warn when consecutive whitespace is used in a definition. + * + * @example + * {"name": "ok.md"} + * + * [example domain]: http://example.com "Example Domain" + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * [example····domain]: http://example.com "Example Domain" + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-1:57: Do not use consecutive whitespace in definition labels + */ + +const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; + +const remarkLintDefinitionSpacing = lintRule( + { + origin: 'remark-lint:definition-spacing', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-definition-spacing#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + + visit$1(tree, (node) => { + if (node.type === 'definition' || node.type === 'footnoteDefinition') { + const start = pointStart(node).offset; + const end = pointEnd(node).offset; + + if (typeof start === 'number' && typeof end === 'number') { + const match = value.slice(start, end).match(label); + + if (match && /[ \t\n]{2,}/.test(match[1])) { + file.message( + 'Do not use consecutive whitespace in definition labels', + node + ); + } + } + } + }); + } +); + +var remarkLintDefinitionSpacing$1 = remarkLintDefinitionSpacing; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module fenced-code-flag + * @fileoverview + * Check fenced code block flags. + * + * Options: `Array.` or `Object`, optional. + * + * Providing an array is as passing `{flags: Array}`. + * + * The object can have an array of `'flags'` which are allowed: other flags + * will not be allowed. + * An `allowEmpty` field (`boolean`, default: `false`) can be set to allow + * code blocks without language flags. + * + * @example + * {"name": "ok.md"} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * ``` + * alpha() + * ``` + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:1-3:4: Missing code language flag + * + * @example + * {"name": "ok.md", "setting": {"allowEmpty": true}} + * + * ``` + * alpha() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "input"} + * + * ``` + * alpha() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "output"} + * + * 1:1-3:4: Missing code language flag + * + * @example + * {"name": "ok.md", "setting": ["alpha"]} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "ok.md", "setting": {"flags":["alpha"]}} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": ["charlie"], "label": "input"} + * + * ```alpha + * bravo() + * ``` + * + * @example + * {"name": "not-ok.md", "setting": ["charlie"], "label": "output"} + * + * 1:1-3:4: Incorrect code language flag + */ + +const fence = /^ {0,3}([~`])\1{2,}/; + +const remarkLintFencedCodeFlag = lintRule( + { + origin: 'remark-lint:fenced-code-flag', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-flag#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option) => { + const value = String(file); + let allowEmpty = false; + /** @type {string[]} */ + let allowed = []; + + if (typeof option === 'object') { + if (Array.isArray(option)) { + allowed = option; + } else { + allowEmpty = Boolean(option.allowEmpty); + + if (option.flags) { + allowed = option.flags; + } + } + } + + visit$1(tree, 'code', (node) => { + if (!generated(node)) { + if (node.lang) { + if (allowed.length > 0 && !allowed.includes(node.lang)) { + file.message('Incorrect code language flag', node); + } + } else { + const slice = value.slice( + pointStart(node).offset, + pointEnd(node).offset + ); + + if (!allowEmpty && fence.test(slice)) { + file.message('Missing code language flag', node); + } + } + } + }); + } +); + +var remarkLintFencedCodeFlag$1 = remarkLintFencedCodeFlag; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module fenced-code-marker + * @fileoverview + * Warn for violating fenced code markers. + * + * Options: `` '`' ``, `'~'`, or `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used fenced code marker style and warns + * when subsequent fenced code blocks use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats fences using ``'`'`` (grave accent) by default. + * Pass + * [`fence: '~'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfence) + * to use `~` (tilde) instead. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * Indented code blocks are not affected by this rule: + * + * bravo() + * + * @example + * {"name": "ok.md", "setting": "`"} + * + * ```alpha + * bravo() + * ``` + * + * ``` + * charlie() + * ``` + * + * @example + * {"name": "ok.md", "setting": "~"} + * + * ~~~alpha + * bravo() + * ~~~ + * + * ~~~ + * charlie() + * ~~~ + * + * @example + * {"name": "not-ok-consistent-tick.md", "label": "input"} + * + * ```alpha + * bravo() + * ``` + * + * ~~~ + * charlie() + * ~~~ + * + * @example + * {"name": "not-ok-consistent-tick.md", "label": "output"} + * + * 5:1-7:4: Fenced code should use `` ` `` as a marker + * + * @example + * {"name": "not-ok-consistent-tilde.md", "label": "input"} + * + * ~~~alpha + * bravo() + * ~~~ + * + * ``` + * charlie() + * ``` + * + * @example + * {"name": "not-ok-consistent-tilde.md", "label": "output"} + * + * 5:1-7:4: Fenced code should use `~` as a marker + * + * @example + * {"name": "not-ok-incorrect.md", "setting": "💩", "label": "output", "positionless": true} + * + * 1:1: Incorrect fenced code marker `💩`: use either `'consistent'`, `` '`' ``, or `'~'` + */ + +const remarkLintFencedCodeMarker = lintRule( + { + origin: 'remark-lint:fenced-code-marker', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-fenced-code-marker#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const contents = String(file); + + if (option !== 'consistent' && option !== '~' && option !== '`') { + file.fail( + 'Incorrect fenced code marker `' + + option + + "`: use either `'consistent'`, `` '`' ``, or `'~'`" + ); + } + + visit$1(tree, 'code', (node) => { + const start = pointStart(node).offset; + + if (typeof start === 'number') { + const marker = contents + .slice(start, start + 4) + .replace(/^\s+/, '') + .charAt(0); + + // Ignore unfenced code blocks. + if (marker === '~' || marker === '`') { + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message( + 'Fenced code should use `' + + (option === '~' ? option : '` ` `') + + '` as a marker', + node + ); + } + } + } + }); + } +); + +var remarkLintFencedCodeMarker$1 = remarkLintFencedCodeMarker; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module file-extension + * @fileoverview + * Warn when the file extension differ from the preferred extension. + * + * Does not warn when given documents have no file extensions (such as + * `AUTHORS` or `LICENSE`). + * + * Options: `string`, default: `'md'` — Expected file extension. + * + * @example + * {"name": "readme.md"} + * + * @example + * {"name": "readme"} + * + * @example + * {"name": "readme.mkd", "label": "output", "positionless": true} + * + * 1:1: Incorrect extension: use `md` + * + * @example + * {"name": "readme.mkd", "setting": "mkd"} + */ + +const remarkLintFileExtension = lintRule( + { + origin: 'remark-lint:file-extension', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-file-extension#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (_, file, option = 'md') => { + const ext = file.extname; + + if (ext && ext.slice(1) !== option) { + file.message('Incorrect extension: use `' + option + '`'); + } + } +); + +var remarkLintFileExtension$1 = remarkLintFileExtension; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module final-definition + * @fileoverview + * Warn when definitions are placed somewhere other than at the end of + * the file. + * + * @example + * {"name": "ok.md"} + * + * Paragraph. + * + * [example]: http://example.com "Example Domain" + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * Paragraph. + * + * [example]: http://example.com "Example Domain" + * + * Another paragraph. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:1-3:47: Move definitions to the end of the file (after the node at line `5`) + * + * @example + * {"name": "ok-comments.md"} + * + * Paragraph. + * + * [example-1]: http://example.com/one/ + * + * + * + * [example-2]: http://example.com/two/ + */ + +const remarkLintFinalDefinition = lintRule( + { + origin: 'remark-lint:final-definition', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-final-definition#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + let last = 0; + + visit$1( + tree, + (node) => { + // Ignore generated and HTML comment nodes. + if ( + node.type === 'root' || + generated(node) || + (node.type === 'html' && /^\s*".length)); + + validateMeta(node, file, meta); + } catch (e) { + file.message(e, node); + } + }); +} + +const remarkLintNodejsYamlComments = lintRule( + "remark-lint:nodejs-yaml-comments", + validateYAMLComments +); + +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'); +} + +const remarkLintProhibitedStrings = lintRule('remark-lint:prohibited-strings', prohibitedStrings); + +function testProhibited (val, content) { + let regexpFlags = 'g'; + let no = val.no; + + if (!no) { + no = escapeStringRegexp(val.yes); + regexpFlags += 'i'; + } + + let regexpString = '(? { + const results = testProhibited(val, content); + if (results.length) { + results.forEach(({ result, index, yes }) => { + const message = val.yes ? `Use "${yes}" instead of "${result}"` : `Do not use "${result}"`; + file.message(message, { + start: myLocation.toPoint(initial + index), + end: myLocation.toPoint(initial + index + [...result].length) + }); + }); + } + }); + } +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module rule-style + * @fileoverview + * Warn when the thematic breaks (horizontal rules) violate a given or + * detected style. + * + * Options: `string`, either a corect thematic breaks such as `***`, or + * `'consistent'`, default: `'consistent'`. + * + * `'consistent'` detects the first used thematic break style and warns when + * subsequent rules use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * has three settings that define how rules are created: + * + * * [`rule`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrule) + * (default: `*`) — Marker to use + * * [`ruleRepetition`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulerepetition) + * (default: `3`) — Number of markers to use + * * [`ruleSpaces`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulespaces) + * (default: `true`) — Whether to pad markers with spaces + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": "* * *"} + * + * * * * + * + * * * * + * + * @example + * {"name": "ok.md", "setting": "_______"} + * + * _______ + * + * _______ + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * *** + * + * * * * + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 3:1-3:6: Rules should use `***` + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect preferred rule style: provide a correct markdown rule or `'consistent'` + */ + +const remarkLintRuleStyle = lintRule( + { + origin: 'remark-lint:rule-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-rule-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && /[^-_* ]/.test(option)) { + file.fail( + "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" + ); + } + + visit$1(tree, 'thematicBreak', (node) => { + const initial = pointStart(node).offset; + const final = pointEnd(node).offset; + + if (typeof initial === 'number' && typeof final === 'number') { + const rule = value.slice(initial, final); + + if (option === 'consistent') { + option = rule; + } else if (rule !== option) { + file.message('Rules should use `' + option + '`', node); + } + } + }); + } +); + +var remarkLintRuleStyle$1 = remarkLintRuleStyle; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module strong-marker + * @fileoverview + * Warn for violating importance (strong) markers. + * + * Options: `'consistent'`, `'*'`, or `'_'`, default: `'consistent'`. + * + * `'consistent'` detects the first used importance style and warns when + * subsequent importance sequences use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats importance using an `*` (asterisk) by default. + * Pass + * [`strong: '_'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsstrong) + * to use `_` (underscore) instead. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * **foo** and **bar**. + * + * @example + * {"name": "also-ok.md"} + * + * __foo__ and __bar__. + * + * @example + * {"name": "ok.md", "setting": "*"} + * + * **foo**. + * + * @example + * {"name": "ok.md", "setting": "_"} + * + * __foo__. + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * **foo** and __bar__. + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 1:13-1:20: Strong should use `*` as a marker + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect strong marker `💩`: use either `'consistent'`, `'*'`, or `'_'` + */ + +const remarkLintStrongMarker = lintRule( + { + origin: 'remark-lint:strong-marker', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-strong-marker#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== '*' && option !== '_' && option !== 'consistent') { + file.fail( + 'Incorrect strong marker `' + + option + + "`: use either `'consistent'`, `'*'`, or `'_'`" + ); + } + + visit$1(tree, 'strong', (node) => { + const start = pointStart(node).offset; + + if (typeof start === 'number') { + const marker = /** @type {Marker} */ (value.charAt(start)); + + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Strong should use `' + option + '` as a marker', node); + } + } + }); + } +); + +var remarkLintStrongMarker$1 = remarkLintStrongMarker; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module table-cell-padding + * @fileoverview + * Warn when table cells are incorrectly padded. + * + * Options: `'consistent'`, `'padded'`, or `'compact'`, default: `'consistent'`. + * + * `'consistent'` detects the first used cell padding style and warns when + * subsequent cells use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats tables with padding by default. + * Pass + * [`spacedTable: false`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsspacedtable) + * to not use padding. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "setting": "padded", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * @example + * {"name": "not-ok.md", "label": "input", "setting": "padded", "gfm": true} + * + * | A | B | + * | :----|----: | + * | Alpha|Bravo | + * + * | C | D | + * | :----- | ---: | + * |Charlie | Delta| + * + * Too much padding isn’t good either: + * + * | E | F | G | H | + * | :---- | -------- | :----: | -----: | + * | Echo | Foxtrot | Golf | Hotel | + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "padded", "gfm": true} + * + * 3:8: Cell should be padded + * 3:9: Cell should be padded + * 7:2: Cell should be padded + * 7:17: Cell should be padded + * 13:9: Cell should be padded with 1 space, not 2 + * 13:20: Cell should be padded with 1 space, not 2 + * 13:21: Cell should be padded with 1 space, not 2 + * 13:29: Cell should be padded with 1 space, not 2 + * 13:30: Cell should be padded with 1 space, not 2 + * + * @example + * {"name": "ok.md", "setting": "compact", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * @example + * {"name": "not-ok.md", "label": "input", "setting": "compact", "gfm": true} + * + * | A | B | + * | -----| -----| + * | Alpha| Bravo| + * + * |C | D| + * |:------|-----:| + * |Charlie|Delta | + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "compact", "gfm": true} + * + * 3:2: Cell should be compact + * 3:11: Cell should be compact + * 7:16: Cell should be compact + * + * @example + * {"name": "ok-padded.md", "setting": "consistent", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * | C | D | + * | ------- | ----- | + * | Charlie | Delta | + * + * @example + * {"name": "not-ok-padded.md", "label": "input", "setting": "consistent", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * | C | D | + * | :----- | ----: | + * |Charlie | Delta | + * + * @example + * {"name": "not-ok-padded.md", "label": "output", "setting": "consistent", "gfm": true} + * + * 7:2: Cell should be padded + * + * @example + * {"name": "ok-compact.md", "setting": "consistent", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * |C |D | + * |-------|-----| + * |Charlie|Delta| + * + * @example + * {"name": "not-ok-compact.md", "label": "input", "setting": "consistent", "gfm": true} + * + * |A |B | + * |-----|-----| + * |Alpha|Bravo| + * + * |C | D| + * |:------|-----:| + * |Charlie|Delta | + * + * @example + * {"name": "not-ok-compact.md", "label": "output", "setting": "consistent", "gfm": true} + * + * 7:16: Cell should be compact + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true, "gfm": true} + * + * 1:1: Incorrect table cell padding style `💩`, expected `'padded'`, `'compact'`, or `'consistent'` + * + * @example + * {"name": "empty.md", "label": "input", "setting": "padded", "gfm": true} + * + * + * + * | | Alpha | Bravo| + * | ------ | ----- | ---: | + * | Charlie| | Echo| + * + * @example + * {"name": "empty.md", "label": "output", "setting": "padded", "gfm": true} + * + * 3:25: Cell should be padded + * 5:10: Cell should be padded + * 5:25: Cell should be padded + * + * @example + * {"name": "missing-body.md", "setting": "padded", "gfm": true} + * + * + * + * | Alpha | Bravo | Charlie | + * | ----- | ------- | ------- | + * | Delta | + * | Echo | Foxtrot | + */ + +const remarkLintTableCellPadding = lintRule( + { + origin: 'remark-lint:table-cell-padding', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-table-cell-padding#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + if ( + option !== 'padded' && + option !== 'compact' && + option !== 'consistent' + ) { + file.fail( + 'Incorrect table cell padding style `' + + option + + "`, expected `'padded'`, `'compact'`, or `'consistent'`" + ); + } + + visit$1(tree, 'table', (node) => { + const rows = node.children; + // To do: fix types to always have `align` defined. + /* c8 ignore next */ + const align = node.align || []; + /** @type {number[]} */ + const sizes = Array.from({length: align.length}); + /** @type {Entry[]} */ + const entries = []; + let index = -1; + + // Check rows. + while (++index < rows.length) { + const row = rows[index]; + let column = -1; + + // Check fences (before, between, and after cells). + while (++column < row.children.length) { + const cell = row.children[column]; + + if (cell.children.length > 0) { + const cellStart = pointStart(cell).offset; + const cellEnd = pointEnd(cell).offset; + const contentStart = pointStart(cell.children[0]).offset; + const contentEnd = pointEnd( + cell.children[cell.children.length - 1] + ).offset; + + if ( + typeof cellStart !== 'number' || + typeof cellEnd !== 'number' || + typeof contentStart !== 'number' || + typeof contentEnd !== 'number' + ) { + continue + } + + entries.push({ + node: cell, + start: contentStart - cellStart - (column ? 0 : 1), + end: cellEnd - contentEnd - 1, + column + }); + + // Detect max space per column. + sizes[column] = Math.max( + sizes[column] || 0, + contentEnd - contentStart + ); + } + } + } + + const style = + option === 'consistent' + ? entries[0] && (!entries[0].start || !entries[0].end) + ? 0 + : 1 + : option === 'padded' + ? 1 + : 0; + + index = -1; + + while (++index < entries.length) { + checkSide('start', entries[index], style, sizes); + checkSide('end', entries[index], style, sizes); + } + + return SKIP$1 + }); + + /** + * @param {'start'|'end'} side + * @param {Entry} entry + * @param {0|1} style + * @param {number[]} sizes + */ + function checkSide(side, entry, style, sizes) { + const cell = entry.node; + const column = entry.column; + const spacing = entry[side]; + + if (spacing === undefined || spacing === style) { + return + } + + let reason = 'Cell should be '; + + if (style === 0) { + // Ignore every cell except the biggest in the column. + if (size$1(cell) < sizes[column]) { + return + } + + reason += 'compact'; + } else { + reason += 'padded'; + + if (spacing > style) { + // May be right or center aligned. + if (size$1(cell) < sizes[column]) { + return + } + + reason += ' with 1 space, not ' + spacing; + } + } + + /** @type {Point} */ + let point; + + if (side === 'start') { + point = pointStart(cell); + if (!column) { + point.column++; + + if (typeof point.offset === 'number') { + point.offset++; + } + } + } else { + point = pointEnd(cell); + point.column--; + + if (typeof point.offset === 'number') { + point.offset--; + } + } + + file.message(reason, point); + } + } +); + +var remarkLintTableCellPadding$1 = remarkLintTableCellPadding; + +/** + * @param {TableCell} node + * @returns {number} + */ +function size$1(node) { + const head = pointStart(node.children[0]).offset; + const tail = pointEnd(node.children[node.children.length - 1]).offset; + // Only called when we’re sure offsets exist. + /* c8 ignore next */ + return typeof head === 'number' && typeof tail === 'number' ? tail - head : 0 +} + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module table-pipes + * @fileoverview + * Warn when table rows are not fenced with pipes. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * creates fenced rows with initial and final pipes by default. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md", "gfm": true} + * + * | A | B | + * | ----- | ----- | + * | Alpha | Bravo | + * + * @example + * {"name": "not-ok.md", "label": "input", "gfm": true} + * + * A | B + * ----- | ----- + * Alpha | Bravo + * + * @example + * {"name": "not-ok.md", "label": "output", "gfm": true} + * + * 1:1: Missing initial pipe in table fence + * 1:10: Missing final pipe in table fence + * 3:1: Missing initial pipe in table fence + * 3:14: Missing final pipe in table fence + */ + +const reasonStart = 'Missing initial pipe in table fence'; +const reasonEnd = 'Missing final pipe in table fence'; + +const remarkLintTablePipes = lintRule( + { + origin: 'remark-lint:table-pipes', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-table-pipes#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file) => { + const value = String(file); + + visit$1(tree, 'table', (node) => { + let index = -1; + + while (++index < node.children.length) { + const row = node.children[index]; + const start = pointStart(row); + const end = pointEnd(row); + + if ( + typeof start.offset === 'number' && + value.charCodeAt(start.offset) !== 124 + ) { + file.message(reasonStart, start); + } + + if ( + typeof end.offset === 'number' && + value.charCodeAt(end.offset - 1) !== 124 + ) { + file.message(reasonEnd, end); + } + } + }); + } +); + +var remarkLintTablePipes$1 = remarkLintTablePipes; + +/** + * @author Titus Wormer + * @copyright 2015 Titus Wormer + * @license MIT + * @module unordered-list-marker-style + * @fileoverview + * Warn when the list item marker style of unordered lists violate a given + * style. + * + * Options: `'consistent'`, `'-'`, `'*'`, or `'+'`, default: `'consistent'`. + * + * `'consistent'` detects the first used list style and warns when subsequent + * lists use different styles. + * + * ## Fix + * + * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) + * formats unordered lists using `-` (hyphen-minus) by default. + * Pass + * [`bullet: '*'` or `bullet: '+'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsbullet) + * to use `*` (asterisk) or `+` (plus sign) instead. + * + * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) + * on how to automatically fix warnings for this rule. + * + * @example + * {"name": "ok.md"} + * + * By default (`'consistent'`), if the file uses only one marker, + * that’s OK. + * + * * Foo + * * Bar + * * Baz + * + * Ordered lists are not affected. + * + * 1. Foo + * 2. Bar + * 3. Baz + * + * @example + * {"name": "ok.md", "setting": "*"} + * + * * Foo + * + * @example + * {"name": "ok.md", "setting": "-"} + * + * - Foo + * + * @example + * {"name": "ok.md", "setting": "+"} + * + * + Foo + * + * @example + * {"name": "not-ok.md", "label": "input"} + * + * * Foo + * - Bar + * + Baz + * + * @example + * {"name": "not-ok.md", "label": "output"} + * + * 2:1-2:6: Marker style should be `*` + * 3:1-3:6: Marker style should be `*` + * + * @example + * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} + * + * 1:1: Incorrect unordered list item marker style `💩`: use either `'-'`, `'*'`, or `'+'` + */ + +const markers = new Set(['-', '*', '+']); + +const remarkLintUnorderedListMarkerStyle = lintRule( + { + origin: 'remark-lint:unordered-list-marker-style', + url: 'https://github.com/remarkjs/remark-lint/tree/main/packages/remark-lint-unordered-list-marker-style#readme' + }, + /** @type {import('unified-lint-rule').Rule} */ + (tree, file, option = 'consistent') => { + const value = String(file); + + if (option !== 'consistent' && !markers.has(option)) { + file.fail( + 'Incorrect unordered list item marker style `' + + option + + "`: use either `'-'`, `'*'`, or `'+'`" + ); + } + + visit$1(tree, 'list', (node) => { + if (node.ordered) return + + let index = -1; + + while (++index < node.children.length) { + const child = node.children[index]; + + if (!generated(child)) { + const marker = /** @type {Marker} */ ( + value + .slice( + pointStart(child).offset, + pointStart(child.children[0]).offset + ) + .replace(/\[[x ]?]\s*$/i, '') + .replace(/\s/g, '') + ); + + if (option === 'consistent') { + option = marker; + } else if (marker !== option) { + file.message('Marker style should be `' + option + '`', child); + } + } + } + }); + } +); + +var remarkLintUnorderedListMarkerStyle$1 = remarkLintUnorderedListMarkerStyle; + +// @see https://github.com/nodejs/node/blob/HEAD/doc/guides/doc-style-guide.md + +// Add in rules alphabetically +const plugins = [ + // Leave preset at the top so it can be overridden + remarkPresetLintRecommended$1, + [remarkLintBlockquoteIndentation$1, 2], + [remarkLintCheckboxCharacterStyle$1, { checked: "x", unchecked: " " }], + remarkLintCheckboxContentIndent$1, + [remarkLintCodeBlockStyle$1, "fenced"], + remarkLintDefinitionSpacing$1, + [ + remarkLintFencedCodeFlag$1, + { + flags: [ + "bash", + "c", + "cjs", + "coffee", + "console", + "cpp", + "diff", + "http", + "js", + "json", + "markdown", + "mjs", + "powershell", + "r", + "text", + ], + }, + ], + [remarkLintFencedCodeMarker$1, "`"], + [remarkLintFileExtension$1, "md"], + remarkLintFinalDefinition$1, + [remarkLintFirstHeadingLevel$1, 1], + [remarkLintHeadingStyle$1, "atx"], + [remarkLintListItemIndent$1, "space"], + remarkLintMaximumLineLength$1, + remarkLintNoConsecutiveBlankLines$1, + remarkLintNoFileNameArticles$1, + remarkLintNoFileNameConsecutiveDashes$1, + remarkLintNofileNameOuterDashes$1, + remarkLintNoHeadingIndent$1, + remarkLintNoMultipleToplevelHeadings$1, + remarkLintNoShellDollars$1, + remarkLintNoTableIndentation$1, + remarkLintNoTabs$1, + remarkLintNoTrailingSpaces, + remarkLintNodejsLinks, + remarkLintNodejsYamlComments, + [ + remarkLintProhibitedStrings, + [ + { yes: "End-of-Life" }, + { yes: "GitHub" }, + { no: "hostname", yes: "host name" }, + { yes: "JavaScript" }, + { no: "[Ll]ong[ -][Tt]erm [Ss]upport", yes: "Long Term Support" }, + { no: "Node", yes: "Node.js", ignoreNextTo: "-API" }, + { yes: "Node.js" }, + { no: "Node[Jj][Ss]", yes: "Node.js" }, + { no: "Node\\.js's?", yes: "the Node.js" }, + { no: "[Nn]ote that", yes: "" }, + { yes: "RFC" }, + { no: "[Rr][Ff][Cc]\\d+", yes: "RFC " }, + { yes: "Unix" }, + { yes: "V8" }, + ], + ], + remarkLintRuleStyle$1, + [remarkLintStrongMarker$1, "*"], + [remarkLintTableCellPadding$1, "padded"], + remarkLintTablePipes$1, + [remarkLintUnorderedListMarkerStyle$1, "*"], +]; + +const settings = { + emphasis: "_", + listItemIndent: 1, + tightDefinitions: true, +}; + +const remarkPresetLintNode = { plugins, settings }; + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').Previous} Previous + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Event} Event + * @typedef {import('micromark-util-types').Code} Code + */ +const www = { + tokenize: tokenizeWww, + partial: true +}; +const domain = { + tokenize: tokenizeDomain, + partial: true +}; +const path = { + tokenize: tokenizePath, + partial: true +}; +const punctuation = { + tokenize: tokenizePunctuation, + partial: true +}; +const namedCharacterReference = { + tokenize: tokenizeNamedCharacterReference, + partial: true +}; +const wwwAutolink = { + tokenize: tokenizeWwwAutolink, + previous: previousWww +}; +const httpAutolink = { + tokenize: tokenizeHttpAutolink, + previous: previousHttp +}; +const emailAutolink = { + tokenize: tokenizeEmailAutolink, + previous: previousEmail +}; +/** @type {ConstructRecord} */ + +const text = {}; +/** @type {Extension} */ + +const gfmAutolinkLiteral = { + text +}; +let code = 48; // Add alphanumerics. + +while (code < 123) { + text[code] = emailAutolink; + code++; + if (code === 58) code = 65; + else if (code === 91) code = 97; +} + +text[43] = emailAutolink; +text[45] = emailAutolink; +text[46] = emailAutolink; +text[95] = emailAutolink; +text[72] = [emailAutolink, httpAutolink]; +text[104] = [emailAutolink, httpAutolink]; +text[87] = [emailAutolink, wwwAutolink]; +text[119] = [emailAutolink, wwwAutolink]; +/** @type {Tokenizer} */ + +function tokenizeEmailAutolink(effects, ok, nok) { + const self = this; + /** @type {boolean} */ + + let hasDot; + /** @type {boolean|undefined} */ + + let hasDigitInLastSegment; + return start + /** @type {State} */ + + function start(code) { + if ( + !gfmAtext(code) || + !previousEmail(self.previous) || + previousUnbalanced(self.events) + ) { + return nok(code) + } + + effects.enter('literalAutolink'); + effects.enter('literalAutolinkEmail'); + return atext(code) + } + /** @type {State} */ + + function atext(code) { + if (gfmAtext(code)) { + effects.consume(code); + return atext + } + + if (code === 64) { + effects.consume(code); + return label + } + + return nok(code) + } + /** @type {State} */ + + function label(code) { + if (code === 46) { + return effects.check(punctuation, done, dotContinuation)(code) + } + + if (code === 45 || code === 95) { + return effects.check(punctuation, nok, dashOrUnderscoreContinuation)(code) + } + + if (asciiAlphanumeric(code)) { + if (!hasDigitInLastSegment && asciiDigit(code)) { + hasDigitInLastSegment = true; + } + + effects.consume(code); + return label + } + + return done(code) + } + /** @type {State} */ + + function dotContinuation(code) { + effects.consume(code); + hasDot = true; + hasDigitInLastSegment = undefined; + return label + } + /** @type {State} */ + + function dashOrUnderscoreContinuation(code) { + effects.consume(code); + return afterDashOrUnderscore + } + /** @type {State} */ + + function afterDashOrUnderscore(code) { + if (code === 46) { + return effects.check(punctuation, nok, dotContinuation)(code) + } + + return label(code) + } + /** @type {State} */ + + function done(code) { + if (hasDot && !hasDigitInLastSegment) { + effects.exit('literalAutolinkEmail'); + effects.exit('literalAutolink'); + return ok(code) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeWwwAutolink(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + if ( + (code !== 87 && code !== 119) || + !previousWww(self.previous) || + previousUnbalanced(self.events) + ) { + return nok(code) + } + + effects.enter('literalAutolink'); + effects.enter('literalAutolinkWww'); // For `www.` we check instead of attempt, because when it matches, GH + // treats it as part of a domain (yes, it says a valid domain must come + // after `www.`, but that’s not how it’s implemented by them). + + return effects.check( + www, + effects.attempt(domain, effects.attempt(path, done), nok), + nok + )(code) + } + /** @type {State} */ + + function done(code) { + effects.exit('literalAutolinkWww'); + effects.exit('literalAutolink'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeHttpAutolink(effects, ok, nok) { + const self = this; + return start + /** @type {State} */ + + function start(code) { + if ( + (code !== 72 && code !== 104) || + !previousHttp(self.previous) || + previousUnbalanced(self.events) + ) { + return nok(code) + } + + effects.enter('literalAutolink'); + effects.enter('literalAutolinkHttp'); + effects.consume(code); + return t1 + } + /** @type {State} */ + + function t1(code) { + if (code === 84 || code === 116) { + effects.consume(code); + return t2 + } + + return nok(code) + } + /** @type {State} */ + + function t2(code) { + if (code === 84 || code === 116) { + effects.consume(code); + return p + } + + return nok(code) + } + /** @type {State} */ + + function p(code) { + if (code === 80 || code === 112) { + effects.consume(code); + return s + } + + return nok(code) + } + /** @type {State} */ + + function s(code) { + if (code === 83 || code === 115) { + effects.consume(code); + return colon + } + + return colon(code) + } + /** @type {State} */ + + function colon(code) { + if (code === 58) { + effects.consume(code); + return slash1 + } + + return nok(code) + } + /** @type {State} */ + + function slash1(code) { + if (code === 47) { + effects.consume(code); + return slash2 + } + + return nok(code) + } + /** @type {State} */ + + function slash2(code) { + if (code === 47) { + effects.consume(code); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + return code === null || + asciiControl(code) || + unicodeWhitespace(code) || + unicodePunctuation(code) + ? nok(code) + : effects.attempt(domain, effects.attempt(path, done), nok)(code) + } + /** @type {State} */ + + function done(code) { + effects.exit('literalAutolinkHttp'); + effects.exit('literalAutolink'); + return ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeWww(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.consume(code); + return w2 + } + /** @type {State} */ + + function w2(code) { + if (code === 87 || code === 119) { + effects.consume(code); + return w3 + } + + return nok(code) + } + /** @type {State} */ + + function w3(code) { + if (code === 87 || code === 119) { + effects.consume(code); + return dot + } + + return nok(code) + } + /** @type {State} */ + + function dot(code) { + if (code === 46) { + effects.consume(code); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + return code === null || markdownLineEnding(code) ? nok(code) : ok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeDomain(effects, ok, nok) { + /** @type {boolean|undefined} */ + let hasUnderscoreInLastSegment; + /** @type {boolean|undefined} */ + + let hasUnderscoreInLastLastSegment; + return domain + /** @type {State} */ + + function domain(code) { + if (code === 38) { + return effects.check( + namedCharacterReference, + done, + punctuationContinuation + )(code) + } + + if (code === 46 || code === 95) { + return effects.check(punctuation, done, punctuationContinuation)(code) + } // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can + // occur, which sounds like ASCII only, but they also support `www.點看.com`, + // so that’s Unicode. + // Instead of some new production for Unicode alphanumerics, markdown + // already has that for Unicode punctuation and whitespace, so use those. + + if ( + code === null || + asciiControl(code) || + unicodeWhitespace(code) || + (code !== 45 && unicodePunctuation(code)) + ) { + return done(code) + } + + effects.consume(code); + return domain + } + /** @type {State} */ + + function punctuationContinuation(code) { + if (code === 46) { + hasUnderscoreInLastLastSegment = hasUnderscoreInLastSegment; + hasUnderscoreInLastSegment = undefined; + effects.consume(code); + return domain + } + + if (code === 95) hasUnderscoreInLastSegment = true; + effects.consume(code); + return domain + } + /** @type {State} */ + + function done(code) { + if (!hasUnderscoreInLastLastSegment && !hasUnderscoreInLastSegment) { + return ok(code) + } + + return nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizePath(effects, ok) { + let balance = 0; + return inPath + /** @type {State} */ + + function inPath(code) { + if (code === 38) { + return effects.check( + namedCharacterReference, + ok, + continuedPunctuation + )(code) + } + + if (code === 40) { + balance++; + } + + if (code === 41) { + return effects.check( + punctuation, + parenAtPathEnd, + continuedPunctuation + )(code) + } + + if (pathEnd(code)) { + return ok(code) + } + + if (trailingPunctuation(code)) { + return effects.check(punctuation, ok, continuedPunctuation)(code) + } + + effects.consume(code); + return inPath + } + /** @type {State} */ + + function continuedPunctuation(code) { + effects.consume(code); + return inPath + } + /** @type {State} */ + + function parenAtPathEnd(code) { + balance--; + return balance < 0 ? ok(code) : continuedPunctuation(code) + } +} +/** @type {Tokenizer} */ + +function tokenizeNamedCharacterReference(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.consume(code); + return inside + } + /** @type {State} */ + + function inside(code) { + if (asciiAlpha(code)) { + effects.consume(code); + return inside + } + + if (code === 59) { + effects.consume(code); + return after + } + + return nok(code) + } + /** @type {State} */ + + function after(code) { + // If the named character reference is followed by the end of the path, it’s + // not continued punctuation. + return pathEnd(code) ? ok(code) : nok(code) + } +} +/** @type {Tokenizer} */ + +function tokenizePunctuation(effects, ok, nok) { + return start + /** @type {State} */ + + function start(code) { + effects.consume(code); + return after + } + /** @type {State} */ + + function after(code) { + // Check the next. + if (trailingPunctuation(code)) { + effects.consume(code); + return after + } // If the punctuation marker is followed by the end of the path, it’s not + // continued punctuation. + + return pathEnd(code) ? ok(code) : nok(code) + } +} +/** + * @param {Code} code + * @returns {boolean} + */ + +function trailingPunctuation(code) { + return ( + code === 33 || + code === 34 || + code === 39 || + code === 41 || + code === 42 || + code === 44 || + code === 46 || + code === 58 || + code === 59 || + code === 60 || + code === 63 || + code === 95 || + code === 126 + ) +} +/** + * @param {Code} code + * @returns {boolean} + */ + +function pathEnd(code) { + return code === null || code === 60 || markdownLineEndingOrSpace(code) +} +/** + * @param {Code} code + * @returns {boolean} + */ + +function gfmAtext(code) { + return ( + code === 43 || + code === 45 || + code === 46 || + code === 95 || + asciiAlphanumeric(code) + ) +} +/** @type {Previous} */ + +function previousWww(code) { + return ( + code === null || + code === 40 || + code === 42 || + code === 95 || + code === 126 || + markdownLineEndingOrSpace(code) + ) +} +/** @type {Previous} */ + +function previousHttp(code) { + return code === null || !asciiAlpha(code) +} +/** @type {Previous} */ + +function previousEmail(code) { + return code !== 47 && previousHttp(code) +} +/** + * @param {Event[]} events + * @returns {boolean} + */ + +function previousUnbalanced(events) { + let index = events.length; + let result = false; + + while (index--) { + const token = events[index][1]; + + if ( + (token.type === 'labelLink' || token.type === 'labelImage') && + !token._balanced + ) { + result = true; + break + } // @ts-expect-error If we’ve seen this token, and it was marked as not + // having any unbalanced bracket before it, we can exit. + + if (token._gfmAutolinkLiteralWalkedInto) { + result = false; + break + } + } + + if (events.length > 0 && !result) { + // @ts-expect-error Mark the last token as “walked into” w/o finding + // anything. + events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true; + } + + return result +} + +const characterReferences = {'"': 'quot', '&': 'amp', '<': 'lt', '>': 'gt'}; + +/** + * Encode only the dangerous HTML characters. + * + * This ensures that certain characters which have special meaning in HTML are + * dealt with. + * Technically, we can skip `>` and `"` in many cases, but CM includes them. + * + * @param {string} value + * @returns {string} + */ +function encode(value) { + return value.replace(/["&<>]/g, replace) + + /** + * @param {string} value + * @returns {string} + */ + function replace(value) { + // @ts-expect-error Hush, it’s fine. + return '&' + characterReferences[value] + ';' + } +} + +/** + * Make a value safe for injection as a URL. + * + * This encodes unsafe characters with percent-encoding and skips already + * encoded sequences (see `normalizeUri` below). + * Further unsafe characters are encoded as character references (see + * `micromark-util-encode`). + * + * Then, a regex of allowed protocols can be given, in which case the URL is + * sanitized. + * For example, `/^(https?|ircs?|mailto|xmpp)$/i` can be used for `a[href]`, + * or `/^https?$/i` for `img[src]`. + * If the URL includes an unknown protocol (one not matched by `protocol`, such + * as a dangerous example, `javascript:`), the value is ignored. + * + * @param {string|undefined} url + * @param {RegExp} [protocol] + * @returns {string} + */ +function sanitizeUri(url, protocol) { + const value = encode(normalizeUri(url || '')); + + if (!protocol) { + return value + } + + const colon = value.indexOf(':'); + const questionMark = value.indexOf('?'); + const numberSign = value.indexOf('#'); + const slash = value.indexOf('/'); + + if ( + // If there is no protocol, it’s relative. + colon < 0 || // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol. + (slash > -1 && colon > slash) || + (questionMark > -1 && colon > questionMark) || + (numberSign > -1 && colon > numberSign) || // It is a protocol, it should be allowed. + protocol.test(value.slice(0, colon)) + ) { + return value + } + + return '' +} +/** + * Normalize a URL (such as used in definitions). + * + * Encode unsafe characters with percent-encoding, skipping already encoded + * sequences. + * + * @param {string} value + * @returns {string} + */ + +function normalizeUri(value) { + /** @type {string[]} */ + const result = []; + let index = -1; + let start = 0; + let skip = 0; + + while (++index < value.length) { + const code = value.charCodeAt(index); + /** @type {string} */ + + let replace = ''; // A correct percent encoded value. + + if ( + code === 37 && + asciiAlphanumeric(value.charCodeAt(index + 1)) && + asciiAlphanumeric(value.charCodeAt(index + 2)) + ) { + skip = 2; + } // ASCII. + else if (code < 128) { + if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) { + replace = String.fromCharCode(code); + } + } // Astral. + else if (code > 55295 && code < 57344) { + const next = value.charCodeAt(index + 1); // A correct surrogate pair. + + if (code < 56320 && next > 56319 && next < 57344) { + replace = String.fromCharCode(code, next); + skip = 1; + } // Lone surrogate. + else { + replace = '\uFFFD'; + } + } // Unicode. + else { + replace = String.fromCharCode(code); + } + + if (replace) { + result.push(value.slice(start, index), encodeURIComponent(replace)); + start = index + skip + 1; + replace = ''; + } + + if (skip) { + index += skip; + skip = 0; + } + } + + return result.join('') + value.slice(start) +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + * @typedef {import('micromark-util-types').Handle} Handle + * @typedef {import('micromark-util-types').CompileContext} CompileContext + * @typedef {import('micromark-util-types').Token} Token + */ +/** @type {HtmlExtension} */ + +const gfmAutolinkLiteralHtml = { + exit: { + literalAutolinkEmail, + literalAutolinkHttp, + literalAutolinkWww + } +}; +/** @type {Handle} */ + +function literalAutolinkWww(token) { + anchorFromToken.call(this, token, 'http://'); +} +/** @type {Handle} */ + +function literalAutolinkEmail(token) { + anchorFromToken.call(this, token, 'mailto:'); +} +/** @type {Handle} */ + +function literalAutolinkHttp(token) { + anchorFromToken.call(this, token); +} +/** + * @this CompileContext + * @param {Token} token + * @param {string} [protocol] + * @returns {void} + */ + +function anchorFromToken(token, protocol) { + const url = this.sliceSerialize(token); + this.tag(''); + this.raw(this.encode(url)); + this.tag(''); +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +/** @type {HtmlExtension} */ +const gfmStrikethroughHtml = { + enter: { + strikethrough() { + this.tag(''); + } + }, + exit: { + strikethrough() { + this.tag(''); + } + } +}; + +/** + * @typedef {import('micromark-util-types').Extension} Extension + * @typedef {import('micromark-util-types').Resolver} Resolver + * @typedef {import('micromark-util-types').Tokenizer} Tokenizer + * @typedef {import('micromark-util-types').State} State + * @typedef {import('micromark-util-types').Token} Token + * @typedef {import('micromark-util-types').Event} Event + */ + +/** + * @param {Options} [options] + * @returns {Extension} + */ +function gfmStrikethrough(options = {}) { + let single = options.singleTilde; + const tokenizer = { + tokenize: tokenizeStrikethrough, + resolveAll: resolveAllStrikethrough + }; + + if (single === null || single === undefined) { + single = true; + } + + return { + text: { + [126]: tokenizer + }, + insideSpan: { + null: [tokenizer] + }, + attentionMarkers: { + null: [126] + } + } + /** + * Take events and resolve strikethrough. + * + * @type {Resolver} + */ + + function resolveAllStrikethrough(events, context) { + let index = -1; + /** @type {Token} */ + + let strikethrough; + /** @type {Token} */ + + let text; + /** @type {number} */ + + let open; + /** @type {Event[]} */ + + let nextEvents; // Walk through all events. + + while (++index < events.length) { + // Find a token that can close. + if ( + events[index][0] === 'enter' && + events[index][1].type === 'strikethroughSequenceTemporary' && + events[index][1]._close + ) { + open = index; // Now walk back to find an opener. + + while (open--) { + // Find a token that can open the closer. + if ( + events[open][0] === 'exit' && + events[open][1].type === 'strikethroughSequenceTemporary' && + events[open][1]._open && // If the sizes are the same: + events[index][1].end.offset - events[index][1].start.offset === + events[open][1].end.offset - events[open][1].start.offset + ) { + events[index][1].type = 'strikethroughSequence'; + events[open][1].type = 'strikethroughSequence'; + strikethrough = { + type: 'strikethrough', + start: Object.assign({}, events[open][1].start), + end: Object.assign({}, events[index][1].end) + }; + text = { + type: 'strikethroughText', + start: Object.assign({}, events[open][1].end), + end: Object.assign({}, events[index][1].start) + }; // Opening. + + nextEvents = [ + ['enter', strikethrough, context], + ['enter', events[open][1], context], + ['exit', events[open][1], context], + ['enter', text, context] + ]; // Between. + + splice( + nextEvents, + nextEvents.length, + 0, + resolveAll( + context.parser.constructs.insideSpan.null, + events.slice(open + 1, index), + context + ) + ); // Closing. + + splice(nextEvents, nextEvents.length, 0, [ + ['exit', text, context], + ['enter', events[index][1], context], + ['exit', events[index][1], context], + ['exit', strikethrough, context] + ]); + splice(events, open - 1, index - open + 3, nextEvents); + index = open + nextEvents.length - 2; + break + } + } + } + } + + index = -1; + + while (++index < events.length) { + if (events[index][1].type === 'strikethroughSequenceTemporary') { + events[index][1].type = 'data'; + } + } + + return events + } + /** @type {Tokenizer} */ + + function tokenizeStrikethrough(effects, ok, nok) { + const previous = this.previous; + const events = this.events; + let size = 0; + return start + /** @type {State} */ + + function start(code) { + if ( + code !== 126 || + (previous === 126 && + events[events.length - 1][1].type !== 'characterEscape') + ) { + return nok(code) + } + + effects.enter('strikethroughSequenceTemporary'); + return more(code) + } + /** @type {State} */ + + function more(code) { + const before = classifyCharacter(previous); + + if (code === 126) { + // If this is the third marker, exit. + if (size > 1) return nok(code) + effects.consume(code); + size++; + return more + } + + if (size < 2 && !single) return nok(code) + const token = effects.exit('strikethroughSequenceTemporary'); + const after = classifyCharacter(code); + token._open = !after || (after === 2 && Boolean(before)); + token._close = !before || (before === 2 && Boolean(after)); + return ok(code) + } + } +} + +/** + * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension + */ + +/** + * @typedef {import('./syntax.js').Align} Align + */ +const alignment = { + null: '', + left: ' align="left"', + right: ' align="right"', + center: ' align="center"' +}; +/** @type {HtmlExtension} */ + +const gfmTableHtml = { + enter: { + table(token) { + this.lineEndingIfNeeded(); + this.tag('
+16.10.0
16.9.1
16.9.0
16.8.0
@@ -47,6 +46,120 @@ * [io.js](CHANGELOG_IOJS.md) * [Archive](CHANGELOG_ARCHIVE.md) + +## 2021-09-22, Version 16.10.0 (Current), @BethGriggs + +### Notable Changes + +* [[`fb226ff2ee`](https://github.com/nodejs/node/commit/fb226ff2ee)] - **(SEMVER-MINOR)** **crypto**: add rsa-pss keygen parameters (Filip Skokan) [#39927](https://github.com/nodejs/node/pull/39927) +* [[`85206b7311`](https://github.com/nodejs/node/commit/85206b7311)] - **deps**: upgrade npm to 7.24.0 (npm team) [#40167](https://github.com/nodejs/node/pull/40167) +* [[`98f56d179c`](https://github.com/nodejs/node/commit/98f56d179c)] - **deps**: update Acorn to v8.5.0 (Michaël Zasso) [#40015](https://github.com/nodejs/node/pull/40015) +* [[`9655329772`](https://github.com/nodejs/node/commit/9655329772)] - **doc**: add Ayase-252 to collaborators (Qingyu Deng) [#40078](https://github.com/nodejs/node/pull/40078) +* [[`59fff925be`](https://github.com/nodejs/node/commit/59fff925be)] - **(SEMVER-MINOR)** **fs**: make `open` and `close` stream override optional when unused (Antoine du Hamel) [#40013](https://github.com/nodejs/node/pull/40013) +* [[`a63a4bce90`](https://github.com/nodejs/node/commit/a63a4bce90)] - **(SEMVER-MINOR)** **http**: limit requests per connection (Artur K) [#40082](https://github.com/nodejs/node/pull/40082) + * The maximum number of requests a socket can handle before closing keep alive connection can be set with `server.maxRequestsPerSocket`. +* [[`9a672961fa`](https://github.com/nodejs/node/commit/9a672961fa)] - **(SEMVER-MINOR)** **src**: add --no-global-search-paths cli option (Cheng Zhao) [#39754](https://github.com/nodejs/node/pull/39754) + * Adds the `--no-global-search-paths` command-line option to not search modules from global paths like `$HOME/.node_modules` and `$NODE_PATH`. +* [[`fe920b6cbf`](https://github.com/nodejs/node/commit/fe920b6cbf)] - **(SEMVER-MINOR)** **src**: make napi\_create\_reference accept symbol (JckXia) [#39926](https://github.com/nodejs/node/pull/39926) +* [[`97f3072ceb`](https://github.com/nodejs/node/commit/97f3072ceb)] - **(SEMVER-MINOR)** **stream**: add signal support to pipeline generators (Robert Nagy) [#39067](https://github.com/nodejs/node/pull/39067) + +### Commits + +* [[`b7dc651884`](https://github.com/nodejs/node/commit/b7dc651884)] - **build**: run modified internet tests on GitHub Actions (Rich Trott) [#40100](https://github.com/nodejs/node/pull/40100) +* [[`8d5787a043`](https://github.com/nodejs/node/commit/8d5787a043)] - **build**: add .mailmap/AUTHORS to paths-ignore for test-macos (Rich Trott) [#40109](https://github.com/nodejs/node/pull/40109) +* [[`9793e7ff08`](https://github.com/nodejs/node/commit/9793e7ff08)] - **build**: add .mailmap/AUTHORS to path-ignore for test-asan (Rich Trott) [#40109](https://github.com/nodejs/node/pull/40109) +* [[`886921de38`](https://github.com/nodejs/node/commit/886921de38)] - **build**: add paths-ignore for build-tarball workflow (Rich Trott) [#40109](https://github.com/nodejs/node/pull/40109) +* [[`01b1946b38`](https://github.com/nodejs/node/commit/01b1946b38)] - **build**: only lint version numbers for pull requests (Michaël Zasso) [#40027](https://github.com/nodejs/node/pull/40027) +* [[`c804d070a6`](https://github.com/nodejs/node/commit/c804d070a6)] - **build**: add daily/on-demand internet test workflow (Rich Trott) [#40086](https://github.com/nodejs/node/pull/40086) +* [[`7bddaecbf4`](https://github.com/nodejs/node/commit/7bddaecbf4)] - **build**: add YAML linting to GitHub Actions (Rich Trott) [#40007](https://github.com/nodejs/node/pull/40007) +* [[`5a20f9055c`](https://github.com/nodejs/node/commit/5a20f9055c)] - **build**: add YAML linting (Rich Trott) [#40007](https://github.com/nodejs/node/pull/40007) +* [[`0b30867c08`](https://github.com/nodejs/node/commit/0b30867c08)] - **build**: run AUTHORS update weekly (Rich Trott) [#40004](https://github.com/nodejs/node/pull/40004) +* [[`22a78a75ee`](https://github.com/nodejs/node/commit/22a78a75ee)] - **build**: preserves symbols during LTO with macOS linker (Jesse Chan) [#39839](https://github.com/nodejs/node/pull/39839) +* [[`f0dec58d43`](https://github.com/nodejs/node/commit/f0dec58d43)] - **crypto**: fix webcrypto ed(25519|448) spki/pkcs8 import (Filip Skokan) [#40131](https://github.com/nodejs/node/pull/40131) +* [[`d80082f3eb`](https://github.com/nodejs/node/commit/d80082f3eb)] - **crypto**: use `validateObject` (Voltrex) [#39872](https://github.com/nodejs/node/pull/39872) +* [[`d657ae6f8a`](https://github.com/nodejs/node/commit/d657ae6f8a)] - **crypto**: fix RSA-PSS default saltLength (Tobias Nießen) [#39999](https://github.com/nodejs/node/pull/39999) +* [[`fc45cbe7a8`](https://github.com/nodejs/node/commit/fc45cbe7a8)] - **crypto**: fix default MGF1 hash for OpenSSL 3 (Tobias Nießen) [#40031](https://github.com/nodejs/node/pull/40031) +* [[`105c9e6d3b`](https://github.com/nodejs/node/commit/105c9e6d3b)] - **crypto**: check webcrypto asymmetric key types during importKey (Filip Skokan) [#39962](https://github.com/nodejs/node/pull/39962) +* [[`fb226ff2ee`](https://github.com/nodejs/node/commit/fb226ff2ee)] - **(SEMVER-MINOR)** **crypto**: add rsa-pss keygen parameters (Filip Skokan) [#39927](https://github.com/nodejs/node/pull/39927) +* [[`85206b7311`](https://github.com/nodejs/node/commit/85206b7311)] - **deps**: upgrade npm to 7.24.0 (npm team) [#40167](https://github.com/nodejs/node/pull/40167) +* [[`06f6e01f37`](https://github.com/nodejs/node/commit/06f6e01f37)] - **deps**: add riscv64 into openssl Makefile and gen openssl-riscv64 (Lu Yahan) [#40063](https://github.com/nodejs/node/pull/40063) +* [[`9c76c69972`](https://github.com/nodejs/node/commit/9c76c69972)] - **deps**: patch V8 to 9.3.345.19 (Michaël Zasso) [#40108](https://github.com/nodejs/node/pull/40108) +* [[`0df47d5843`](https://github.com/nodejs/node/commit/0df47d5843)] - **deps**: upgrade npm to 7.23.0 (npm team) [#40055](https://github.com/nodejs/node/pull/40055) +* [[`b3843bf417`](https://github.com/nodejs/node/commit/b3843bf417)] - **deps**: patch v8 for vs2019 in std17 (Jiawen Geng) [#40060](https://github.com/nodejs/node/pull/40060) +* [[`67759585a0`](https://github.com/nodejs/node/commit/67759585a0)] - **deps**: patch for v8 on windows (Jiawen Geng) [#40010](https://github.com/nodejs/node/pull/40010) +* [[`98f56d179c`](https://github.com/nodejs/node/commit/98f56d179c)] - **deps**: update Acorn to v8.5.0 (Michaël Zasso) [#40015](https://github.com/nodejs/node/pull/40015) +* [[`5c6708582e`](https://github.com/nodejs/node/commit/5c6708582e)] - **dns**: cleanup validation (Voltrex) [#40061](https://github.com/nodejs/node/pull/40061) +* [[`e4825dcfd5`](https://github.com/nodejs/node/commit/e4825dcfd5)] - **doc**: changes default values for fs.read fns (RISHABH BUDHIRAJA) [#39163](https://github.com/nodejs/node/pull/39163) +* [[`0254b4b0d3`](https://github.com/nodejs/node/commit/0254b4b0d3)] - **doc**: fix markdown indentation in lists (Michaël Zasso) [#40142](https://github.com/nodejs/node/pull/40142) +* [[`b6939a3419`](https://github.com/nodejs/node/commit/b6939a3419)] - **doc**: prepare README.md for stricter linting (Rich Trott) [#40137](https://github.com/nodejs/node/pull/40137) +* [[`a07d8444f9`](https://github.com/nodejs/node/commit/a07d8444f9)] - **doc**: fix comma splice (Rich Trott) [#40133](https://github.com/nodejs/node/pull/40133) +* [[`2488bc0c4f`](https://github.com/nodejs/node/commit/2488bc0c4f)] - **doc**: clean up weird notes about reentrancy (Anna Henningsen) [#40107](https://github.com/nodejs/node/pull/40107) +* [[`8b80dcbc30`](https://github.com/nodejs/node/commit/8b80dcbc30)] - **doc**: correct parameters in fs and stream documentation (vipul kumar) [#39984](https://github.com/nodejs/node/pull/39984) +* [[`1ced732078`](https://github.com/nodejs/node/commit/1ced732078)] - **doc**: fix CJS-ESM selector in Safari (Bradley Farias) [#40135](https://github.com/nodejs/node/pull/40135) +* [[`7fdb12739d`](https://github.com/nodejs/node/commit/7fdb12739d)] - **doc**: add timeout.close (Nikita Galkin) [#40036](https://github.com/nodejs/node/pull/40036) +* [[`81cb14bb58`](https://github.com/nodejs/node/commit/81cb14bb58)] - **doc**: clarify that ObjectWrap requires manual cleanup on shutdown (Gerhard Stöbich) [#40074](https://github.com/nodejs/node/pull/40074) +* [[`8aad81dd99`](https://github.com/nodejs/node/commit/8aad81dd99)] - **doc**: add full list of subsystems (FrankQiu) [#39971](https://github.com/nodejs/node/pull/39971) +* [[`9655329772`](https://github.com/nodejs/node/commit/9655329772)] - **doc**: add Ayase-252 to collaborators (Qingyu Deng) [#40078](https://github.com/nodejs/node/pull/40078) +* [[`6d399e11e9`](https://github.com/nodejs/node/commit/6d399e11e9)] - **doc**: fix CCM cipher example in MJS (Tobias Nießen) [#39949](https://github.com/nodejs/node/pull/39949) +* [[`d426ee9b17`](https://github.com/nodejs/node/commit/d426ee9b17)] - **doc**: fix property name 'detail' of performanceEntry (Christian Boehlke) [#40019](https://github.com/nodejs/node/pull/40019) +* [[`846e7e880e`](https://github.com/nodejs/node/commit/846e7e880e)] - **doc**: fix list indentation in corepack.md (Alexey Ten) [#40029](https://github.com/nodejs/node/pull/40029) +* [[`b6dd2ea930`](https://github.com/nodejs/node/commit/b6dd2ea930)] - **doc**: fix missing history version in `fs.md` (Antoine du Hamel) [#39972](https://github.com/nodejs/node/pull/39972) +* [[`f666f5a8d1`](https://github.com/nodejs/node/commit/f666f5a8d1)] - **events**: fix duplicate require which cause performance penalty (wwwzbwcom) [#39892](https://github.com/nodejs/node/pull/39892) +* [[`59fff925be`](https://github.com/nodejs/node/commit/59fff925be)] - **(SEMVER-MINOR)** **fs**: make `open` and `close` stream override optional when unused (Antoine du Hamel) [#40013](https://github.com/nodejs/node/pull/40013) +* [[`a63a4bce90`](https://github.com/nodejs/node/commit/a63a4bce90)] - **(SEMVER-MINOR)** **http**: limit requests per connection (Artur K) [#40082](https://github.com/nodejs/node/pull/40082) +* [[`bc9c2ca6af`](https://github.com/nodejs/node/commit/bc9c2ca6af)] - **http**: remove CRLF variable (shfshanyue) [#40101](https://github.com/nodejs/node/pull/40101) +* [[`dd50b91f77`](https://github.com/nodejs/node/commit/dd50b91f77)] - **lib**: remove useless statement (Maledong) [#39983](https://github.com/nodejs/node/pull/39983) +* [[`608528028c`](https://github.com/nodejs/node/commit/608528028c)] - **lib**: avoid creating a throw away object in `validateObject` (Antoine du Hamel) [#39807](https://github.com/nodejs/node/pull/39807) +* [[`edcfffeaea`](https://github.com/nodejs/node/commit/edcfffeaea)] - **lib**: use standard property names (null) [#39981](https://github.com/nodejs/node/pull/39981) +* [[`640353af86`](https://github.com/nodejs/node/commit/640353af86)] - **lib,repl**: ignore non-canBeRequiredByUsers built-in (Khaidi Chu) [#39942](https://github.com/nodejs/node/pull/39942) +* [[`4444b5c938`](https://github.com/nodejs/node/commit/4444b5c938)] - **meta**: update AUTHORS (Node.js GitHub Bot) [#40148](https://github.com/nodejs/node/pull/40148) +* [[`4993318862`](https://github.com/nodejs/node/commit/4993318862)] - **meta**: update GeoffreyBooth email addresses in AUTHORS and .mailmap (Rich Trott) [#40132](https://github.com/nodejs/node/pull/40132) +* [[`98d42fa1f4`](https://github.com/nodejs/node/commit/98d42fa1f4)] - **meta**: add mailmap entry for LPardue (Rich Trott) [#40129](https://github.com/nodejs/node/pull/40129) +* [[`effdfa91be`](https://github.com/nodejs/node/commit/effdfa91be)] - **meta**: update GeoffreyBooth email address (Geoffrey Booth) [#40102](https://github.com/nodejs/node/pull/40102) +* [[`588257c00a`](https://github.com/nodejs/node/commit/588257c00a)] - **meta**: add .mailmap entry for arcanis (Rich Trott) [#40103](https://github.com/nodejs/node/pull/40103) +* [[`7ee3fbd1e0`](https://github.com/nodejs/node/commit/7ee3fbd1e0)] - **meta**: update AUTHORS (Node.js GitHub Bot) [#40087](https://github.com/nodejs/node/pull/40087) +* [[`2a41530a5e`](https://github.com/nodejs/node/commit/2a41530a5e)] - **meta**: consolidate AUTHORS entry for mikemaccana (Rich Trott) [#40051](https://github.com/nodejs/node/pull/40051) +* [[`a71579b05e`](https://github.com/nodejs/node/commit/a71579b05e)] - **meta**: add more mailmap entries for bajtos (Rich Trott) [#40023](https://github.com/nodejs/node/pull/40023) +* [[`29104f5e64`](https://github.com/nodejs/node/commit/29104f5e64)] - **meta**: consolidate AUTHORS entries for mithunsasidharan (Rich Trott) [#40003](https://github.com/nodejs/node/pull/40003) +* [[`381293f54a`](https://github.com/nodejs/node/commit/381293f54a)] - **meta**: update AUTHORS (Node.js GitHub Bot) [#39957](https://github.com/nodejs/node/pull/39957) +* [[`1eca9bc5b2`](https://github.com/nodejs/node/commit/1eca9bc5b2)] - **module**: support pattern trailers for imports field (Guy Bedford) [#40041](https://github.com/nodejs/node/pull/40041) +* [[`7376edca6d`](https://github.com/nodejs/node/commit/7376edca6d)] - **module**: deprecate trailing slash pattern mappings (Guy Bedford) [#40039](https://github.com/nodejs/node/pull/40039) +* [[`92f182b23d`](https://github.com/nodejs/node/commit/92f182b23d)] - **module**: fix $ pattern replacements (Guy Bedford) [#40044](https://github.com/nodejs/node/pull/40044) +* [[`d6124d8259`](https://github.com/nodejs/node/commit/d6124d8259)] - **repl**: fix top level await with surrogate characters (Mestery) [#39931](https://github.com/nodejs/node/pull/39931) +* [[`9a672961fa`](https://github.com/nodejs/node/commit/9a672961fa)] - **(SEMVER-MINOR)** **src**: add --no-global-search-paths cli option (Cheng Zhao) [#39754](https://github.com/nodejs/node/pull/39754) +* [[`51f9ad4897`](https://github.com/nodejs/node/commit/51f9ad4897)] - **(SEMVER-MINOR)** **src**: add option to disable global search paths (Cheng Zhao) [#39754](https://github.com/nodejs/node/pull/39754) +* [[`95528b284d`](https://github.com/nodejs/node/commit/95528b284d)] - **src**: remove unnecessary comment and add a CHECK in crypto\_tls.cc (Darshan Sen) [#39991](https://github.com/nodejs/node/pull/39991) +* [[`31994fbf8e`](https://github.com/nodejs/node/commit/31994fbf8e)] - **src**: register zlib external references for snapshot (Joyee Cheung) [#40050](https://github.com/nodejs/node/pull/40050) +* [[`cfcd57182b`](https://github.com/nodejs/node/commit/cfcd57182b)] - **src**: fix -Wunreachable-code-return error (Shelley Vohr) [#40034](https://github.com/nodejs/node/pull/40034) +* [[`9f3a015b60`](https://github.com/nodejs/node/commit/9f3a015b60)] - **src**: add option to disable loading native addons (Dominic Elm) [#39977](https://github.com/nodejs/node/pull/39977) +* [[`570bef1710`](https://github.com/nodejs/node/commit/570bef1710)] - ***Revert*** "**src**: skip test\_fatal/test\_threads for Debug builds" (Anna Henningsen) [#39954](https://github.com/nodejs/node/pull/39954) +* [[`842f936e04`](https://github.com/nodejs/node/commit/842f936e04)] - **src**: use Isolate::TryGetCurrent where appropriate (Anna Henningsen) [#39954](https://github.com/nodejs/node/pull/39954) +* [[`fe920b6cbf`](https://github.com/nodejs/node/commit/fe920b6cbf)] - **(SEMVER-MINOR)** **src**: make napi\_create\_reference accept symbol (JckXia) [#39926](https://github.com/nodejs/node/pull/39926) +* [[`73aa4e34ff`](https://github.com/nodejs/node/commit/73aa4e34ff)] - **src**: fix C4805 MSVC warning (Michaël Zasso) [#39998](https://github.com/nodejs/node/pull/39998) +* [[`826eee363c`](https://github.com/nodejs/node/commit/826eee363c)] - **src**: register external references of PipeWrap for snapshot (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`7a17cbfdea`](https://github.com/nodejs/node/commit/7a17cbfdea)] - **src**: register external references of TTYWrap for snapshot (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`00cca48081`](https://github.com/nodejs/node/commit/00cca48081)] - **src**: register external references of TCPWrap for snapshot (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`6095fb07b6`](https://github.com/nodejs/node/commit/6095fb07b6)] - **src**: register external references of SignalWrap for snapshot (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`db75711c5c`](https://github.com/nodejs/node/commit/db75711c5c)] - **src**: register missing process methods external references (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`b4e074c295`](https://github.com/nodejs/node/commit/b4e074c295)] - **src**: register missing stream wrap external references (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`a2c1c3ef64`](https://github.com/nodejs/node/commit/a2c1c3ef64)] - **src**: register external references of BaseObject for snapshot (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`6fdf02523e`](https://github.com/nodejs/node/commit/6fdf02523e)] - **src**: register external references of node-report for snapshot (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`bef78a2f88`](https://github.com/nodejs/node/commit/bef78a2f88)] - **src**: register external references of dtrace for snapshot (Joyee Cheung) [#39961](https://github.com/nodejs/node/pull/39961) +* [[`97f3072ceb`](https://github.com/nodejs/node/commit/97f3072ceb)] - **(SEMVER-MINOR)** **stream**: add signal support to pipeline generators (Robert Nagy) [#39067](https://github.com/nodejs/node/pull/39067) +* [[`6be405bd7b`](https://github.com/nodejs/node/commit/6be405bd7b)] - **test**: fix test-dgram-udp6-link-local-address on Windows (Michaël Zasso) [#40005](https://github.com/nodejs/node/pull/40005) +* [[`ec94bec9a3`](https://github.com/nodejs/node/commit/ec94bec9a3)] - **test**: do not run `test-corepack-yarn-install` with no internet (Antoine du Hamel) [#40090](https://github.com/nodejs/node/pull/40090) +* [[`4aa2610252`](https://github.com/nodejs/node/commit/4aa2610252)] - **test**: update OpenSSL3 error messages for 3.0.0+quic (Daniel Bevenius) [#40093](https://github.com/nodejs/node/pull/40093) +* [[`4367a61a9b`](https://github.com/nodejs/node/commit/4367a61a9b)] - **test**: mark test-crypto-timing-safe-equal-benchmarks flaky (Richard Lau) [#40065](https://github.com/nodejs/node/pull/40065) +* [[`5b5e27281c`](https://github.com/nodejs/node/commit/5b5e27281c)] - **test**: fix internet/test-dns (Rich Trott) [#40083](https://github.com/nodejs/node/pull/40083) +* [[`67bbfeb7e1`](https://github.com/nodejs/node/commit/67bbfeb7e1)] - **test**: make tests pass on Windows with Unix EOL (Michaël Zasso) [#40002](https://github.com/nodejs/node/pull/40002) +* [[`a8c99d9f09`](https://github.com/nodejs/node/commit/a8c99d9f09)] - **tools**: update doc generator dependencies (Michaël Zasso) [#40042](https://github.com/nodejs/node/pull/40042) +* [[`ec6de1195a`](https://github.com/nodejs/node/commit/ec6de1195a)] - **tools**: update ansi-regex in lint-md rollup (Rich Trott) [#40112](https://github.com/nodejs/node/pull/40112) +* [[`d55804ca4e`](https://github.com/nodejs/node/commit/d55804ca4e)] - **tools**: update all dependencies of markdown linter (Michaël Zasso) [#40035](https://github.com/nodejs/node/pull/40035) +* [[`f03bae7c82`](https://github.com/nodejs/node/commit/f03bae7c82)] - **tools**: update remark-html to v13.0.2 (Michaël Zasso) [#40043](https://github.com/nodejs/node/pull/40043) +* [[`99af21292f`](https://github.com/nodejs/node/commit/99af21292f)] - **tools,build**: update YAML files in preparation for linting (Rich Trott) [#40007](https://github.com/nodejs/node/pull/40007) +* [[`590ace418d`](https://github.com/nodejs/node/commit/590ace418d)] - **tools,doc**: fix misrendering of consecutive JS blocks (Rich Trott) [#40146](https://github.com/nodejs/node/pull/40146) +* [[`5983568204`](https://github.com/nodejs/node/commit/5983568204)] - **worker**: avoid potential deadlock on NearHeapLimit (Santiago Gimeno) [#38403](https://github.com/nodejs/node/pull/38403) + ## 2021-09-10, Version 16.9.1 (Current), @richardlau diff --git a/doc/changelogs/CHANGELOG_V4.md b/doc/changelogs/CHANGELOG_V4.md index 089bc23f9d5125..757420beda9d9a 100644 --- a/doc/changelogs/CHANGELOG_V4.md +++ b/doc/changelogs/CHANGELOG_V4.md @@ -1,8 +1,6 @@ # Node.js 4 ChangeLog - - - + diff --git a/doc/changelogs/CHANGELOG_V5.md b/doc/changelogs/CHANGELOG_V5.md index 79c92d09418fca..52dabcb46c353e 100644 --- a/doc/changelogs/CHANGELOG_V5.md +++ b/doc/changelogs/CHANGELOG_V5.md @@ -1,8 +1,6 @@ # Node.js 5 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index 68d243d03f6707..1ed801efc0d793 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -1,8 +1,6 @@ # Node.js 6 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V7.md b/doc/changelogs/CHANGELOG_V7.md index 9f5581129c1fc6..d32d2451ff4505 100644 --- a/doc/changelogs/CHANGELOG_V7.md +++ b/doc/changelogs/CHANGELOG_V7.md @@ -1,8 +1,6 @@ # Node.js 7 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V8.md b/doc/changelogs/CHANGELOG_V8.md index f64372f41b44e3..ab474c998259db 100644 --- a/doc/changelogs/CHANGELOG_V8.md +++ b/doc/changelogs/CHANGELOG_V8.md @@ -1,8 +1,6 @@ # Node.js 8 ChangeLog - - - +
diff --git a/doc/changelogs/CHANGELOG_V9.md b/doc/changelogs/CHANGELOG_V9.md index 6721296dd422d9..c08ea38714ecf9 100644 --- a/doc/changelogs/CHANGELOG_V9.md +++ b/doc/changelogs/CHANGELOG_V9.md @@ -1,8 +1,6 @@ # Node.js 9 ChangeLog - - - +
diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml index 9f209505db9c33..90715e4ea37d69 100644 --- a/lib/.eslintrc.yaml +++ b/lib/.eslintrc.yaml @@ -6,7 +6,7 @@ rules: no-buffer-constructor: error no-mixed-operators: - error - - groups: [[ "&&", "||" ]] + - groups: [["&&", "||"]] no-restricted-syntax: # Config copied from .eslintrc.js - error diff --git a/lib/_http_server.js b/lib/_http_server.js index 2221b132f4d29c..045e0b2f719717 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -394,7 +394,7 @@ function Server(options, requestListener) { this.timeout = 0; this.keepAliveTimeout = 5000; this.maxHeadersCount = null; - this.maxRequestsPerSocket = null; + this.maxRequestsPerSocket = 0; this.headersTimeout = 60 * 1000; // 60 seconds this.requestTimeout = 0; } @@ -908,13 +908,18 @@ function parserOnIncoming(server, socket, state, req, keepAlive) { let handled = false; if (req.httpVersionMajor === 1 && req.httpVersionMinor === 1) { - if (typeof server.maxRequestsPerSocket === 'number') { + const isRequestsLimitSet = ( + typeof server.maxRequestsPerSocket === 'number' && + server.maxRequestsPerSocket > 0 + ); + + if (isRequestsLimitSet) { state.requestsCount++; res.maxRequestsOnConnectionReached = ( server.maxRequestsPerSocket <= state.requestsCount); } - if (typeof server.maxRequestsPerSocket === 'number' && + if (isRequestsLimitSet && (server.maxRequestsPerSocket < state.requestsCount)) { handled = true; diff --git a/lib/internal/console/constructor.js b/lib/internal/console/constructor.js index 22b84e5e42b956..92c6d7293350ed 100644 --- a/lib/internal/console/constructor.js +++ b/lib/internal/console/constructor.js @@ -42,12 +42,15 @@ const { isStackOverflowError, codes: { ERR_CONSOLE_WRITABLE_STREAM, - ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_INCOMPATIBLE_OPTION_PAIR, }, } = require('internal/errors'); -const { validateInteger } = require('internal/validators'); +const { + validateArray, + validateInteger, + validateObject, +} = require('internal/validators'); const { previewEntries } = internalBinding('util'); const { Buffer: { isBuffer } } = require('buffer'); const { @@ -58,18 +61,14 @@ const { isTypedArray, isSet, isMap, isSetIterator, isMapIterator, } = require('internal/util/types'); const { - CHAR_LOWERCASE_B, - CHAR_LOWERCASE_E, - CHAR_LOWERCASE_N, - CHAR_UPPERCASE_C, + CHAR_LOWERCASE_B: kTraceBegin, + CHAR_LOWERCASE_E: kTraceEnd, + CHAR_LOWERCASE_N: kTraceInstant, + CHAR_UPPERCASE_C: kTraceCount, } = require('internal/constants'); const kCounts = Symbol('counts'); const kTraceConsoleCategory = 'node,node.console'; -const kTraceCount = CHAR_UPPERCASE_C; -const kTraceBegin = CHAR_LOWERCASE_B; -const kTraceEnd = CHAR_LOWERCASE_E; -const kTraceInstant = CHAR_LOWERCASE_N; const kSecond = 1000; const kMinute = 60 * kSecond; @@ -136,18 +135,15 @@ function Console(options /* or: stdout, stderr, ignoreErrors = true */) { 0, kMaxGroupIndentation); } - if (typeof inspectOptions === 'object' && inspectOptions !== null) { + if (inspectOptions !== undefined) { + validateObject(inspectOptions, 'options.inspectOptions'); + if (inspectOptions.colors !== undefined && options.colorMode !== undefined) { throw new ERR_INCOMPATIBLE_OPTION_PAIR( 'options.inspectOptions.color', 'colorMode'); } optionsMap.set(this, inspectOptions); - } else if (inspectOptions !== undefined) { - throw new ERR_INVALID_ARG_TYPE( - 'options.inspectOptions', - 'object', - inspectOptions); } // Bind the prototype functions to this Console instance @@ -483,8 +479,8 @@ const consoleMethods = { // https://console.spec.whatwg.org/#table table(tabularData, properties) { - if (properties !== undefined && !ArrayIsArray(properties)) - throw new ERR_INVALID_ARG_TYPE('properties', 'Array', properties); + if (properties !== undefined) + validateArray(properties, 'properties'); if (tabularData === null || typeof tabularData !== 'object') return this.log(tabularData); diff --git a/lib/internal/crypto/ec.js b/lib/internal/crypto/ec.js index 76c6b306cf25a3..c684d6c66af26a 100644 --- a/lib/internal/crypto/ec.js +++ b/lib/internal/crypto/ec.js @@ -122,13 +122,12 @@ function createECRawKey(namedCurve, keyData, isPublic) { break; } - if (isPublic) { - handle.initEDRaw(namedCurve, keyData, kKeyTypePublic); - return new PublicKeyObject(handle); + const keyType = isPublic ? kKeyTypePublic : kKeyTypePrivate; + if (!handle.initEDRaw(namedCurve, keyData, keyType)) { + throw lazyDOMException('Failure to generate key object'); } - handle.initEDRaw(namedCurve, keyData, kKeyTypePrivate); - return new PrivateKeyObject(handle); + return isPublic ? new PublicKeyObject(handle) : new PrivateKeyObject(handle); } async function ecGenerateKey(algorithm, extractable, keyUsages) { diff --git a/lib/internal/crypto/keys.js b/lib/internal/crypto/keys.js index ce053fbb4b800a..ea2ecc262ed665 100644 --- a/lib/internal/crypto/keys.js +++ b/lib/internal/crypto/keys.js @@ -435,16 +435,10 @@ function getKeyObjectHandleFromJwk(key, ctx) { } const handle = new KeyObjectHandle(); - if (isPublic) { - handle.initEDRaw( - `NODE-${key.crv.toUpperCase()}`, - keyData, - kKeyTypePublic); - } else { - handle.initEDRaw( - `NODE-${key.crv.toUpperCase()}`, - keyData, - kKeyTypePrivate); + + const keyType = isPublic ? kKeyTypePublic : kKeyTypePrivate; + if (!handle.initEDRaw(`NODE-${key.crv.toUpperCase()}`, keyData, keyType)) { + throw new ERR_CRYPTO_INVALID_JWK(); } return handle; diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index c45d53c796d26a..8812120091f930 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -102,7 +102,7 @@ function randomBytes(size, callback) { // Keep the callback as a regular function so this is propagated. randomFill(buf.buffer, 0, size, function(error) { - if (error) FunctionPrototypeCall(callback, this, error); + if (error) return FunctionPrototypeCall(callback, this, error); FunctionPrototypeCall(callback, this, null, buf); }); } diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 84431fe811d9fc..755f1b2b86176d 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -1459,8 +1459,8 @@ E('ERR_REQUIRE_ESM', return msg; } const path = require('path'); - const basename = path.basename(filename) === path.basename(parentPath) ? - filename : path.basename(filename); + const basename = parentPath && path.basename(filename) === + path.basename(parentPath) ? filename : path.basename(filename); if (hasEsmSyntax) { msg += `\nInstead change the require of ${basename} in ${parentPath} to` + ' a dynamic import() which is available in all CommonJS modules.'; diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 03b2540878c625..ddab605c8a3c6a 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -521,8 +521,11 @@ class EventTarget { } const root = this[kEvents].get(type); - if (root === undefined || root.next === undefined) + if (root === undefined || root.next === undefined) { + if (event !== undefined) + event[kIsBeingDispatched] = false; return true; + } let handler = root.next; let next; diff --git a/lib/internal/fs/promises.js b/lib/internal/fs/promises.js index e26f1314d155de..b9c3b7cb407159 100644 --- a/lib/internal/fs/promises.js +++ b/lib/internal/fs/promises.js @@ -115,6 +115,12 @@ function lazyLoadCpPromises() { return cpPromises ??= require('internal/fs/cp/cp').cpFn; } +// Lazy loaded to avoid circular dependency. +let fsStreams; +function lazyFsStreams() { + return fsStreams ??= require('internal/fs/streams'); +} + class FileHandle extends EventEmitterMixin(JSTransferable) { /** * @param {InternalFSBinding.FileHandle | undefined} filehandle @@ -252,6 +258,40 @@ class FileHandle extends EventEmitterMixin(JSTransferable) { return readable; } + /** + * @typedef {import('./streams').ReadStream + * } ReadStream + * @param {{ + * encoding?: string; + * autoClose?: boolean; + * emitClose?: boolean; + * start: number; + * end?: number; + * highWaterMark?: number; + * }} [options] + * @returns {ReadStream} + */ + createReadStream(options = undefined) { + const { ReadStream } = lazyFsStreams(); + return new ReadStream(undefined, { ...options, fd: this }); + } + + /** + * @typedef {import('./streams').WriteStream + * } WriteStream + * @param {{ + * encoding?: string; + * autoClose?: boolean; + * emitClose?: boolean; + * start: number; + * }} [options] + * @returns {WriteStream} + */ + createWriteStream(options = undefined) { + const { WriteStream } = lazyFsStreams(); + return new WriteStream(undefined, { ...options, fd: this }); + } + [kTransfer]() { if (this[kClosePromise] || this[kRefs] > 1) { throw lazyDOMException('Cannot transfer FileHandle while in use', diff --git a/lib/internal/modules/cjs/loader.js b/lib/internal/modules/cjs/loader.js index b8eff0440624a4..622805ea78fd0c 100644 --- a/lib/internal/modules/cjs/loader.js +++ b/lib/internal/modules/cjs/loader.js @@ -457,7 +457,7 @@ function trySelf(parentPath, request) { try { return finalizeEsmResolution(packageExportsResolve( pathToFileURL(pkgPath + '/package.json'), expansion, pkg, - pathToFileURL(parentPath), cjsConditions), request, parentPath, pkgPath); + pathToFileURL(parentPath), cjsConditions), parentPath, pkgPath); } catch (e) { if (e.code === 'ERR_MODULE_NOT_FOUND') throw createEsmNotFoundErr(request, pkgPath + '/package.json'); @@ -481,7 +481,7 @@ function resolveExports(nmPath, request) { try { return finalizeEsmResolution(packageExportsResolve( pathToFileURL(pkgPath + '/package.json'), '.' + expansion, pkg, null, - cjsConditions), request, null, pkgPath); + cjsConditions), null, pkgPath); } catch (e) { if (e.code === 'ERR_MODULE_NOT_FOUND') throw createEsmNotFoundErr(request, pkgPath + '/package.json'); @@ -894,7 +894,7 @@ Module._resolveFilename = function(request, parent, isMain, options) { try { return finalizeEsmResolution( packageImportsResolve(request, pathToFileURL(parent.filename), - cjsConditions), request, parent.filename, + cjsConditions), parent.filename, pkg.path); } catch (e) { if (e.code === 'ERR_MODULE_NOT_FOUND') @@ -936,18 +936,12 @@ Module._resolveFilename = function(request, parent, isMain, options) { throw err; }; -function finalizeEsmResolution(match, request, parentPath, pkgPath) { - const { resolved, exact } = match; +function finalizeEsmResolution(resolved, parentPath, pkgPath) { if (RegExpPrototypeTest(encodedSepRegEx, resolved)) throw new ERR_INVALID_MODULE_SPECIFIER( resolved, 'must not include encoded "/" or "\\" characters', parentPath); const filename = fileURLToPath(resolved); - let actual = tryFile(filename); - if (!exact && !actual) { - const exts = ObjectKeys(Module._extensions); - actual = tryExtensions(filename, exts, false) || - tryPackage(filename, exts, false, request); - } + const actual = tryFile(filename); if (actual) return actual; const err = createEsmNotFoundErr(filename, diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js index dcb7d10a47961a..1a28f994ec612c 100644 --- a/lib/internal/modules/esm/resolve.js +++ b/lib/internal/modules/esm/resolve.js @@ -19,6 +19,7 @@ const { StringPrototypeIncludes, StringPrototypeIndexOf, StringPrototypeLastIndexOf, + StringPrototypeReplace, StringPrototypeSlice, StringPrototypeSplit, StringPrototypeStartsWith, @@ -82,38 +83,15 @@ const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS); const emittedPackageWarnings = new SafeSet(); -/** - * @param {string} match - * @param {URL} pjsonUrl - * @param {boolean} isExports - * @param {string | URL | undefined} base - * @returns {void} - */ -function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) { +function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) { const pjsonPath = fileURLToPath(pjsonUrl); - if (emittedPackageWarnings.has(pjsonPath + '|' + match)) return; emittedPackageWarnings.add(pjsonPath + '|' + match); process.emitWarning( - `Use of deprecated folder mapping "${match}" in the ${isExports ? - '"exports"' : '"imports"'} field module resolution of the package at ${ - pjsonPath}${base ? ` imported from ${fileURLToPath(base)}` : ''}.\n` + - `Update this package.json to use a subpath pattern like "${match}*".`, - 'DeprecationWarning', - 'DEP0148' - ); -} - -function emitTrailingSlashPatternDeprecation(match, pjsonUrl, isExports, base) { - const pjsonPath = fileURLToPath(pjsonUrl); - if (emittedPackageWarnings.has(pjsonPath + '|' + match)) - return; - emittedPackageWarnings.add(pjsonPath + '|' + match); - process.emitWarning( - `Use of deprecated trailing slash pattern mapping "${match}" in the ${ - isExports ? '"exports"' : '"imports"'} field module resolution of the ` + - `package at ${pjsonPath}${base ? ` imported from ${fileURLToPath(base)}` : + `Use of deprecated trailing slash pattern mapping "${match}" in the ` + + `"exports" field module resolution of the package at ${pjsonPath}${ + base ? ` imported from ${fileURLToPath(base)}` : ''}. Mapping specifiers ending in "/" is no longer supported.`, 'DeprecationWarning', 'DEP0155' @@ -504,8 +482,11 @@ function resolvePackageTargetString( if (subpath === '') return resolved; - if (RegExpPrototypeTest(invalidSegmentRegEx, subpath)) - throwInvalidSubpath(match + subpath, packageJSONUrl, internal, base); + if (RegExpPrototypeTest(invalidSegmentRegEx, subpath)) { + const request = pattern ? + StringPrototypeReplace(match, '*', () => subpath) : match + subpath; + throwInvalidSubpath(request, packageJSONUrl, internal, base); + } if (pattern) return new URL(RegExpPrototypeSymbolReplace(patternRegEx, resolved.href, @@ -641,7 +622,7 @@ function packageExportsResolve( ); if (resolved === null || resolved === undefined) throwExportsNotFound(packageSubpath, packageJSONUrl, base); - return { resolved, exact: true }; + return resolved; } let bestMatch = ''; @@ -653,9 +634,15 @@ function packageExportsResolve( if (patternIndex !== -1 && StringPrototypeStartsWith(packageSubpath, StringPrototypeSlice(key, 0, patternIndex))) { + // When this reaches EOL, this can throw at the top of the whole function: + // + // if (StringPrototypeEndsWith(packageSubpath, '/')) + // throwInvalidSubpath(packageSubpath) + // + // To match "imports" and the spec. if (StringPrototypeEndsWith(packageSubpath, '/')) emitTrailingSlashPatternDeprecation(packageSubpath, packageJSONUrl, - true, base); + base); const patternTrailer = StringPrototypeSlice(key, patternIndex + 1); if (packageSubpath.length >= key.length && StringPrototypeEndsWith(packageSubpath, patternTrailer) && @@ -666,25 +653,17 @@ function packageExportsResolve( packageSubpath, patternIndex, packageSubpath.length - patternTrailer.length); } - } else if (key[key.length - 1] === '/' && - StringPrototypeStartsWith(packageSubpath, key) && - patternKeyCompare(bestMatch, key) === 1) { - bestMatch = key; - bestMatchSubpath = StringPrototypeSlice(packageSubpath, key.length); } } if (bestMatch) { const target = exports[bestMatch]; - const pattern = StringPrototypeIncludes(bestMatch, '*'); const resolved = resolvePackageTarget(packageJSONUrl, target, bestMatchSubpath, bestMatch, base, - pattern, false, conditions); + true, false, conditions); if (resolved === null || resolved === undefined) throwExportsNotFound(packageSubpath, packageJSONUrl, base); - if (!pattern) - emitFolderMapDeprecation(bestMatch, packageJSONUrl, true, base); - return { resolved, exact: pattern }; + return resolved; } throwExportsNotFound(packageSubpath, packageJSONUrl, base); @@ -711,7 +690,8 @@ function patternKeyCompare(a, b) { * @returns */ function packageImportsResolve(name, base, conditions) { - if (name === '#' || StringPrototypeStartsWith(name, '#/')) { + if (name === '#' || StringPrototypeStartsWith(name, '#/') || + StringPrototypeEndsWith(name, '/')) { const reason = 'is not a valid internal imports specifier name'; throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base)); } @@ -722,13 +702,12 @@ function packageImportsResolve(name, base, conditions) { const imports = packageConfig.imports; if (imports) { if (ObjectPrototypeHasOwnProperty(imports, name) && - !StringPrototypeIncludes(name, '*') && - !StringPrototypeEndsWith(name, '/')) { + !StringPrototypeIncludes(name, '*')) { const resolved = resolvePackageTarget( packageJSONUrl, imports[name], '', name, base, false, true, conditions ); - if (resolved !== null) - return { resolved, exact: true }; + if (resolved !== null && resolved !== undefined) + return resolved; } else { let bestMatch = ''; let bestMatchSubpath; @@ -749,26 +728,16 @@ function packageImportsResolve(name, base, conditions) { bestMatchSubpath = StringPrototypeSlice( name, patternIndex, name.length - patternTrailer.length); } - } else if (key[key.length - 1] === '/' && - StringPrototypeStartsWith(name, key) && - patternKeyCompare(bestMatch, key) === 1) { - bestMatch = key; - bestMatchSubpath = StringPrototypeSlice(name, key.length); } } if (bestMatch) { const target = imports[bestMatch]; - const pattern = StringPrototypeIncludes(bestMatch, '*'); const resolved = resolvePackageTarget(packageJSONUrl, target, bestMatchSubpath, bestMatch, - base, pattern, true, - conditions); - if (resolved !== null) { - if (!pattern) - emitFolderMapDeprecation(bestMatch, packageJSONUrl, false, base); - return { resolved, exact: pattern }; - } + base, true, true, conditions); + if (resolved !== null && resolved !== undefined) + return resolved; } } } @@ -845,7 +814,7 @@ function packageResolve(specifier, base, conditions) { packageConfig.exports !== undefined && packageConfig.exports !== null) { return packageExportsResolve( packageJSONUrl, packageSubpath, packageConfig, base, conditions - ).resolved; + ); } } @@ -870,7 +839,7 @@ function packageResolve(specifier, base, conditions) { if (packageConfig.exports !== undefined && packageConfig.exports !== null) return packageExportsResolve( packageJSONUrl, packageSubpath, packageConfig, base, conditions - ).resolved; + ); if (packageSubpath === '.') return legacyMainResolve(packageJSONUrl, packageConfig, base); return new URL(packageSubpath, packageJSONUrl); @@ -919,7 +888,7 @@ function moduleResolve(specifier, base, conditions) { if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { resolved = new URL(specifier, base); } else if (specifier[0] === '#') { - ({ resolved } = packageImportsResolve(specifier, base, conditions)); + resolved = packageImportsResolve(specifier, base, conditions); } else { try { resolved = new URL(specifier); diff --git a/lib/internal/repl/await.js b/lib/internal/repl/await.js index ba138fdfe8c8d9..ec1d0c8823e107 100644 --- a/lib/internal/repl/await.js +++ b/lib/internal/repl/await.js @@ -221,22 +221,26 @@ function processTopLevelAwait(src) { return null; } - const last = body.body[body.body.length - 1]; - if (last.type === 'ExpressionStatement') { - // For an expression statement of the form - // ( expr ) ; - // ^^^^^^^^^^ // last - // ^^^^ // last.expression - // - // We do not want the left parenthesis before the `return` keyword; - // therefore we prepend the `return (` to `last`. - // - // On the other hand, we do not want the right parenthesis after the - // semicolon. Since there can only be more right parentheses between - // last.expression.end and the semicolon, appending one more to - // last.expression should be fine. - state.prepend(last, 'return ('); - state.append(last.expression, ')'); + for (let i = body.body.length - 1; i >= 0; i--) { + const node = body.body[i]; + if (node.type === 'EmptyStatement') continue; + if (node.type === 'ExpressionStatement') { + // For an expression statement of the form + // ( expr ) ; + // ^^^^^^^^^^ // node + // ^^^^ // node.expression + // + // We do not want the left parenthesis before the `return` keyword; + // therefore we prepend the `return (` to `node`. + // + // On the other hand, we do not want the right parenthesis after the + // semicolon. Since there can only be more right parentheses between + // node.expression.end and the semicolon, appending one more to + // node.expression should be fine. + state.prepend(node, 'return ('); + state.append(node.expression, ')'); + } + break; } return ( diff --git a/lib/internal/util.js b/lib/internal/util.js index 34c210f27d7f7a..9a8139cdae34b4 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -28,10 +28,6 @@ const { SymbolFor, } = primordials; -const { - toUSVString: _toUSVString, -} = internalBinding('url'); - const { hideStackFrames, codes: { @@ -47,7 +43,8 @@ const { setHiddenValue, arrow_message_private_symbol: kArrowMessagePrivateSymbolIndex, decorated_private_symbol: kDecoratedPrivateSymbolIndex, - sleep: _sleep + sleep: _sleep, + toUSVString: _toUSVString, } = internalBinding('util'); const { isNativeError } = internalBinding('types'); diff --git a/lib/internal/worker.js b/lib/internal/worker.js index d59399bfefed10..1d2cd8cefd2996 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -1,7 +1,6 @@ 'use strict'; const { - ArrayIsArray, ArrayPrototypeForEach, ArrayPrototypeMap, ArrayPrototypePush, @@ -122,11 +121,9 @@ class Worker extends EventEmitter { constructor(filename, options = {}) { super(); debug(`[${threadId}] create new worker`, filename, options); - if (options.execArgv && !ArrayIsArray(options.execArgv)) { - throw new ERR_INVALID_ARG_TYPE('options.execArgv', - 'Array', - options.execArgv); - } + if (options.execArgv) + validateArray(options.execArgv, 'options.execArgv'); + let argv; if (options.argv) { validateArray(options.argv, 'options.argv'); diff --git a/onboarding.md b/onboarding.md index ae65f07f37b621..d74600dcce0061 100644 --- a/onboarding.md +++ b/onboarding.md @@ -51,12 +51,13 @@ onboarding session. [Publicizing or hiding organization membership][]. * Notifications: - * Use [https://github.com/notifications](https://github.com/notifications) or + * Use or set up email * Watching the main repository will flood your inbox (several hundred notifications on typical weekdays), so be prepared The project has two venues for real-time discussion: + * [`#nodejs-dev`](https://openjs-foundation.slack.com/archives/C019Y2T6STH) on the [OpenJS Foundation](https://slack-invite.openjsf.org/) @@ -71,7 +72,7 @@ The project has two venues for real-time discussion: * The best outcome is for people who come to our issue tracker to feel like they can come back again. -* You are expected to follow *and* hold others accountable to the +* You are expected to follow _and_ hold others accountable to the [Code of Conduct][]. ## Managing the issue tracker @@ -88,7 +89,7 @@ The project has two venues for real-time discussion: not perfect, of course. Feel free to apply relevant labels and remove irrelevant labels from pull requests and issues. * `semver-{minor,major}`: - * If a change has the remote *chance* of breaking something, use the + * If a change has the remote _chance_ of breaking something, use the `semver-major` label * When adding a `semver-*` label, add a comment explaining why you're adding it. Do it right away so you don't forget! @@ -113,20 +114,26 @@ The project has two venues for real-time discussion: ## Reviewing pull requests * The primary goal is for the codebase to improve. + * Secondary (but not far off) is for the person submitting code to succeed. A pull request from a new contributor is an opportunity to grow the community. + * Review a bit at a time. Do not overwhelm new contributors. * It is tempting to micro-optimize. Don't succumb to that temptation. We change V8 often. Techniques that provide improved performance today may be unnecessary in the future. + * Be aware: Your opinion carries a lot of weight! + * Nits (requests for small changes that are not essential) are fine, but try to avoid stalling the pull request. * Identify them as nits when you comment: `Nit: change foo() to bar().` * If they are stalling the pull request, fix them yourself on merge. + * Insofar as possible, issues should be identified by tools rather than human reviewers. If you are leaving comments about issues that could be identified by tools but are not, consider implementing the necessary tooling. + * Minimum wait for comments time * There is a minimum waiting time which we try to respect for non-trivial changes so that people who may have important input in such a distributed @@ -134,6 +141,7 @@ The project has two venues for real-time discussion: * For non-trivial changes, leave the pull request open for at least 48 hours. * If a pull request is abandoned, check if they'd mind if you took it over (especially if it just has nits left). + * Approving a change * Collaborators indicate that they have reviewed and approve of the changes in a pull request using GitHub’s approval interface @@ -159,7 +167,7 @@ The project has two venues for real-time discussion: such as `async_hooks`. * Continuous Integration (CI) Testing: - * [https://ci.nodejs.org/](https://ci.nodejs.org/) + * * It is not automatically run. You need to start it manually. * Log in on CI is integrated with GitHub. Try to log in now! * You will be using `node-test-pull-request` most of the time. Go there now! @@ -228,12 +236,12 @@ needs to be pointed out separately during the onboarding. * Almost any mistake you could make can be fixed or reverted. * The existing collaborators trust you and are grateful for your help! * Other repositories: - * [https://github.com/nodejs/TSC](https://github.com/nodejs/TSC) - * [https://github.com/nodejs/build](https://github.com/nodejs/build) - * [https://github.com/nodejs/nodejs.org](https://github.com/nodejs/nodejs.org) - * [https://github.com/nodejs/readable-stream](https://github.com/nodejs/readable-stream) - * [https://github.com/nodejs/LTS](https://github.com/nodejs/LTS) - * [https://github.com/nodejs/citgm](https://github.com/nodejs/citgm) + * + * + * + * + * + * * The OpenJS Foundation hosts regular summits for active contributors to the Node.js project, where we have face-to-face discussions about our work on the project. The Foundation has travel funds to cover participants' expenses diff --git a/src/README.md b/src/README.md index 91b9f3817a36b0..25c63e2f8cc3e5 100644 --- a/src/README.md +++ b/src/README.md @@ -68,6 +68,7 @@ A number of concepts are involved in putting together Node.js on top of V8 and libuv. This section aims to explain some of them and how they work together. + ### `Isolate` The `v8::Isolate` class represents a single JavaScript engine instance, in @@ -102,6 +103,7 @@ subclasses such as `v8::Number` (which in turn has subclasses like `v8::Int32`), of `v8::Object`, e.g. `v8::Uint8Array` or `v8::Date`. + ### Internal fields V8 provides the ability to store data in so-called “internal fields” inside @@ -128,12 +130,14 @@ Typical ways of working with internal fields are: [`Context`][]s provide the same feature under the name “embedder data”. + ### JavaScript value handles All JavaScript values are accessed through the V8 API through so-called handles, of which there are two types: [`Local`][]s and [`Global`][]s. + #### `Local` handles A `v8::Local` handle is a temporary pointer to a JavaScript object, where @@ -210,6 +214,7 @@ any functions that are called from the event loop and want to run or access JavaScript code to create `HandleScope`s. + #### `Global` handles A `v8::Global` handle (sometimes also referred to by the name of its parent @@ -246,6 +251,7 @@ the `v8::Eternal` itself is destroyed at some point. This type of handle is rarely used. + ### `Context` JavaScript allows multiple global objects and sets of built-in JavaScript @@ -270,6 +276,7 @@ Typical ways of accessing the current `Context` in the Node.js code are: main context. + ### Event loop The main abstraction for an event loop inside Node.js is the `uv_loop_t` struct. @@ -284,6 +291,7 @@ could restructure Node.js to provide e.g. the ability to run parts of Node.js inside an event loop separate from the active thread’s event loop. + ### `Environment` Node.js instances are represented by the `Environment` class. @@ -315,6 +323,7 @@ Typical ways of accessing the current `Environment` in the Node.js code are: up the current [`Context`][] and then uses that. + ### `IsolateData` Every Node.js instance ([`Environment`][]) is associated with one `IsolateData` @@ -346,6 +355,7 @@ The platform can be accessed through `isolate_data->platform()` given an and who passed this to Node.js. + ### Binding functions C++ functions exposed to JS follow a specific signature. The following example @@ -463,6 +473,7 @@ Which explains that the unregistered external reference is `node::util::GetHiddenValue` defined in `node_util.cc`. + #### Per-binding state Some internal bindings, such as the HTTP parser, maintain internal state that @@ -519,6 +530,7 @@ of `SnapshotableObject` on how to implement its serialization and deserialization. + ### Exception handling The V8 engine provides multiple features to work with JavaScript exceptions, @@ -554,7 +566,7 @@ The most common reasons for this are: * Calls to functions like `object->Get(...)` or `object->Set(...)` may fail on most objects, if the `Object.prototype` object has been modified from userland code that added getters or setters. -* Calls that invoke *any* JavaScript code, including JavaScript code that is +* Calls that invoke _any_ JavaScript code, including JavaScript code that is provided from Node.js internals or V8 internals, will fail when JavaScript execution is being terminated. This typically happens inside Workers when `worker.terminate()` is called, but it can also affect the main thread when @@ -661,6 +673,7 @@ and the exception object will not be a meaningful JavaScript value. `try_catch.ReThrow()` should not be used in this case. + ### libuv handles and requests Two central concepts when working with libuv are handles and requests. @@ -682,6 +695,7 @@ When a Node.js [`Environment`][] is destroyed, it generally needs to clean up any resources owned by it, e.g. memory or libuv requests/handles. + #### Cleanup hooks Cleanup hooks are provided that run before the [`Environment`][] @@ -690,7 +704,7 @@ is destroyed. They can be added and removed through by using `env->RemoveCleanupHook(callback, hint);`, where callback takes a `void* hint` argument. -Inside these cleanup hooks, new asynchronous operations *may* be started on the +Inside these cleanup hooks, new asynchronous operations _may_ be started on the event loop, although ideally that is avoided as much as possible. Every [`BaseObject`][] has its own cleanup hook that deletes it. For @@ -742,6 +756,7 @@ This can be useful for debugging memory leaks. The [`memory_tracker.h`][] header file explains how to use this class. + ### `BaseObject` A frequently recurring situation is that a JavaScript object and a C++ object @@ -819,6 +834,7 @@ called. This can be useful when one `BaseObject` fully owns another `BaseObject`. + ### `AsyncWrap` `AsyncWrap` is a subclass of `BaseObject` that additionally provides tracking @@ -837,6 +853,7 @@ See the [`async_hooks` module][] documentation for more information about how this information is provided to async tracking tools. + #### `MakeCallback` The `AsyncWrap` class has a set of methods called `MakeCallback()`, with the @@ -876,6 +893,7 @@ void StatWatcher::Callback(uv_fs_poll_t* handle, See [Callback scopes][] for more information. + ### `HandleWrap` `HandleWrap` is a subclass of `AsyncWrap` specifically designed to make working @@ -890,6 +908,7 @@ current Node.js [`Environment`][] is destroyed, e.g. when a Worker thread stops. overview over libuv handles managed by Node.js. + ### `ReqWrap` `ReqWrap` is a subclass of `AsyncWrap` specifically designed to make working @@ -902,6 +921,7 @@ track of the current count of active libuv requests. overview over libuv handles managed by Node.js. + ### Callback scopes The public `CallbackScope` and the internally used `InternalCallbackScope` diff --git a/src/crypto/README.md b/src/crypto/README.md index 479ac3378ef7d0..bb901bc1a07268 100644 --- a/src/crypto/README.md +++ b/src/crypto/README.md @@ -31,7 +31,7 @@ throughout the rest of the code. The rest of the files are structured by their function, as detailed in the following table: -| File (*.h/*.cc) | Description | +| File (\*.h/\*.cc) | Description | | -------------------- | ----------- | | `crypto_aes` | AES Cipher support. | | `crypto_cipher` | General Encryption/Decryption utilities. | @@ -98,7 +98,7 @@ Examples of these being used are pervasive through the `src/crypto` code. ### `ByteSource` -The `ByteSource` class is a helper utility representing a *read-only* byte +The `ByteSource` class is a helper utility representing a _read-only_ byte array. Instances can either wrap external ("foreign") data sources, such as an `ArrayBuffer` (`v8::BackingStore`) or allocated data. If allocated data is used, then the allocation is freed automatically when the `ByteSource` is @@ -119,9 +119,9 @@ specific to `src/crypto`. It is used extensively within `src/crypto` to hold allocated data that is intended to be output in response to various crypto functions (generated hash values, or ciphertext, for instance). -*Currently, we are working to transition away from using `AllocatedBuffer` +_Currently, we are working to transition away from using `AllocatedBuffer` to directly using the `v8::BackingStore` API. This will take some time. -New uses of `AllocatedBuffer` should be avoided if possible.* +New uses of `AllocatedBuffer` should be avoided if possible._ ### Key objects diff --git a/src/crypto/crypto_common.cc b/src/crypto/crypto_common.cc index f4b7bd3ad8548a..cc03fddd464b09 100644 --- a/src/crypto/crypto_common.cc +++ b/src/crypto/crypto_common.cc @@ -26,7 +26,9 @@ namespace node { using v8::Array; +using v8::ArrayBuffer; using v8::ArrayBufferView; +using v8::BackingStore; using v8::Context; using v8::EscapableHandleScope; using v8::Integer; @@ -562,11 +564,17 @@ MaybeLocal GetPubKey(Environment* env, const RSAPointer& rsa) { int size = i2d_RSA_PUBKEY(rsa.get(), nullptr); CHECK_GE(size, 0); - AllocatedBuffer buffer = AllocatedBuffer::AllocateManaged(env, size); - unsigned char* serialized = - reinterpret_cast(buffer.data()); - i2d_RSA_PUBKEY(rsa.get(), &serialized); - return buffer.ToBuffer(); + std::unique_ptr bs; + { + NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); + bs = ArrayBuffer::NewBackingStore(env->isolate(), size); + } + + unsigned char* serialized = reinterpret_cast(bs->Data()); + CHECK_GE(i2d_RSA_PUBKEY(rsa.get(), &serialized), 0); + + Local ab = ArrayBuffer::New(env->isolate(), std::move(bs)); + return Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local()); } MaybeLocal GetExponentString( @@ -600,11 +608,17 @@ MaybeLocal GetModulusString( MaybeLocal GetRawDERCertificate(Environment* env, X509* cert) { int size = i2d_X509(cert, nullptr); - AllocatedBuffer buffer = AllocatedBuffer::AllocateManaged(env, size); - unsigned char* serialized = - reinterpret_cast(buffer.data()); - i2d_X509(cert, &serialized); - return buffer.ToBuffer(); + std::unique_ptr bs; + { + NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); + bs = ArrayBuffer::NewBackingStore(env->isolate(), size); + } + + unsigned char* serialized = reinterpret_cast(bs->Data()); + CHECK_GE(i2d_X509(cert, &serialized), 0); + + Local ab = ArrayBuffer::New(env->isolate(), std::move(bs)); + return Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local()); } MaybeLocal GetSerialNumber(Environment* env, X509* cert) { @@ -878,18 +892,26 @@ MaybeLocal ECPointToBuffer(Environment* env, if (error != nullptr) *error = "Failed to get public key length"; return MaybeLocal(); } - AllocatedBuffer buf = AllocatedBuffer::AllocateManaged(env, len); + + std::unique_ptr bs; + { + NoArrayBufferZeroFillScope no_zero_fill_scope(env->isolate_data()); + bs = ArrayBuffer::NewBackingStore(env->isolate(), len); + } + len = EC_POINT_point2oct(group, point, form, - reinterpret_cast(buf.data()), - buf.size(), + reinterpret_cast(bs->Data()), + bs->ByteLength(), nullptr); if (len == 0) { if (error != nullptr) *error = "Failed to get public key"; return MaybeLocal(); } - return buf.ToBuffer(); + + Local ab = ArrayBuffer::New(env->isolate(), std::move(bs)); + return Buffer::New(env, ab, 0, ab->ByteLength()).FromMaybe(Local()); } MaybeLocal GetPeerCert( diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc index 1c48f98656fd21..86475e3b1b1e01 100644 --- a/src/crypto/crypto_dh.cc +++ b/src/crypto/crypto_dh.cc @@ -11,6 +11,7 @@ namespace node { +using v8::ArrayBuffer; using v8::ConstructorBehavior; using v8::DontDelete; using v8::FunctionCallback; @@ -28,6 +29,7 @@ using v8::ReadOnly; using v8::SideEffectType; using v8::Signature; using v8::String; +using v8::Uint8Array; using v8::Value; namespace crypto { @@ -539,41 +541,9 @@ WebCryptoKeyExportStatus DHKeyExportTraits::DoExport( } namespace { -AllocatedBuffer StatelessDiffieHellman( - Environment* env, - ManagedEVPPKey our_key, - ManagedEVPPKey their_key) { - size_t out_size; - - EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(our_key.get(), nullptr)); - if (!ctx || - EVP_PKEY_derive_init(ctx.get()) <= 0 || - EVP_PKEY_derive_set_peer(ctx.get(), their_key.get()) <= 0 || - EVP_PKEY_derive(ctx.get(), nullptr, &out_size) <= 0) - return AllocatedBuffer(); - - AllocatedBuffer result = AllocatedBuffer::AllocateManaged(env, out_size); - CHECK_NOT_NULL(result.data()); - - unsigned char* data = reinterpret_cast(result.data()); - if (EVP_PKEY_derive(ctx.get(), data, &out_size) <= 0) - return AllocatedBuffer(); - - ZeroPadDiffieHellmanSecret(out_size, &result); - return result; -} - -// The version of StatelessDiffieHellman that returns an AllocatedBuffer -// is not threadsafe because of the AllocatedBuffer allocation of a -// v8::BackingStore (it'll cause much crashing if we call it from a -// libuv worker thread). This version allocates a ByteSource instead, -// which we can convert into a v8::BackingStore later. -// TODO(@jasnell): Eliminate the code duplication between these two -// versions of the function. ByteSource StatelessDiffieHellmanThreadsafe( - Environment* env, - ManagedEVPPKey our_key, - ManagedEVPPKey their_key) { + const ManagedEVPPKey& our_key, + const ManagedEVPPKey& their_key) { size_t out_size; EVPKeyCtxPointer ctx(EVP_PKEY_CTX_new(our_key.get(), nullptr)); @@ -612,11 +582,18 @@ void DiffieHellman::Stateless(const FunctionCallbackInfo& args) { ManagedEVPPKey our_key = our_key_object->Data()->GetAsymmetricKey(); ManagedEVPPKey their_key = their_key_object->Data()->GetAsymmetricKey(); - AllocatedBuffer out = StatelessDiffieHellman(env, our_key, their_key); - if (out.size() == 0) + Local out; + { + Local ab = StatelessDiffieHellmanThreadsafe(our_key, their_key) + .ToArrayBuffer(env); + out = Buffer::New(env, ab, 0, ab->ByteLength()) + .FromMaybe(Local()); + } + + if (Buffer::Length(out) == 0) return ThrowCryptoError(env, ERR_get_error(), "diffieHellman failed"); - args.GetReturnValue().Set(out.ToBuffer().FromMaybe(Local())); + args.GetReturnValue().Set(out); } Maybe DHBitsTraits::AdditionalConfig( @@ -661,7 +638,6 @@ bool DHBitsTraits::DeriveBits( const DHBitsConfig& params, ByteSource* out) { *out = StatelessDiffieHellmanThreadsafe( - env, params.private_key->GetAsymmetricKey(), params.public_key->GetAsymmetricKey()); return true; diff --git a/src/env-inl.h b/src/env-inl.h index 2b000ed9ace5f7..1e85bc07a4cc29 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -25,6 +25,7 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS #include "aliased_buffer.h" +#include "allocated_buffer-inl.h" #include "callback_queue-inl.h" #include "env.h" #include "node.h" @@ -971,6 +972,29 @@ inline IsolateData* Environment::isolate_data() const { return isolate_data_; } +inline uv_buf_t Environment::allocate_managed_buffer( + const size_t suggested_size) { + NoArrayBufferZeroFillScope no_zero_fill_scope(isolate_data()); + std::unique_ptr bs = + v8::ArrayBuffer::NewBackingStore(isolate(), suggested_size); + uv_buf_t buf = uv_buf_init(static_cast(bs->Data()), bs->ByteLength()); + released_allocated_buffers()->emplace(buf.base, std::move(bs)); + return buf; +} + +inline std::unique_ptr Environment::release_managed_buffer( + const uv_buf_t& buf) { + std::unique_ptr bs; + if (buf.base != nullptr) { + auto map = released_allocated_buffers(); + auto it = map->find(buf.base); + CHECK_NE(it, map->end()); + bs = std::move(it->second); + map->erase(it); + } + return bs; +} + std::unordered_map>* Environment::released_allocated_buffers() { return &released_allocated_buffers_; diff --git a/src/env.h b/src/env.h index f055e6b45013d9..0c3715151488f4 100644 --- a/src/env.h +++ b/src/env.h @@ -1438,6 +1438,9 @@ class Environment : public MemoryRetainer { void RunAndClearNativeImmediates(bool only_refed = false); void RunAndClearInterrupts(); + inline uv_buf_t allocate_managed_buffer(const size_t suggested_size); + inline std::unique_ptr release_managed_buffer( + const uv_buf_t& buf); inline std::unordered_map>* released_allocated_buffers(); diff --git a/src/node.cc b/src/node.cc index acf4f0fac03c0b..e942c108a15a3c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -803,13 +803,6 @@ int ProcessGlobalArgs(std::vector* args, return 12; } - // TODO(mylesborins): remove this when the harmony-top-level-await flag - // is removed in V8 - if (std::find(v8_args.begin(), v8_args.end(), - "--no-harmony-top-level-await") == v8_args.end()) { - v8_args.push_back("--harmony-top-level-await"); - } - auto env_opts = per_process::cli_options->per_isolate->per_env; if (std::find(v8_args.begin(), v8_args.end(), "--abort-on-uncaught-exception") != v8_args.end() || diff --git a/src/node_credentials.cc b/src/node_credentials.cc index fa3dfa48a3ceb2..de0ba3c8be2b1e 100644 --- a/src/node_credentials.cc +++ b/src/node_credentials.cc @@ -11,6 +11,10 @@ #if !defined(_MSC_VER) #include // setuid, getuid #endif +#ifdef __linux__ +#include +#include +#endif // __linux__ namespace node { @@ -33,11 +37,42 @@ bool linux_at_secure = false; namespace credentials { -// Look up environment variable unless running as setuid root. +#if defined(__linux__) +// Returns true if the current process only has the passed-in capability. +bool HasOnly(int capability) { + DCHECK(cap_valid(capability)); + + struct __user_cap_data_struct cap_data[2]; + struct __user_cap_header_struct cap_header_data = { + _LINUX_CAPABILITY_VERSION_3, + getpid()}; + + + if (syscall(SYS_capget, &cap_header_data, &cap_data) != 0) { + return false; + } + if (capability < 32) { + return cap_data[0].permitted == + static_cast(CAP_TO_MASK(capability)); + } + return cap_data[1].permitted == + static_cast(CAP_TO_MASK(capability)); +} +#endif + +// Look up the environment variable and allow the lookup if the current +// process only has the capability CAP_NET_BIND_SERVICE set. If the current +// process does not have any capabilities set and the process is running as +// setuid root then lookup will not be allowed. bool SafeGetenv(const char* key, std::string* text, Environment* env) { #if !defined(__CloudABI__) && !defined(_WIN32) +#if defined(__linux__) + if ((!HasOnly(CAP_NET_BIND_SERVICE) && per_process::linux_at_secure) || + getuid() != geteuid() || getgid() != getegid()) +#else if (per_process::linux_at_secure || getuid() != geteuid() || getgid() != getegid()) +#endif goto fail; #endif diff --git a/src/node_url.cc b/src/node_url.cc index d78cb7a3e1ceb0..14522fccb079ab 100644 --- a/src/node_url.cc +++ b/src/node_url.cc @@ -52,9 +52,6 @@ namespace { // https://url.spec.whatwg.org/#eof-code-point constexpr char kEOL = -1; -// Used in ToUSVString(). -constexpr char16_t kUnicodeReplacementCharacter = 0xFFFD; - // https://url.spec.whatwg.org/#concept-host class URLHost { public: @@ -160,14 +157,6 @@ enum url_error_cb_args { #undef XX }; -#define CHAR_TEST(bits, name, expr) \ - template \ - bool name(const T ch) { \ - static_assert(sizeof(ch) >= (bits) / 8, \ - "Character must be wider than " #bits " bits"); \ - return (expr); \ - } - #define TWO_CHAR_STRING_TEST(bits, name, expr) \ template \ bool name(const T ch1, const T ch2) { \ @@ -225,19 +214,8 @@ TWO_CHAR_STRING_TEST(8, IsWindowsDriveLetter, TWO_CHAR_STRING_TEST(8, IsNormalizedWindowsDriveLetter, (IsASCIIAlpha(ch1) && ch2 == ':')) -// If a UTF-16 character is a low/trailing surrogate. -CHAR_TEST(16, IsUnicodeTrail, (ch & 0xFC00) == 0xDC00) - -// If a UTF-16 character is a surrogate. -CHAR_TEST(16, IsUnicodeSurrogate, (ch & 0xF800) == 0xD800) - -// If a UTF-16 surrogate is a low/trailing one. -CHAR_TEST(16, IsUnicodeSurrogateTrail, (ch & 0x400) != 0) - -#undef CHAR_TEST #undef TWO_CHAR_STRING_TEST - bool BitAt(const uint8_t a[], const uint8_t i) { return !!(a[i >> 3] & (1 << (i & 7))); } @@ -1736,40 +1714,6 @@ void EncodeAuthSet(const FunctionCallbackInfo& args) { String::NewFromUtf8(env->isolate(), output.c_str()).ToLocalChecked()); } -void ToUSVString(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); - CHECK_GE(args.Length(), 2); - CHECK(args[0]->IsString()); - CHECK(args[1]->IsNumber()); - - TwoByteValue value(env->isolate(), args[0]); - - int64_t start = args[1]->IntegerValue(env->context()).FromJust(); - CHECK_GE(start, 0); - - for (size_t i = start; i < value.length(); i++) { - char16_t c = value[i]; - if (!IsUnicodeSurrogate(c)) { - continue; - } else if (IsUnicodeSurrogateTrail(c) || i == value.length() - 1) { - value[i] = kUnicodeReplacementCharacter; - } else { - char16_t d = value[i + 1]; - if (IsUnicodeTrail(d)) { - i++; - } else { - value[i] = kUnicodeReplacementCharacter; - } - } - } - - args.GetReturnValue().Set( - String::NewFromTwoByte(env->isolate(), - *value, - NewStringType::kNormal, - value.length()).ToLocalChecked()); -} - void DomainToASCII(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); CHECK_GE(args.Length(), 1); @@ -1820,7 +1764,6 @@ void Initialize(Local target, Environment* env = Environment::GetCurrent(context); env->SetMethod(target, "parse", Parse); env->SetMethodNoSideEffect(target, "encodeAuth", EncodeAuthSet); - env->SetMethodNoSideEffect(target, "toUSVString", ToUSVString); env->SetMethodNoSideEffect(target, "domainToASCII", DomainToASCII); env->SetMethodNoSideEffect(target, "domainToUnicode", DomainToUnicode); env->SetMethod(target, "setURLConstructor", SetURLConstructor); @@ -1838,7 +1781,6 @@ void Initialize(Local target, void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(Parse); registry->Register(EncodeAuthSet); - registry->Register(ToUSVString); registry->Register(DomainToASCII); registry->Register(DomainToUnicode); registry->Register(SetURLConstructor); diff --git a/src/node_util.cc b/src/node_util.cc index cc03ec0aba602a..2db45bd1fb40af 100644 --- a/src/node_util.cc +++ b/src/node_util.cc @@ -35,6 +35,18 @@ using v8::String; using v8::Uint32; using v8::Value; +// Used in ToUSVString(). +constexpr char16_t kUnicodeReplacementCharacter = 0xFFFD; + +// If a UTF-16 character is a low/trailing surrogate. +CHAR_TEST(16, IsUnicodeTrail, (ch & 0xFC00) == 0xDC00) + +// If a UTF-16 character is a surrogate. +CHAR_TEST(16, IsUnicodeSurrogate, (ch & 0xF800) == 0xD800) + +// If a UTF-16 surrogate is a low/trailing one. +CHAR_TEST(16, IsUnicodeSurrogateTrail, (ch & 0x400) != 0) + static void GetOwnNonIndexProperties( const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -282,6 +294,40 @@ static void IsConstructor(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(args[0].As()->IsConstructor()); } +static void ToUSVString(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + CHECK_GE(args.Length(), 2); + CHECK(args[0]->IsString()); + CHECK(args[1]->IsNumber()); + + TwoByteValue value(env->isolate(), args[0]); + + int64_t start = args[1]->IntegerValue(env->context()).FromJust(); + CHECK_GE(start, 0); + + for (size_t i = start; i < value.length(); i++) { + char16_t c = value[i]; + if (!IsUnicodeSurrogate(c)) { + continue; + } else if (IsUnicodeSurrogateTrail(c) || i == value.length() - 1) { + value[i] = kUnicodeReplacementCharacter; + } else { + char16_t d = value[i + 1]; + if (IsUnicodeTrail(d)) { + i++; + } else { + value[i] = kUnicodeReplacementCharacter; + } + } + } + + args.GetReturnValue().Set( + String::NewFromTwoByte(env->isolate(), + *value, + v8::NewStringType::kNormal, + value.length()).ToLocalChecked()); +} + void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(GetHiddenValue); registry->Register(SetHiddenValue); @@ -299,6 +345,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(WeakReference::DecRef); registry->Register(GuessHandleType); registry->Register(IsConstructor); + registry->Register(ToUSVString); } void Initialize(Local target, @@ -370,6 +417,8 @@ void Initialize(Local target, env->SetConstructorFunction(target, "WeakReference", weak_ref); env->SetMethod(target, "guessHandleType", GuessHandleType); + + env->SetMethodNoSideEffect(target, "toUSVString", ToUSVString); } } // namespace util diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 10a5fd929f6037..10c92358cc7661 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -31,12 +31,16 @@ namespace node { using v8::Array; +using v8::ArrayBuffer; +using v8::BackingStore; +using v8::Boolean; using v8::Context; using v8::DontDelete; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::HandleScope; using v8::Integer; +using v8::Isolate; using v8::Local; using v8::MaybeLocal; using v8::Object; @@ -314,7 +318,7 @@ void UDPWrap::BufferSize(const FunctionCallbackInfo& args) { CHECK(args[0]->IsUint32()); CHECK(args[1]->IsBoolean()); - bool is_recv = args[1].As()->Value(); + bool is_recv = args[1].As()->Value(); const char* uv_func_name = is_recv ? "uv_recv_buffer_size" : "uv_send_buffer_size"; @@ -679,7 +683,7 @@ void UDPWrap::OnAlloc(uv_handle_t* handle, } uv_buf_t UDPWrap::OnAlloc(size_t suggested_size) { - return AllocatedBuffer::AllocateManaged(env(), suggested_size).release(); + return env()->allocate_managed_buffer(suggested_size); } void UDPWrap::OnRecv(uv_udp_t* handle, @@ -696,27 +700,32 @@ void UDPWrap::OnRecv(ssize_t nread, const sockaddr* addr, unsigned int flags) { Environment* env = this->env(); - AllocatedBuffer buf(env, buf_); + Isolate* isolate = env->isolate(); + std::unique_ptr bs = env->release_managed_buffer(buf_); if (nread == 0 && addr == nullptr) { return; } - HandleScope handle_scope(env->isolate()); + HandleScope handle_scope(isolate); Context::Scope context_scope(env->context()); Local argv[] = { - Integer::New(env->isolate(), static_cast(nread)), + Integer::New(isolate, static_cast(nread)), object(), - Undefined(env->isolate()), - Undefined(env->isolate())}; + Undefined(isolate), + Undefined(isolate)}; if (nread < 0) { MakeCallback(env->onmessage_string(), arraysize(argv), argv); return; + } else if (nread == 0) { + bs = ArrayBuffer::NewBackingStore(isolate, 0); + } else { + bs = BackingStore::Reallocate(isolate, std::move(bs), nread); } - buf.Resize(nread); - argv[2] = buf.ToBuffer().ToLocalChecked(); + Local ab = ArrayBuffer::New(isolate, std::move(bs)); + argv[2] = Buffer::New(env, ab, 0, ab->ByteLength()).ToLocalChecked(); argv[3] = AddressToJS(env, addr); MakeCallback(env->onmessage_string(), arraysize(argv), argv); } diff --git a/src/util-inl.h b/src/util-inl.h index 517da707170586..b860c7008a340a 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -64,6 +64,14 @@ (((x) & 0x00000000000000FFull) << 56) #endif +#define CHAR_TEST(bits, name, expr) \ + template \ + bool name(const T ch) { \ + static_assert(sizeof(ch) >= (bits) / 8, \ + "Character must be wider than " #bits " bits"); \ + return (expr); \ + } + namespace node { template diff --git a/test/README.md b/test/README.md index cc3725764da543..470f525ebe1ebc 100644 --- a/test/README.md +++ b/test/README.md @@ -17,7 +17,7 @@ For the tests to run on Windows, be sure to clone Node.js source code with the | ---------------- | ---------- | --------------- | | `abort` | Yes | Tests that use `--abort-on-uncaught-exception` and other situations where we want to test something but avoid generating a core file. | | `addons` | Yes | Tests for [addon](https://nodejs.org/api/addons.html) functionality along with some tests that require an addon. | -| `async-hooks` | Yes | Tests for [async_hooks](https://nodejs.org/api/async_hooks.html) functionality. | +| `async-hooks` | Yes | Tests for [async\_hooks](https://nodejs.org/api/async\_hooks.html) functionality. | | `benchmark` | Yes | Test minimal functionality of benchmarks. | | `cctest` | Yes | C++ tests that are run as part of the build process. | | `code-cache` | No | Tests for a Node.js binary compiled with V8 code cache. | diff --git a/test/common/README.md b/test/common/README.md index 6b42fa1070d015..2352e0497a4378 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -31,10 +31,10 @@ The `benchmark` module is used by tests to run benchmarks. ### `runBenchmark(name, args, env)` -* `name` [<string>][] Name of benchmark suite to be run. -* `args` [<Array>][] Array of environment variable key/value pairs (ex: +* `name` [\][] Name of benchmark suite to be run. +* `args` [\][] Array of environment variable key/value pairs (ex: `n=1`) to be applied via `--set`. -* `env` [<Object>][] Environment variables to be applied during the run. +* `env` [\][] Environment variables to be applied during the run. ## Common Module API @@ -43,19 +43,19 @@ tasks. ### `allowGlobals(...allowlist)` -* `allowlist` [<Array>][] Array of Globals -* return [<Array>][] +* `allowlist` [\][] Array of Globals +* return [\][] Takes `allowlist` and concats that with predefined `knownGlobals`. ### `canCreateSymLink()` -* return [<boolean>][] +* return [\][] Checks whether the current running process can create symlinks. On Windows, this returns `false` if the process running doesn't have privileges to create symlinks -([SeCreateSymbolicLinkPrivilege](https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716(v=vs.85).aspx)). +([SeCreateSymbolicLinkPrivilege](https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716\(v=vs.85\).aspx)). On non-Windows platforms, this always returns `true`. ### `createZeroFilledFile(filename)` @@ -64,17 +64,17 @@ Creates a 10 MB file of all null characters. ### `enoughTestMem` -* [<boolean>][] +* [\][] Indicates if there is more than 1gb of total memory. ### `expectsError(validator[, exact])` -* `validator` [<Object>][] | [<RegExp>][] | [<Function>][] | - [<Error>][] The validator behaves identical to +* `validator` [\][] | [\][] | [\][] | + [\][] The validator behaves identical to `assert.throws(fn, validator)`. -* `exact` [<number>][] default = 1 -* return [<Function>][] A callback function that expects an error. +* `exact` [\][] default = 1 +* return [\][] A callback function that expects an error. A function suitable as callback to validate callback based errors. The error is validated using `assert.throws(() => { throw error; }, validator)`. If the @@ -83,9 +83,9 @@ test is complete, then the test will fail. ### `expectWarning(name[, expected[, code]])` -* `name` [<string>][] | [<Object>][] -* `expected` [<string>][] | [<Array>][] | [<Object>][] -* `code` [<string>][] +* `name` [\][] | [\][] +* `expected` [\][] | [\][] | [\][] +* `code` [\][] Tests whether `name`, `expected`, and `code` are part of a raised warning. @@ -130,23 +130,23 @@ expectWarning({ ### `getArrayBufferViews(buf)` -* `buf` [<Buffer>][] -* return [<ArrayBufferView>][]\[\] +* `buf` [\][] +* return [\][]\[] Returns an instance of all possible `ArrayBufferView`s of the provided Buffer. ### `getBufferSources(buf)` -* `buf` [<Buffer>][] -* return [<BufferSource>][]\[\] +* `buf` [\][] +* return [\][]\[] Returns an instance of all possible `BufferSource`s of the provided Buffer, consisting of all `ArrayBufferView` and an `ArrayBuffer`. ### `getCallSite(func)` -* `func` [<Function>][] -* return [<string>][] +* `func` [\][] +* return [\][] Returns the file name and line number for the provided Function. @@ -158,13 +158,13 @@ The TTY file descriptor is assumed to be capable of being writable. ### `hasCrypto` -* [<boolean>][] +* [\][] Indicates whether OpenSSL is available. ### `hasFipsCrypto` -* [<boolean>][] +* [\][] Indicates that Node.js has been linked with a FIPS compatible OpenSSL library, and that FIPS as been enabled using `--enable-fips`. @@ -175,104 +175,104 @@ used to determine that situation. ### `hasIntl` -* [<boolean>][] +* [\][] Indicates if [internationalization][] is supported. ### `hasIPv6` -* [<boolean>][] +* [\][] Indicates whether `IPv6` is supported on this platform. ### `hasMultiLocalhost` -* [<boolean>][] +* [\][] Indicates if there are multiple localhosts available. ### `inFreeBSDJail` -* [<boolean>][] +* [\][] Checks whether free BSD Jail is true or false. ### `isAIX` -* [<boolean>][] +* [\][] Platform check for Advanced Interactive eXecutive (AIX). ### `isAlive(pid)` -* `pid` [<number>][] -* return [<boolean>][] +* `pid` [\][] +* return [\][] Attempts to 'kill' `pid` ### `isDumbTerminal` -* [<boolean>][] +* [\][] ### `isFreeBSD` -* [<boolean>][] +* [\][] Platform check for Free BSD. ### `isIBMi` -* [<boolean>][] +* [\][] Platform check for IBMi. ### `isLinux` -* [<boolean>][] +* [\][] Platform check for Linux. ### `isLinuxPPCBE` -* [<boolean>][] +* [\][] Platform check for Linux on PowerPC. ### `isOSX` -* [<boolean>][] +* [\][] Platform check for macOS. ### `isSunOS` -* [<boolean>][] +* [\][] Platform check for SunOS. ### `isWindows` -* [<boolean>][] +* [\][] Platform check for Windows. ### `localhostIPv4` -* [<string>][] +* [\][] IP of `localhost`. ### `localIPv6Hosts` -* [<Array>][] +* [\][] Array of IPV6 representations for `localhost`. ### `mustCall([fn][, exact])` -* `fn` [<Function>][] default = () => {} -* `exact` [<number>][] default = 1 -* return [<Function>][] +* `fn` [\][] default = () => {} +* `exact` [\][] default = 1 +* return [\][] Returns a function that calls `fn`. If the returned function has not been called exactly `exact` number of times when the test is complete, then the test will @@ -282,9 +282,9 @@ If `fn` is not provided, an empty function will be used. ### `mustCallAtLeast([fn][, minimum])` -* `fn` [<Function>][] default = () => {} -* `minimum` [<number>][] default = 1 -* return [<Function>][] +* `fn` [\][] default = () => {} +* `minimum` [\][] default = 1 +* return [\][] Returns a function that calls `fn`. If the returned function has not been called at least `minimum` number of times when the test is complete, then the test will @@ -294,16 +294,16 @@ If `fn` is not provided, an empty function will be used. ### `mustNotCall([msg])` -* `msg` [<string>][] default = 'function should not have been called' -* return [<Function>][] +* `msg` [\][] default = 'function should not have been called' +* return [\][] Returns a function that triggers an `AssertionError` if it is invoked. `msg` is used as the error message for the `AssertionError`. ### `mustSucceed([fn])` -* `fn` [<Function>][] default = () => {} -* return [<Function>][] +* `fn` [\][] default = () => {} +* return [\][] Returns a function that accepts arguments `(err, ...args)`. If `err` is not `undefined` or `null`, it triggers an `AssertionError`. Otherwise, it calls @@ -311,9 +311,9 @@ Returns a function that accepts arguments `(err, ...args)`. If `err` is not ### `nodeProcessAborted(exitCode, signal)` -* `exitCode` [<number>][] -* `signal` [<string>][] -* return [<boolean>][] +* `exitCode` [\][] +* `signal` [\][] +* return [\][] Returns `true` if the exit code `exitCode` and/or signal name `signal` represent the exit code and/or signal name of a node process that aborted, `false` @@ -321,14 +321,14 @@ otherwise. ### `opensslCli` -* [<boolean>][] +* [\][] Indicates whether 'opensslCli' is supported. ### `platformTimeout(ms)` -* `ms` [<number>][] | [<bigint>][] -* return [<number>][] | [<bigint>][] +* `ms` [\][] | [\][] +* return [\][] | [\][] Returns a timeout value based on detected conditions. For example, a debug build may need extra time so the returned value will be larger than on a release @@ -336,27 +336,28 @@ build. ### `PIPE` -* [<string>][] +* [\][] Path to the test socket. ### `PORT` -* [<number>][] +* [\][] A port number for tests to use if one is needed. ### `printSkipMessage(msg)` -* `msg` [<string>][] +* `msg` [\][] Logs '1..0 # Skipped: ' + `msg` ### `pwdCommand` -* [<array>][] First two argument for the `spawn`/`exec` functions. +* [\][] First two argument for the `spawn`/`exec` functions. Platform normalized `pwd` command options. Usage example: + ```js const common = require('../common'); const { spawn } = require('child_process'); @@ -366,14 +367,14 @@ spawn(...common.pwdCommand, { stdio: ['pipe'] }); ### `requireNoPackageJSONAbove([dir])` -* `dir` [<string>][] default = \_\_dirname +* `dir` [\][] default = \_\_dirname Throws an `AssertionError` if a `package.json` file exists in any ancestor directory above `dir`. Such files may interfere with proper test functionality. ### `runWithInvalidFD(func)` -* `func` [<Function>][] +* `func` [\][] Runs `func` with an invalid file descriptor that is an unsigned integer and can be used to trigger `EBADF` as the first argument. If no such file @@ -382,7 +383,7 @@ will not be run. ### `skip(msg)` -* `msg` [<string>][] +* `msg` [\][] Logs '1..0 # Skipped: ' + `msg` and exits with exit code `0`. @@ -416,6 +417,7 @@ The `ArrayStream` module provides a simple `Stream` that pushes elements from a given array. + ```js const ArrayStream = require('../common/arraystream'); const stream = new ArrayStream(); @@ -432,6 +434,7 @@ tasks (for instance, shutting down an HTTP server after a specific number of requests). The Countdown will fail the test if the remainder did not reach 0. + ```js const Countdown = require('../common/countdown'); @@ -466,14 +469,14 @@ The `cpu-prof` module provides utilities related to CPU profiling tests. ### `env` -* Default: { ...process.env, NODE_DEBUG_NATIVE: 'INSPECTOR_PROFILER' } +* Default: { ...process.env, NODE\_DEBUG\_NATIVE: 'INSPECTOR\_PROFILER' } Environment variables used in profiled processes. ### `getCpuProfiles(dir)` * `dir` {string} The directory containing the CPU profile files. -* return [<string>][] +* return [\][] Returns an array of all `.cpuprofile` files found in `dir`. @@ -481,7 +484,7 @@ Returns an array of all `.cpuprofile` files found in `dir`. * `file` {string} Path to a `.cpuprofile` file. * `suffix` {string} Suffix of the URL of call frames to retrieve. -* returns { frames: [<Object>][], nodes: [<Object>][] } +* returns { frames: [\][], nodes: [\][] } Returns an object containing an array of the relevant call frames and an array of all the profile nodes. @@ -505,10 +508,10 @@ Provides common functionality for tests for `node inspect`. ### `startCLI(args[[, flags], spawnOpts])` -* `args` [<string>][] -* `flags` [<string>][] default = [] -* `showOpts` [<Object>][] default = {} -* return [<Object>][] +* `args` [\][] +* `flags` [\][] default = \[] +* `showOpts` [\][] default = {} +* return [\][] Returns a null-prototype object with properties that are functions and getters used to interact with the `node inspect` CLI. These functions are: @@ -533,9 +536,9 @@ The `DNS` module provides utilities related to the `dns` built-in module. ### `errorLookupMock(code, syscall)` -* `code` [<string>][] Defaults to `dns.mockedErrorCode`. -* `syscall` [<string>][] Defaults to `dns.mockedSysCall`. -* return [<Function>][] +* `code` [\][] Defaults to `dns.mockedErrorCode`. +* `syscall` [\][] Defaults to `dns.mockedSysCall`. +* return [\][] A mock for the `lookup` option of `net.connect()` that would result in an error with the `code` and the `syscall` specified. Returns a function that has the @@ -551,39 +554,39 @@ The default `syscall` of errors generated by `errorLookupMock`. ### `readDomainFromPacket(buffer, offset)` -* `buffer` [<Buffer>][] -* `offset` [<number>][] -* return [<Object>][] +* `buffer` [\][] +* `offset` [\][] +* return [\][] Reads the domain string from a packet and returns an object containing the number of bytes read and the domain. ### `parseDNSPacket(buffer)` -* `buffer` [<Buffer>][] -* return [<Object>][] +* `buffer` [\][] +* return [\][] Parses a DNS packet. Returns an object with the values of the various flags of the packet depending on the type of packet. ### `writeIPv6(ip)` -* `ip` [<string>][] -* return [<Buffer>][] +* `ip` [\][] +* return [\][] Reads an IPv6 String and returns a Buffer containing the parts. ### `writeDomainName(domain)` -* `domain` [<string>][] -* return [<Buffer>][] +* `domain` [\][] +* return [\][] Reads a Domain String and returns a Buffer containing the domain. ### `writeDNSPacket(parsed)` -* `parsed` [<Object>][] -* return [<Buffer>][] +* `parsed` [\][] +* return [\][] Takes in a parsed Object and writes its fields to a DNS packet as a Buffer object. @@ -604,7 +607,7 @@ environment variables. ### `NODE_COMMON_PORT` If set, `NODE_COMMON_PORT`'s value overrides the `common.PORT` default value of -12346. +12346\. ### `NODE_SKIP_FLAG_CHECK` @@ -627,26 +630,26 @@ files in the `test/fixtures` directory. ### `fixtures.fixturesDir` -* [<string>][] +* [\][] The absolute path to the `test/fixtures/` directory. ### `fixtures.path(...args)` -* `...args` [<string>][] +* `...args` [\][] Returns the result of `path.join(fixtures.fixturesDir, ...args)`. ### `fixtures.readSync(args[, enc])` -* `args` [<string>][] | [<Array>][] +* `args` [\][] | [\][] Returns the result of `fs.readFileSync(path.join(fixtures.fixturesDir, ...args), 'enc')`. ### `fixtures.readKey(arg[, enc])` -* `arg` [<string>][] +* `arg` [\][] Returns the result of `fs.readFileSync(path.join(fixtures.fixturesDir, 'keys', arg), 'enc')`. @@ -665,16 +668,17 @@ one listed below. (`heap.validateSnapshotNodes(...)` is a shortcut for ### `heap.validateSnapshotNodes(name, expected, options)` -* `name` [<string>][] Look for this string as the name of heap dump nodes. -* `expected` [<Array>][] A list of objects, possibly with an `children` +* `name` [\][] Look for this string as the name of heap dump nodes. +* `expected` [\][] A list of objects, possibly with an `children` property that points to expected other adjacent nodes. -* `options` [<Array>][] - * `loose` [<boolean>][] Do not expect an exact listing of occurrences +* `options` [\][] + * `loose` [\][] Do not expect an exact listing of occurrences of nodes with name `name` in `expected`. Create a heap dump and an embedder graph copy and validate occurrences. + ```js validateSnapshotNodes('TLSWRAP', [ { @@ -693,6 +697,7 @@ The `hijackstdio` module provides utility functions for temporarily redirecting `stdout` and `stderr` output. + ```js const { hijackStdout, restoreStdout } = require('../common/hijackstdio'); @@ -706,7 +711,7 @@ console.log('this is sent to the hijacked listener'); ### `hijackStderr(listener)` -* `listener` [<Function>][]: a listener with a single parameter +* `listener` [\][]: a listener with a single parameter called `data`. Eavesdrop to `process.stderr.write()` calls. Once `process.stderr.write()` is @@ -716,7 +721,7 @@ the number of calls. ### `hijackStdout(listener)` -* `listener` [<Function>][]: a listener with a single parameter +* `listener` [\][]: a listener with a single parameter called `data`. Eavesdrop to `process.stdout.write()` calls. Once `process.stdout.write()` is @@ -740,6 +745,7 @@ The http2.js module provides a handful of utilities for creating mock HTTP/2 frames for testing of HTTP/2 endpoints + ```js const http2 = require('../common/http2'); ``` @@ -750,6 +756,7 @@ The `http2.Frame` is a base class that creates a `Buffer` containing a serialized HTTP/2 frame header. + ```js // length is a 24-bit unsigned integer // type is an 8-bit unsigned integer identifying the frame type @@ -769,6 +776,7 @@ The `http2.DataFrame` is a subclass of `http2.Frame` that serializes a `DATA` frame. + ```js // id is the 32-bit stream identifier // payload is a Buffer containing the DATA payload @@ -786,6 +794,7 @@ The `http2.HeadersFrame` is a subclass of `http2.Frame` that serializes a `HEADERS` frame. + ```js // id is the 32-bit stream identifier // payload is a Buffer containing the HEADERS payload (see either @@ -804,6 +813,7 @@ The `http2.SettingsFrame` is a subclass of `http2.Frame` that serializes an empty `SETTINGS` frame. + ```js // ack is a boolean indicating whether or not to set the ACK flag. const frame = new http2.SettingsFrame(ack); @@ -817,6 +827,7 @@ Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2 request headers to be used as the payload of a `http2.HeadersFrame`. + ```js const frame = new http2.HeadersFrame(1, http2.kFakeRequestHeaders, 0, true); @@ -829,6 +840,7 @@ Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2 response headers to be used as the payload a `http2.HeadersFrame`. + ```js const frame = new http2.HeadersFrame(1, http2.kFakeResponseHeaders, 0, true); @@ -841,6 +853,7 @@ Set to a `Buffer` containing the preamble bytes an HTTP/2 client must send upon initial establishment of a connection. + ```js socket.write(http2.kClientMagic); ``` @@ -852,27 +865,27 @@ internet-related tests. ### `internet.addresses` -* [<Object>][] - * `INET_HOST` [<string>][] A generic host that has registered common +* [\][] + * `INET_HOST` [\][] A generic host that has registered common DNS records, supports both IPv4 and IPv6, and provides basic HTTP/HTTPS services - * `INET4_HOST` [<string>][] A host that provides IPv4 services - * `INET6_HOST` [<string>][] A host that provides IPv6 services - * `INET4_IP` [<string>][] An accessible IPv4 IP, defaults to the + * `INET4_HOST` [\][] A host that provides IPv4 services + * `INET6_HOST` [\][] A host that provides IPv6 services + * `INET4_IP` [\][] An accessible IPv4 IP, defaults to the Google Public DNS IPv4 address - * `INET6_IP` [<string>][] An accessible IPv6 IP, defaults to the + * `INET6_IP` [\][] An accessible IPv6 IP, defaults to the Google Public DNS IPv6 address - * `INVALID_HOST` [<string>][] An invalid host that cannot be resolved - * `MX_HOST` [<string>][] A host with MX records registered - * `SRV_HOST` [<string>][] A host with SRV records registered - * `PTR_HOST` [<string>][] A host with PTR records registered - * `NAPTR_HOST` [<string>][] A host with NAPTR records registered - * `SOA_HOST` [<string>][] A host with SOA records registered - * `CNAME_HOST` [<string>][] A host with CNAME records registered - * `NS_HOST` [<string>][] A host with NS records registered - * `TXT_HOST` [<string>][] A host with TXT records registered - * `DNS4_SERVER` [<string>][] An accessible IPv4 DNS server - * `DNS6_SERVER` [<string>][] An accessible IPv6 DNS server + * `INVALID_HOST` [\][] An invalid host that cannot be resolved + * `MX_HOST` [\][] A host with MX records registered + * `SRV_HOST` [\][] A host with SRV records registered + * `PTR_HOST` [\][] A host with PTR records registered + * `NAPTR_HOST` [\][] A host with NAPTR records registered + * `SOA_HOST` [\][] A host with SOA records registered + * `CNAME_HOST` [\][] A host with CNAME records registered + * `NS_HOST` [\][] A host with NS records registered + * `TXT_HOST` [\][] A host with TXT records registered + * `DNS4_SERVER` [\][] An accessible IPv4 DNS server + * `DNS6_SERVER` [\][] An accessible IPv6 DNS server A set of addresses for internet-related tests. All properties are configurable via `NODE_TEST_*` environment variables. For example, to configure @@ -893,9 +906,9 @@ onGC({}, { ongc() { console.log('collected'); } }); ### `onGC(target, listener)` -* `target` [<Object>][] -* `listener` [<Object>][] - * `ongc` [<Function>][] +* `target` [\][] +* `listener` [\][] + * `ongc` [\][] Installs a GC listener for the collection of `target`. @@ -914,23 +927,23 @@ functionality. ### `findReports(pid, dir)` -* `pid` [<number>][] Process ID to retrieve diagnostic report files for. -* `dir` [<string>][] Directory to search for diagnostic report files. -* return [<Array>][] +* `pid` [\][] Process ID to retrieve diagnostic report files for. +* `dir` [\][] Directory to search for diagnostic report files. +* return [\][] Returns an array of diagnostic report file names found in `dir`. The files should have been generated by a process whose PID matches `pid`. ### `validate(filepath)` -* `filepath` [<string>][] Diagnostic report filepath to validate. +* `filepath` [\][] Diagnostic report filepath to validate. Validates the schema of a diagnostic report file whose path is specified in `filepath`. If the report fails validation, an exception is thrown. ### `validateContent(report)` -* `report` [<Object>][] | [<string>][] JSON contents of a diagnostic +* `report` [\][] | [\][] JSON contents of a diagnostic report file, the parsed Object thereof, or the result of `process.report.getReport()`. @@ -944,8 +957,8 @@ after a given number of event loop "ticks". ### `tick(x, cb)` -* `x` [<number>][] Number of event loop "ticks". -* `cb` [<Function>][] A callback function. +* `x` [\][] Number of event loop "ticks". +* `cb` [\][] A callback function. ## tmpdir Module @@ -953,7 +966,7 @@ The `tmpdir` module supports the use of a temporary directory for testing. ### `path` -* [<string>][] +* [\][] The realpath of the testing temporary directory. @@ -1002,18 +1015,18 @@ A driver class for running WPT with the WPT harness in a worker thread. See [the WPT tests README][] for details. -[<Array>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array -[<ArrayBufferView>]: https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView -[<Buffer>]: https://nodejs.org/api/buffer.html#buffer_class_buffer -[<BufferSource>]: https://developer.mozilla.org/en-US/docs/Web/API/BufferSource -[<Error>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error -[<Function>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function -[<Object>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object -[<RegExp>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp -[<bigint>]: https://github.com/tc39/proposal-bigint -[<boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type -[<number>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type -[<string>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array +[\]: https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView +[\]: https://nodejs.org/api/buffer.html#buffer_class_buffer +[\]: https://developer.mozilla.org/en-US/docs/Web/API/BufferSource +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp +[\]: https://github.com/tc39/proposal-bigint +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type +[\]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type [Web Platform Tests]: https://github.com/web-platform-tests/wpt [`hijackstdio.hijackStdErr()`]: #hijackstderrlistener [`hijackstdio.hijackStdOut()`]: #hijackstdoutlistener diff --git a/test/es-module/test-esm-exports-deprecations.mjs b/test/es-module/test-esm-exports-deprecations.mjs index fd92dd3d78d14e..5523af286bccfc 100644 --- a/test/es-module/test-esm-exports-deprecations.mjs +++ b/test/es-module/test-esm-exports-deprecations.mjs @@ -3,12 +3,7 @@ import assert from 'assert'; let curWarning = 0; const expectedWarnings = [ - '"./sub/"', - '"./fallbackdir/"', '"./trailing-pattern-slash/"', - '"./subpath/"', - '"./subpath/dir1/"', - '"./subpath/dir2/"', 'no_exports', 'default_index', ]; diff --git a/test/es-module/test-esm-exports.mjs b/test/es-module/test-esm-exports.mjs index 11323351b6512f..e6182a16e736eb 100644 --- a/test/es-module/test-esm-exports.mjs +++ b/test/es-module/test-esm-exports.mjs @@ -11,8 +11,6 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; const validSpecifiers = new Map([ // A simple mapping of a path. ['pkgexports/valid-cjs', { default: 'asdf' }], - // A directory mapping, pointing to the package root. - ['pkgexports/sub/asdf.js', { default: 'asdf' }], // A mapping pointing to a file that needs special encoding (%20) in URLs. ['pkgexports/space', { default: 'encoded path' }], // Verifying that normal packages still work with exports turned on. @@ -47,15 +45,7 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; { default: 'trailing-pattern-slash' }], ]); - if (isRequire) { - validSpecifiers.set('pkgexports/subpath/file', { default: 'file' }); - validSpecifiers.set('pkgexports/subpath/dir1', { default: 'main' }); - // Deprecated: - validSpecifiers.set('pkgexports/subpath/dir1/', { default: 'main' }); - validSpecifiers.set('pkgexports/subpath/dir2', { default: 'index' }); - // Deprecated: - validSpecifiers.set('pkgexports/subpath/dir2/', { default: 'index' }); - } else { + if (!isRequire) { // No exports or main field validSpecifiers.set('no_exports', { default: 'index' }); // Main field without extension @@ -93,8 +83,6 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; ]); const invalidExports = new Map([ - // Directory mappings require a trailing / to work - ['pkgexports/missingtrailer/x', './missingtrailer/'], // This path steps back inside the package but goes through an exports // target that escapes the package, so we still catch that as invalid ['pkgexports/belowdir/pkgexports/asdf.js', './belowdir/'], @@ -171,7 +159,6 @@ import fromInside from '../fixtures/node_modules/pkgexports/lib/hole.js'; strictEqual(err.code, 'ERR_UNSUPPORTED_DIR_IMPORT'); assertStartsWith(err.message, 'Directory import'); }; - notFoundExports.set('pkgexports/subpath/file', 'pkgexports/subpath/file'); loadFixture('pkgexports/subpath/dir1').catch(mustCall(onDirectoryImport)); loadFixture('pkgexports/subpath/dir2').catch(mustCall(onDirectoryImport)); } diff --git a/test/es-module/test-esm-imports.mjs b/test/es-module/test-esm-imports.mjs index 577e33b60d08ec..9dc78199012cd7 100644 --- a/test/es-module/test-esm-imports.mjs +++ b/test/es-module/test-esm-imports.mjs @@ -34,8 +34,6 @@ const { requireImport, importImport } = importer; } const invalidImportTargets = new Set([ - // External subpath import without trailing slash - ['#external/invalidsubpath/x', '#external/invalidsubpath/'], // Target steps below the package base ['#belowbase', '#belowbase'], // Target is a URL @@ -73,6 +71,8 @@ const { requireImport, importImport } = importer; } const undefinedImports = new Set([ + // EOL subpaths + '#external/invalidsubpath/x', // Missing import '#missing', // Explicit null import diff --git a/test/es-module/test-esm-local-deprecations.mjs b/test/es-module/test-esm-local-deprecations.mjs deleted file mode 100644 index a9030b40912ddb..00000000000000 --- a/test/es-module/test-esm-local-deprecations.mjs +++ /dev/null @@ -1,37 +0,0 @@ -import '../common/index.mjs'; -import assert from 'assert'; -import fixtures from '../common/fixtures.js'; -import { pathToFileURL } from 'url'; - -const selfDeprecatedFolders = - fixtures.path('/es-modules/self-deprecated-folders/main.js'); - -const deprecatedFoldersIgnore = - fixtures.path('/es-modules/deprecated-folders-ignore/main.js'); - -const deprecatedTrailingSlashPattern = - fixtures.path('/es-modules/pattern-trailing-slash.mjs'); - -const expectedWarnings = [ - '"./" in the "exports" field', - '"#self/" in the "imports" field', - '"./folder/" in the "exports" field', - '"./trailing-pattern-slash/" in the "exports" field', -]; - -process.addListener('warning', (warning) => { - if (warning.stack.includes(expectedWarnings[0])) { - expectedWarnings.shift(); - } -}); - -process.on('exit', () => { - assert.deepStrictEqual(expectedWarnings, []); -}); - -(async () => { - await import(pathToFileURL(selfDeprecatedFolders)); - await import(pathToFileURL(deprecatedFoldersIgnore)); - await import(pathToFileURL(deprecatedTrailingSlashPattern)); -})() -.catch((err) => console.error(err)); diff --git a/test/fixtures/es-modules/pkgimports/package.json b/test/fixtures/es-modules/pkgimports/package.json index 299ce9c197b554..cebe36b350fa50 100644 --- a/test/fixtures/es-modules/pkgimports/package.json +++ b/test/fixtures/es-modules/pkgimports/package.json @@ -22,7 +22,7 @@ }, "default": "./test.js" }, - "#subpath/nullshadow/": [null], + "#subpath/nullshadow/*": [null], "#": "./test.js", "#/initialslash": "./test.js", "#notfound": "./notfound.js", diff --git a/test/fixtures/node_modules/pkgexports/package.json b/test/fixtures/node_modules/pkgexports/package.json index fe46111f793314..b686257875bc42 100644 --- a/test/fixtures/node_modules/pkgexports/package.json +++ b/test/fixtures/node_modules/pkgexports/package.json @@ -4,10 +4,9 @@ "./hole": "./lib/hole.js", "./space": "./sp%20ce.js", "./valid-cjs": "./asdf.js", - "./sub/": "./", - "./belowdir/": "../belowdir/", + "./sub/*": "./*", + "./belowdir/*": "../belowdir/*", "./belowfile": "../belowfile", - "./missingtrailer/": ".", "./null": null, "./null/": null, "./invalid1": {}, @@ -15,7 +14,7 @@ "./invalid3": "", "./invalid4": {}, "./invalid5": "invalid5.js", - "./fallbackdir/": [[], null, {}, "builtin:x/", "./fallbackfile", "./"], + "./fallbackdir/*": [[], null, {}, "builtin:x/*", "./*"], "./fallbackfile": [[], null, {}, "builtin:x", "./asdf.js"], "./nofallback1": [], "./nofallback2": [null, {}, "builtin:x"], @@ -58,7 +57,7 @@ "./a/*": "./subpath/*.js", "./a/b/": "./nomatch/", "./a/b*": "./subpath*.js", - "./subpath/": "./subpath/", + "./subpath/*": "./subpath/*", "./subpath/sub-*": "./subpath/dir1/*.js", "./subpath/sub-*.js": "./subpath/dir1/*.js", "./features/*": "./subpath/*/*.js", diff --git a/test/message/esm_display_syntax_error.mjs b/test/message/esm_display_syntax_error.mjs deleted file mode 100644 index 0b9a30c2d054f7..00000000000000 --- a/test/message/esm_display_syntax_error.mjs +++ /dev/null @@ -1,4 +0,0 @@ -// Flags: --no-harmony-top-level-await - -'use strict'; -await async () => 0; diff --git a/test/message/esm_display_syntax_error.out b/test/message/esm_display_syntax_error.out deleted file mode 100644 index 46db263e67181f..00000000000000 --- a/test/message/esm_display_syntax_error.out +++ /dev/null @@ -1,10 +0,0 @@ -file:///*/test/message/esm_display_syntax_error.mjs:4 -await async () => 0; -^^^^^ - -SyntaxError: Unexpected reserved word - at ESMLoader.moduleStrategy (node:internal/modules/esm/translators:*:*) - at ESMLoader.moduleProvider (node:internal/modules/esm/loader:*:*) - at async link (node:internal/modules/esm/module_job:*:*) - -Node.js * diff --git a/test/parallel/test-dgram-udp6-link-local-address.js b/test/parallel/test-dgram-udp6-link-local-address.js index bb7307de2430db..5c090acc6b9e11 100644 --- a/test/parallel/test-dgram-udp6-link-local-address.js +++ b/test/parallel/test-dgram-udp6-link-local-address.js @@ -7,6 +7,8 @@ const assert = require('assert'); const dgram = require('dgram'); const os = require('os'); +const { isWindows } = common; + function linklocal() { for (const [ifname, entries] of Object.entries(os.networkInterfaces())) { for (const { address, family, scopeid } of entries) { @@ -21,7 +23,7 @@ const iface = linklocal(); if (!iface) common.skip('cannot find any IPv6 interfaces with a link local address'); -const address = `${iface.address}%${iface.ifname}`; +const address = isWindows ? iface.address : `${iface.address}%${iface.ifname}`; const message = 'Hello, local world!'; // Create a client socket for sending to the link-local address. @@ -42,7 +44,7 @@ server.on('message', common.mustCall((buf, info) => { // including the link local scope identifier. assert.strictEqual( info.address, - common.isWindows ? `${iface.address}%${iface.scopeid}` : address + isWindows ? `${iface.address}%${iface.scopeid}` : address ); server.close(); client.close(); diff --git a/test/parallel/test-eventtarget.js b/test/parallel/test-eventtarget.js index cfad9c60a32c01..d3b1ee7358a104 100644 --- a/test/parallel/test-eventtarget.js +++ b/test/parallel/test-eventtarget.js @@ -186,6 +186,22 @@ let asyncTest = Promise.resolve(); deepStrictEqual(event.composedPath(), []); + eventTarget2.dispatchEvent(event); + strictEqual(event.eventPhase, Event.NONE); + strictEqual(event.target, eventTarget2); + deepStrictEqual(event.composedPath(), []); +} +{ + // Same event dispatched multiple times, without listeners added. + const event = new Event('foo'); + const eventTarget1 = new EventTarget(); + const eventTarget2 = new EventTarget(); + + eventTarget1.dispatchEvent(event); + strictEqual(event.eventPhase, Event.NONE); + strictEqual(event.target, eventTarget1); + deepStrictEqual(event.composedPath(), []); + eventTarget2.dispatchEvent(event); strictEqual(event.eventPhase, Event.NONE); strictEqual(event.target, eventTarget2); diff --git a/test/parallel/test-fs-promises-file-handle-stream.js b/test/parallel/test-fs-promises-file-handle-stream.js new file mode 100644 index 00000000000000..71f312b6f9d78c --- /dev/null +++ b/test/parallel/test-fs-promises-file-handle-stream.js @@ -0,0 +1,48 @@ +'use strict'; + +const common = require('../common'); + +// The following tests validate base functionality for the fs.promises +// FileHandle.write method. + +const fs = require('fs'); +const { open } = fs.promises; +const path = require('path'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const { finished } = require('stream/promises'); +const { buffer } = require('stream/consumers'); +const tmpDir = tmpdir.path; + +tmpdir.refresh(); + +async function validateWrite() { + const filePathForHandle = path.resolve(tmpDir, 'tmp-write.txt'); + const fileHandle = await open(filePathForHandle, 'w'); + const buffer = Buffer.from('Hello world'.repeat(100), 'utf8'); + + const stream = fileHandle.createWriteStream(); + stream.end(buffer); + await finished(stream); + + const readFileData = fs.readFileSync(filePathForHandle); + assert.deepStrictEqual(buffer, readFileData); +} + +async function validateRead() { + const filePathForHandle = path.resolve(tmpDir, 'tmp-read.txt'); + const buf = Buffer.from('Hello world'.repeat(100), 'utf8'); + + fs.writeFileSync(filePathForHandle, buf); + + const fileHandle = await open(filePathForHandle); + assert.deepStrictEqual( + await buffer(fileHandle.createReadStream()), + buf + ); +} + +Promise.all([ + validateWrite(), + validateRead(), +]).then(common.mustCall()); diff --git a/test/parallel/test-http-server-keep-alive-defaults.js b/test/parallel/test-http-server-keep-alive-defaults.js new file mode 100644 index 00000000000000..6f3abc30b573a2 --- /dev/null +++ b/test/parallel/test-http-server-keep-alive-defaults.js @@ -0,0 +1,76 @@ +'use strict'; + +const common = require('../common'); +const net = require('net'); +const http = require('http'); +const assert = require('assert'); + +const bodySent = 'This is my request'; + +function assertResponse(headers, body, expectClosed) { + assert.match(headers, /Connection: keep-alive\r\n/m); + assert.match(headers, /Keep-Alive: timeout=5\r\n/m); + assert.match(body, /Hello World!/m); +} + +function writeRequest(socket) { + socket.write('POST / HTTP/1.1\r\n'); + socket.write('Connection: keep-alive\r\n'); + socket.write('Content-Type: text/plain\r\n'); + socket.write(`Content-Length: ${bodySent.length}\r\n\r\n`); + socket.write(`${bodySent}\r\n`); + socket.write('\r\n\r\n'); +} + +const server = http.createServer((req, res) => { + let body = ''; + req.on('data', (data) => { + body += data; + }); + + req.on('end', () => { + if (req.method === 'POST') { + assert.strictEqual(bodySent, body); + } + + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('Hello World!'); + res.end(); + }); +}); + +server.listen(0, common.mustCall((res) => { + assert.strictEqual(server.maxRequestsPerSocket, 0); + + const socket = new net.Socket(); + + socket.on('end', common.mustCall(() => { + server.close(); + })); + + socket.on('ready', common.mustCall(() => { + writeRequest(socket); + writeRequest(socket); + writeRequest(socket); + writeRequest(socket); + })); + + let buffer = ''; + + socket.on('data', (data) => { + buffer += data; + + const responseParts = buffer.trim().split('\r\n\r\n'); + + if (responseParts.length === 8) { + assertResponse(responseParts[0], responseParts[1]); + assertResponse(responseParts[2], responseParts[3]); + assertResponse(responseParts[4], responseParts[5]); + assertResponse(responseParts[6], responseParts[7]); + + socket.end(); + } + }); + + socket.connect({ port: server.address().port }); +})); diff --git a/test/parallel/test-http-server-keep-alive-max-requests-null.js b/test/parallel/test-http-server-keep-alive-max-requests-null.js new file mode 100644 index 00000000000000..fee882be856290 --- /dev/null +++ b/test/parallel/test-http-server-keep-alive-max-requests-null.js @@ -0,0 +1,75 @@ +'use strict'; + +const common = require('../common'); +const net = require('net'); +const http = require('http'); +const assert = require('assert'); + +const bodySent = 'This is my request'; + +function assertResponse(headers, body, expectClosed) { + assert.match(headers, /Connection: keep-alive\r\n/m); + assert.match(headers, /Keep-Alive: timeout=5\r\n/m); + assert.match(body, /Hello World!/m); +} + +function writeRequest(socket) { + socket.write('POST / HTTP/1.1\r\n'); + socket.write('Connection: keep-alive\r\n'); + socket.write('Content-Type: text/plain\r\n'); + socket.write(`Content-Length: ${bodySent.length}\r\n\r\n`); + socket.write(`${bodySent}\r\n`); + socket.write('\r\n\r\n'); +} + +const server = http.createServer((req, res) => { + let body = ''; + req.on('data', (data) => { + body += data; + }); + + req.on('end', () => { + if (req.method === 'POST') { + assert.strictEqual(bodySent, body); + } + + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('Hello World!'); + res.end(); + }); +}); + +server.maxRequestsPerSocket = null; +server.listen(0, common.mustCall((res) => { + const socket = new net.Socket(); + + socket.on('end', common.mustCall(() => { + server.close(); + })); + + socket.on('ready', common.mustCall(() => { + writeRequest(socket); + writeRequest(socket); + writeRequest(socket); + writeRequest(socket); + })); + + let buffer = ''; + + socket.on('data', (data) => { + buffer += data; + + const responseParts = buffer.trim().split('\r\n\r\n'); + + if (responseParts.length === 8) { + assertResponse(responseParts[0], responseParts[1]); + assertResponse(responseParts[2], responseParts[3]); + assertResponse(responseParts[4], responseParts[5]); + assertResponse(responseParts[6], responseParts[7]); + + socket.end(); + } + }); + + socket.connect({ port: server.address().port }); +})); diff --git a/test/parallel/test-http2-methods.js b/test/parallel/test-http2-methods.js index 143b50b66b4dff..936a264e990843 100644 --- a/test/parallel/test-http2-methods.js +++ b/test/parallel/test-http2-methods.js @@ -8,7 +8,7 @@ const h2 = require('http2'); const server = h2.createServer(); -const methods = [undefined, 'GET', 'POST', 'PATCH', 'FOO', 'A B C']; +const methods = ['GET', 'POST', 'PATCH', 'FOO', 'A_B_C']; let expected = methods.length; // We use the lower-level API here diff --git a/test/parallel/test-http2-multiplex.js b/test/parallel/test-http2-multiplex.js index 1778bced5f92f4..4c157d0edeec71 100644 --- a/test/parallel/test-http2-multiplex.js +++ b/test/parallel/test-http2-multiplex.js @@ -29,7 +29,7 @@ server.listen(0, common.mustCall(() => { }); function doRequest() { - const req = client.request({ ':method': 'POST ' }); + const req = client.request({ ':method': 'POST' }); let data = ''; req.setEncoding('utf8'); diff --git a/test/parallel/test-no-harmony-top-level-await.mjs b/test/parallel/test-no-harmony-top-level-await.mjs deleted file mode 100644 index 5805af0e5ee265..00000000000000 --- a/test/parallel/test-no-harmony-top-level-await.mjs +++ /dev/null @@ -1,8 +0,0 @@ -// Flags: --no-harmony-top-level-await - -import { - mustCall, -} from '../common/index.mjs'; - -process.on('unhandledRejection', mustCall()); -Promise.reject(new Error('should not be fatal error')); diff --git a/test/parallel/test-repl-preprocess-top-level-await.js b/test/parallel/test-repl-preprocess-top-level-await.js index 656b616b71d9e6..51b15e107f53bc 100644 --- a/test/parallel/test-repl-preprocess-top-level-await.js +++ b/test/parallel/test-repl-preprocess-top-level-await.js @@ -22,6 +22,8 @@ const testCases = [ `(async () => { return (await ${surrogate}) })()` ], [ 'await 0;', '(async () => { return (await 0); })()' ], + [ 'await 0;;;', + '(async () => { return (await 0);;; })()' ], [ `await ${surrogate};`, `(async () => { return (await ${surrogate}); })()` ], [ `await ${surrogate};`, diff --git a/test/wasi/README.md b/test/wasi/README.md index ccb02d095ef939..87ea3fb0549cff 100644 --- a/test/wasi/README.md +++ b/test/wasi/README.md @@ -3,6 +3,7 @@ Compile with clang and `wasm32-wasi` target. The clang version used must be built with wasi-libc. You can specify the location for clang and the sysroot if needed when running make: + ```console $ make CC=/usr/local/opt/llvm/bin/clang SYSROOT=/path/to/wasi-libc/sysroot ``` diff --git a/test/wpt/README.md b/test/wpt/README.md index ec30c2176849a7..b8ded27ef37d78 100644 --- a/test/wpt/README.md +++ b/test/wpt/README.md @@ -15,6 +15,7 @@ WPT harness and have automatic updates. There are also a few This folder covers the tests that have been migrated. + ## How to add tests for a new module ### 1. Create a status file @@ -142,6 +143,7 @@ skipping tests that cannot be run because of lack of dependency or expected failures. + ## Format of a status JSON file ```text diff --git a/tools/.eslintrc.yaml b/tools/.eslintrc.yaml index b98c59a15c1b77..d2fe553393693d 100644 --- a/tools/.eslintrc.yaml +++ b/tools/.eslintrc.yaml @@ -8,6 +8,8 @@ rules: - properties: 'never' ignoreDestructuring: true allow: ['child_process'] - no-unused-vars: [error, { args: 'after-used' }] + no-unused-vars: + - error + - args: 'after-used' prefer-arrow-callback: error no-var: error diff --git a/tools/code_cache/mkcodecache.cc b/tools/code_cache/mkcodecache.cc index 3a1d0ee50e5078..9a0127184372bc 100644 --- a/tools/code_cache/mkcodecache.cc +++ b/tools/code_cache/mkcodecache.cc @@ -28,7 +28,6 @@ int main(int argc, char* argv[]) { #endif // _WIN32 v8::V8::SetFlagsFromString("--random_seed=42"); - v8::V8::SetFlagsFromString("--harmony-top-level-await"); if (argc < 2) { std::cerr << "Usage: " << argv[0] << " \n"; diff --git a/tools/find-inactive-collaborators.mjs b/tools/find-inactive-collaborators.mjs index 5f0173564b69af..3925f210e7c5e3 100755 --- a/tools/find-inactive-collaborators.mjs +++ b/tools/find-inactive-collaborators.mjs @@ -115,7 +115,7 @@ async function moveCollaboratorToEmeritus(peopleToMove) { // the list, print out the remaining entries to be moved because they come // alphabetically after the last item. if (inCollaboratorEmeritusSection && line === '' && - fileContents.endsWith('>\n')) { + fileContents.endsWith('>\n')) { while (textToMove.length) { fileContents += textToMove.pop(); } diff --git a/tools/icu/README.md b/tools/icu/README.md index ab90b760b8c844..544f4bf2152ff0 100644 --- a/tools/icu/README.md +++ b/tools/icu/README.md @@ -11,13 +11,14 @@ Both V8 and Node.js use ICU to provide internationalization functionality. * `icu-generic.gyp` is the build file used for most ICU builds within ICU. * `icu-system.gyp` is an alternate build file used when `--with-intl=system-icu` - is invoked. It builds against the `pkg-config` located ICU. + is invoked. It builds against the `pkg-config` located ICU. * `iculslocs.cc` is source for the `iculslocs` utility, invoked by `icutrim.py` - as part of repackaging. Not used separately. See source for more details. + as part of repackaging. Not used separately. See source for more details. * `no-op.cc` contains an empty function to convince gyp to use a C++ compiler. * `shrink-icu-src.py` is used during upgrade (see guide below). Note: + > The files in this directory were written for the Node.js v0.12 effort. > The original intent was to merge the tools such as `icutrim.py` and `iculslocs.cc` > back into ICU. ICU has gained its own “data slicer” tool. @@ -27,10 +28,11 @@ Note: ## See Also * [docs/guides/maintaining-icu.md](../../doc/guides/maintaining-icu.md) for -information on maintaining ICU in Node.js + information on maintaining ICU in Node.js * [docs/api/intl.md](../../doc/api/intl.md) for information on the -internationalization-related APIs in Node.js + internationalization-related APIs in Node.js + * [The ICU Homepage][ICU] [ICU]: http://icu-project.org diff --git a/tools/lint-md.mjs b/tools/lint-md.mjs deleted file mode 100644 index f5e5a47a30e98b..00000000000000 --- a/tools/lint-md.mjs +++ /dev/null @@ -1,56085 +0,0 @@ -import path$b from 'path'; -import process$1 from 'process'; -import { URL as URL$1, fileURLToPath, pathToFileURL } from 'url'; -import require$$0$3, { realpathSync as realpathSync$1, statSync, Stats } from 'fs'; -import process$2 from 'node:process'; -import stream, { PassThrough } from 'node:stream'; -import require$$0$2 from 'os'; -import tty$1 from 'tty'; -import require$$0$5 from 'events'; -import require$$0$4, { format as format$2, inspect as inspect$1 } from 'util'; -import require$$1 from 'stream'; -import path$c from 'node:path'; -import { pathToFileURL as pathToFileURL$1 } from 'node:url'; -import assert$2 from 'assert'; -import fs$a from 'node:fs'; -import { EventEmitter as EventEmitter$1 } from 'node:events'; - -var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -function getAugmentedNamespace(n) { - if (n.__esModule) return n; - var a = Object.defineProperty({}, '__esModule', {value: true}); - Object.keys(n).forEach(function (k) { - var d = Object.getOwnPropertyDescriptor(n, k); - Object.defineProperty(a, k, d.get ? d : { - enumerable: true, - get: function () { - return n[k]; - } - }); - }); - return a; -} - -function commonjsRequire (path) { - throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); -} - -var ansiStyles$2 = {exports: {}}; - -var colorName$1 = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -/* MIT license */ - -/* eslint-disable no-mixed-operators */ -const cssKeywords$1 = colorName$1; - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -const reverseKeywords$1 = {}; -for (const key of Object.keys(cssKeywords$1)) { - reverseKeywords$1[cssKeywords$1[key]] = key; -} - -const convert$4 = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -var conversions$5 = convert$4; - -// Hide .channels and .labels properties -for (const model of Object.keys(convert$4)) { - if (!('channels' in convert$4[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert$4[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert$4[model].labels.length !== convert$4[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - const {channels, labels} = convert$4[model]; - delete convert$4[model].channels; - delete convert$4[model].labels; - Object.defineProperty(convert$4[model], 'channels', {value: channels}); - Object.defineProperty(convert$4[model], 'labels', {value: labels}); -} - -convert$4.rgb.hsl = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const min = Math.min(r, g, b); - const max = Math.max(r, g, b); - const delta = max - min; - let h; - let s; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - - const l = (min + max) / 2; - - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - - return [h, s * 100, l * 100]; -}; - -convert$4.rgb.hsv = function (rgb) { - let rdif; - let gdif; - let bdif; - let h; - let s; - - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const v = Math.max(r, g, b); - const diff = v - Math.min(r, g, b); - const diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - - if (diff === 0) { - h = 0; - s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); - - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } - - return [ - h * 360, - s * 100, - v * 100 - ]; -}; - -convert$4.rgb.hwb = function (rgb) { - const r = rgb[0]; - const g = rgb[1]; - let b = rgb[2]; - const h = convert$4.rgb.hsl(rgb)[0]; - const w = 1 / 255 * Math.min(r, Math.min(g, b)); - - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -}; - -convert$4.rgb.cmyk = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - - const k = Math.min(1 - r, 1 - g, 1 - b); - const c = (1 - r - k) / (1 - k) || 0; - const m = (1 - g - k) / (1 - k) || 0; - const y = (1 - b - k) / (1 - k) || 0; - - return [c * 100, m * 100, y * 100, k * 100]; -}; - -function comparativeDistance$1(x, y) { - /* - See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - */ - return ( - ((x[0] - y[0]) ** 2) + - ((x[1] - y[1]) ** 2) + - ((x[2] - y[2]) ** 2) - ); -} - -convert$4.rgb.keyword = function (rgb) { - const reversed = reverseKeywords$1[rgb]; - if (reversed) { - return reversed; - } - - let currentClosestDistance = Infinity; - let currentClosestKeyword; - - for (const keyword of Object.keys(cssKeywords$1)) { - const value = cssKeywords$1[keyword]; - - // Compute comparative distance - const distance = comparativeDistance$1(rgb, value); - - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - - return currentClosestKeyword; -}; - -convert$4.keyword.rgb = function (keyword) { - return cssKeywords$1[keyword]; -}; - -convert$4.rgb.xyz = function (rgb) { - let r = rgb[0] / 255; - let g = rgb[1] / 255; - let b = rgb[2] / 255; - - // Assume sRGB - r = r > 0.04045 ? (((r + 0.055) / 1.055) ** 2.4) : (r / 12.92); - g = g > 0.04045 ? (((g + 0.055) / 1.055) ** 2.4) : (g / 12.92); - b = b > 0.04045 ? (((b + 0.055) / 1.055) ** 2.4) : (b / 12.92); - - const x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - const y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - const z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y * 100, z * 100]; -}; - -convert$4.rgb.lab = function (rgb) { - const xyz = convert$4.rgb.xyz(rgb); - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$4.hsl.rgb = function (hsl) { - const h = hsl[0] / 360; - const s = hsl[1] / 100; - const l = hsl[2] / 100; - let t2; - let t3; - let val; - - if (s === 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - - const t1 = 2 * l - t2; - - const rgb = [0, 0, 0]; - for (let i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - - if (t3 > 1) { - t3--; - } - - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } - - rgb[i] = val * 255; - } - - return rgb; -}; - -convert$4.hsl.hsv = function (hsl) { - const h = hsl[0]; - let s = hsl[1] / 100; - let l = hsl[2] / 100; - let smin = s; - const lmin = Math.max(l, 0.01); - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - const v = (l + s) / 2; - const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - - return [h, sv * 100, v * 100]; -}; - -convert$4.hsv.rgb = function (hsv) { - const h = hsv[0] / 60; - const s = hsv[1] / 100; - let v = hsv[2] / 100; - const hi = Math.floor(h) % 6; - - const f = h - Math.floor(h); - const p = 255 * v * (1 - s); - const q = 255 * v * (1 - (s * f)); - const t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; - -convert$4.hsv.hsl = function (hsv) { - const h = hsv[0]; - const s = hsv[1] / 100; - const v = hsv[2] / 100; - const vmin = Math.max(v, 0.01); - let sl; - let l; - - l = (2 - s) * v; - const lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; - - return [h, sl * 100, l * 100]; -}; - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert$4.hwb.rgb = function (hwb) { - const h = hwb[0] / 360; - let wh = hwb[1] / 100; - let bl = hwb[2] / 100; - const ratio = wh + bl; - let f; - - // Wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - const i = Math.floor(6 * h); - const v = 1 - bl; - f = 6 * h - i; - - if ((i & 0x01) !== 0) { - f = 1 - f; - } - - const n = wh + f * (v - wh); // Linear interpolation - - let r; - let g; - let b; - /* eslint-disable max-statements-per-line,no-multi-spaces */ - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - /* eslint-enable max-statements-per-line,no-multi-spaces */ - - return [r * 255, g * 255, b * 255]; -}; - -convert$4.cmyk.rgb = function (cmyk) { - const c = cmyk[0] / 100; - const m = cmyk[1] / 100; - const y = cmyk[2] / 100; - const k = cmyk[3] / 100; - - const r = 1 - Math.min(1, c * (1 - k) + k); - const g = 1 - Math.min(1, m * (1 - k) + k); - const b = 1 - Math.min(1, y * (1 - k) + k); - - return [r * 255, g * 255, b * 255]; -}; - -convert$4.xyz.rgb = function (xyz) { - const x = xyz[0] / 100; - const y = xyz[1] / 100; - const z = xyz[2] / 100; - let r; - let g; - let b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // Assume sRGB - r = r > 0.0031308 - ? ((1.055 * (r ** (1.0 / 2.4))) - 0.055) - : r * 12.92; - - g = g > 0.0031308 - ? ((1.055 * (g ** (1.0 / 2.4))) - 0.055) - : g * 12.92; - - b = b > 0.0031308 - ? ((1.055 * (b ** (1.0 / 2.4))) - 0.055) - : b * 12.92; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -}; - -convert$4.xyz.lab = function (xyz) { - let x = xyz[0]; - let y = xyz[1]; - let z = xyz[2]; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? (x ** (1 / 3)) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? (y ** (1 / 3)) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? (z ** (1 / 3)) : (7.787 * z) + (16 / 116); - - const l = (116 * y) - 16; - const a = 500 * (x - y); - const b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$4.lab.xyz = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let x; - let y; - let z; - - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; - - const y2 = y ** 3; - const x2 = x ** 3; - const z2 = z ** 3; - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - - x *= 95.047; - y *= 100; - z *= 108.883; - - return [x, y, z]; -}; - -convert$4.lab.lch = function (lab) { - const l = lab[0]; - const a = lab[1]; - const b = lab[2]; - let h; - - const hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - - if (h < 0) { - h += 360; - } - - const c = Math.sqrt(a * a + b * b); - - return [l, c, h]; -}; - -convert$4.lch.lab = function (lch) { - const l = lch[0]; - const c = lch[1]; - const h = lch[2]; - - const hr = h / 360 * 2 * Math.PI; - const a = c * Math.cos(hr); - const b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert$4.rgb.ansi16 = function (args, saturation = null) { - const [r, g, b] = args; - let value = saturation === null ? convert$4.rgb.hsv(args)[2] : saturation; // Hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; - } - - let ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - - if (value === 2) { - ansi += 60; - } - - return ansi; -}; - -convert$4.hsv.ansi16 = function (args) { - // Optimization here; we already know the value and don't need to get - // it converted for us. - return convert$4.rgb.ansi16(convert$4.hsv.rgb(args), args[2]); -}; - -convert$4.rgb.ansi256 = function (args) { - const r = args[0]; - const g = args[1]; - const b = args[2]; - - // We use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } - - if (r > 248) { - return 231; - } - - return Math.round(((r - 8) / 247) * 24) + 232; - } - - const ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - - return ansi; -}; - -convert$4.ansi16.rgb = function (args) { - let color = args % 10; - - // Handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } - - color = color / 10.5 * 255; - - return [color, color, color]; - } - - const mult = (~~(args > 50) + 1) * 0.5; - const r = ((color & 1) * mult) * 255; - const g = (((color >> 1) & 1) * mult) * 255; - const b = (((color >> 2) & 1) * mult) * 255; - - return [r, g, b]; -}; - -convert$4.ansi256.rgb = function (args) { - // Handle greyscale - if (args >= 232) { - const c = (args - 232) * 10 + 8; - return [c, c, c]; - } - - args -= 16; - - let rem; - const r = Math.floor(args / 36) / 5 * 255; - const g = Math.floor((rem = args % 36) / 6) / 5 * 255; - const b = (rem % 6) / 5 * 255; - - return [r, g, b]; -}; - -convert$4.rgb.hex = function (args) { - const integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$4.hex.rgb = function (args) { - const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - - let colorString = match[0]; - - if (match[0].length === 3) { - colorString = colorString.split('').map(char => { - return char + char; - }).join(''); - } - - const integer = parseInt(colorString, 16); - const r = (integer >> 16) & 0xFF; - const g = (integer >> 8) & 0xFF; - const b = integer & 0xFF; - - return [r, g, b]; -}; - -convert$4.rgb.hcg = function (rgb) { - const r = rgb[0] / 255; - const g = rgb[1] / 255; - const b = rgb[2] / 255; - const max = Math.max(Math.max(r, g), b); - const min = Math.min(Math.min(r, g), b); - const chroma = (max - min); - let grayscale; - let hue; - - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } - - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma; - } - - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; -}; - -convert$4.hsl.hcg = function (hsl) { - const s = hsl[1] / 100; - const l = hsl[2] / 100; - - const c = l < 0.5 ? (2.0 * s * l) : (2.0 * s * (1.0 - l)); - - let f = 0; - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } - - return [hsl[0], c * 100, f * 100]; -}; - -convert$4.hsv.hcg = function (hsv) { - const s = hsv[1] / 100; - const v = hsv[2] / 100; - - const c = s * v; - let f = 0; - - if (c < 1.0) { - f = (v - c) / (1 - c); - } - - return [hsv[0], c * 100, f * 100]; -}; - -convert$4.hcg.rgb = function (hcg) { - const h = hcg[0] / 360; - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } - - const pure = [0, 0, 0]; - const hi = (h % 1) * 6; - const v = hi % 1; - const w = 1 - v; - let mg = 0; - - /* eslint-disable max-statements-per-line */ - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - /* eslint-enable max-statements-per-line */ - - mg = (1.0 - c) * g; - - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; - -convert$4.hcg.hsv = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - const v = c + g * (1.0 - c); - let f = 0; - - if (v > 0.0) { - f = c / v; - } - - return [hcg[0], f * 100, v * 100]; -}; - -convert$4.hcg.hsl = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - - const l = g * (1.0 - c) + 0.5 * c; - let s = 0; - - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } - - return [hcg[0], s * 100, l * 100]; -}; - -convert$4.hcg.hwb = function (hcg) { - const c = hcg[1] / 100; - const g = hcg[2] / 100; - const v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; - -convert$4.hwb.hcg = function (hwb) { - const w = hwb[1] / 100; - const b = hwb[2] / 100; - const v = 1 - b; - const c = v - w; - let g = 0; - - if (c < 1) { - g = (v - c) / (1 - c); - } - - return [hwb[0], c * 100, g * 100]; -}; - -convert$4.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; - -convert$4.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; - -convert$4.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; - -convert$4.gray.hsl = function (args) { - return [0, 0, args[0]]; -}; - -convert$4.gray.hsv = convert$4.gray.hsl; - -convert$4.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; - -convert$4.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; - -convert$4.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; - -convert$4.gray.hex = function (gray) { - const val = Math.round(gray[0] / 100 * 255) & 0xFF; - const integer = (val << 16) + (val << 8) + val; - - const string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$4.rgb.gray = function (rgb) { - const val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; - -const conversions$4 = conversions$5; - -/* - This function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/ - -function buildGraph$1() { - const graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - const models = Object.keys(conversions$4); - - for (let len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } - - return graph; -} - -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS$1(fromModel) { - const graph = buildGraph$1(); - const queue = [fromModel]; // Unshift -> queue -> pop - - graph[fromModel].distance = 0; - - while (queue.length) { - const current = queue.pop(); - const adjacents = Object.keys(conversions$4[current]); - - for (let len = adjacents.length, i = 0; i < len; i++) { - const adjacent = adjacents[i]; - const node = graph[adjacent]; - - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } - - return graph; -} - -function link$2(from, to) { - return function (args) { - return to(from(args)); - }; -} - -function wrapConversion$1(toModel, graph) { - const path = [graph[toModel].parent, toModel]; - let fn = conversions$4[graph[toModel].parent][toModel]; - - let cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link$2(conversions$4[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -var route$3 = function (fromModel) { - const graph = deriveBFS$1(fromModel); - const conversion = {}; - - const models = Object.keys(graph); - for (let len = models.length, i = 0; i < len; i++) { - const toModel = models[i]; - const node = graph[toModel]; - - if (node.parent === null) { - // No possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion$1(toModel, graph); - } - - return conversion; -}; - -const conversions$3 = conversions$5; -const route$2 = route$3; - -const convert$3 = {}; - -const models$1 = Object.keys(conversions$3); - -function wrapRaw$1(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - if (arg0 === undefined || arg0 === null) { - return arg0; - } - - if (arg0.length > 1) { - args = arg0; - } - - return fn(args); - }; - - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded$1(fn) { - const wrappedFn = function (...args) { - const arg0 = args[0]; - - if (arg0 === undefined || arg0 === null) { - return arg0; - } - - if (arg0.length > 1) { - args = arg0; - } - - const result = fn(args); - - // We're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (let len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - - return result; - }; - - // Preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -models$1.forEach(fromModel => { - convert$3[fromModel] = {}; - - Object.defineProperty(convert$3[fromModel], 'channels', {value: conversions$3[fromModel].channels}); - Object.defineProperty(convert$3[fromModel], 'labels', {value: conversions$3[fromModel].labels}); - - const routes = route$2(fromModel); - const routeModels = Object.keys(routes); - - routeModels.forEach(toModel => { - const fn = routes[toModel]; - - convert$3[fromModel][toModel] = wrapRounded$1(fn); - convert$3[fromModel][toModel].raw = wrapRaw$1(fn); - }); -}); - -var colorConvert$1 = convert$3; - -(function (module) { - -const wrapAnsi16 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${code + offset}m`; -}; - -const wrapAnsi256 = (fn, offset) => (...args) => { - const code = fn(...args); - return `\u001B[${38 + offset};5;${code}m`; -}; - -const wrapAnsi16m = (fn, offset) => (...args) => { - const rgb = fn(...args); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; - -const ansi2ansi = n => n; -const rgb2rgb = (r, g, b) => [r, g, b]; - -const setLazyProperty = (object, property, get) => { - Object.defineProperty(object, property, { - get: () => { - const value = get(); - - Object.defineProperty(object, property, { - value, - enumerable: true, - configurable: true - }); - - return value; - }, - enumerable: true, - configurable: true - }); -}; - -/** @type {typeof import('color-convert')} */ -let colorConvert; -const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => { - if (colorConvert === undefined) { - colorConvert = colorConvert$1; - } - - const offset = isBackground ? 10 : 0; - const styles = {}; - - for (const [sourceSpace, suite] of Object.entries(colorConvert)) { - const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace; - if (sourceSpace === targetSpace) { - styles[name] = wrap(identity, offset); - } else if (typeof suite === 'object') { - styles[name] = wrap(suite[targetSpace], offset); - } - } - - return styles; -}; - -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - - // Bright color - blackBright: [90, 39], - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Alias bright black as gray (and grey) - styles.color.gray = styles.color.blackBright; - styles.bgColor.bgGray = styles.bgColor.bgBlackBright; - styles.color.grey = styles.color.blackBright; - styles.bgColor.bgGrey = styles.bgColor.bgBlackBright; - - for (const [groupName, group] of Object.entries(styles)) { - for (const [styleName, style] of Object.entries(group)) { - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - } - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false)); - setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false)); - setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true)); - setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true)); - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); -}(ansiStyles$2)); - -var hasFlag$4 = (flag, argv = process.argv) => { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -}; - -const os$2 = require$$0$2; -const tty = tty$1; -const hasFlag$3 = hasFlag$4; - -const {env: env$2} = process; - -let forceColor$1; -if (hasFlag$3('no-color') || - hasFlag$3('no-colors') || - hasFlag$3('color=false') || - hasFlag$3('color=never')) { - forceColor$1 = 0; -} else if (hasFlag$3('color') || - hasFlag$3('colors') || - hasFlag$3('color=true') || - hasFlag$3('color=always')) { - forceColor$1 = 1; -} - -if ('FORCE_COLOR' in env$2) { - if (env$2.FORCE_COLOR === 'true') { - forceColor$1 = 1; - } else if (env$2.FORCE_COLOR === 'false') { - forceColor$1 = 0; - } else { - forceColor$1 = env$2.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env$2.FORCE_COLOR, 10), 3); - } -} - -function translateLevel$2(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor$2(haveStream, streamIsTTY) { - if (forceColor$1 === 0) { - return 0; - } - - if (hasFlag$3('color=16m') || - hasFlag$3('color=full') || - hasFlag$3('color=truecolor')) { - return 3; - } - - if (hasFlag$3('color=256')) { - return 2; - } - - if (haveStream && !streamIsTTY && forceColor$1 === undefined) { - return 0; - } - - const min = forceColor$1 || 0; - - if (env$2.TERM === 'dumb') { - return min; - } - - if (process.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = os$2.release().split('.'); - if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env$2) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE'].some(sign => sign in env$2) || env$2.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env$2) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env$2.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env$2.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env$2) { - const version = parseInt((env$2.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env$2.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env$2.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env$2.TERM)) { - return 1; - } - - if ('COLORTERM' in env$2) { - return 1; - } - - return min; -} - -function getSupportLevel$1(stream) { - const level = supportsColor$2(stream, stream && stream.isTTY); - return translateLevel$2(level); -} - -var supportsColor_1$1 = { - supportsColor: getSupportLevel$1, - stdout: translateLevel$2(supportsColor$2(true, tty.isatty(1))), - stderr: translateLevel$2(supportsColor$2(true, tty.isatty(2))) -}; - -const stringReplaceAll$1 = (string, substring, replacer) => { - let index = string.indexOf(substring); - if (index === -1) { - return string; - } - - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ''; - do { - returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring, endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -const stringEncaseCRLFWithFirstIndex$1 = (string, prefix, postfix, index) => { - let endIndex = 0; - let returnValue = ''; - do { - const gotCR = string[index - 1] === '\r'; - returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - endIndex = index + 1; - index = string.indexOf('\n', endIndex); - } while (index !== -1); - - returnValue += string.substr(endIndex); - return returnValue; -}; - -var util$4 = { - stringReplaceAll: stringReplaceAll$1, - stringEncaseCRLFWithFirstIndex: stringEncaseCRLFWithFirstIndex$1 -}; - -const TEMPLATE_REGEX$1 = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX$1 = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX$1 = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX$1 = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES$1 = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape$1(c) { - const u = c[0] === 'u'; - const bracket = c[1] === '{'; - - if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - if (u && bracket) { - return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); - } - - return ESCAPES$1.get(c) || c; -} - -function parseArguments$1(name, arguments_) { - const results = []; - const chunks = arguments_.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - const number = Number(chunk); - if (!Number.isNaN(number)) { - results.push(number); - } else if ((matches = chunk.match(STRING_REGEX$1))) { - results.push(matches[2].replace(ESCAPE_REGEX$1, (m, escape, character) => escape ? unescape$1(escape) : character)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle$1(style) { - STYLE_REGEX$1.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX$1.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments$1(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; -} - -function buildStyle$1(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const [styleName, styles] of Object.entries(enabled)) { - if (!Array.isArray(styles)) { - continue; - } - - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; - } - - return current; -} - -var templates$1 = (chalk, temporary) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - temporary.replace(TEMPLATE_REGEX$1, (m, escapeCharacter, inverse, style, close, character) => { - if (escapeCharacter) { - chunk.push(unescape$1(escapeCharacter)); - } else if (style) { - const string = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? string : buildStyle$1(chalk, styles)(string)); - styles.push({inverse, styles: parseStyle$1(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle$1(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(character); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); - } - - return chunks.join(''); -}; - -const ansiStyles$1 = ansiStyles$2.exports; -const {stdout: stdoutColor, stderr: stderrColor} = supportsColor_1$1; -const { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -} = util$4; - -const {isArray: isArray$2} = Array; - -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = [ - 'ansi', - 'ansi', - 'ansi256', - 'ansi16m' -]; - -const styles = Object.create(null); - -const applyOptions = (object, options = {}) => { - if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { - throw new Error('The `level` option should be an integer from 0 to 3'); - } - - // Detect level if not set manually - const colorLevel = stdoutColor ? stdoutColor.level : 0; - object.level = options.level === undefined ? colorLevel : options.level; -}; - -class ChalkClass { - constructor(options) { - // eslint-disable-next-line no-constructor-return - return chalkFactory(options); - } -} - -const chalkFactory = options => { - const chalk = {}; - applyOptions(chalk, options); - - chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = () => { - throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); - }; - - chalk.template.Instance = ChalkClass; - - return chalk.template; -}; - -function Chalk(options) { - return chalkFactory(options); -} - -for (const [styleName, style] of Object.entries(ansiStyles$1)) { - styles[styleName] = { - get() { - const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); - Object.defineProperty(this, styleName, {value: builder}); - return builder; - } - }; -} - -styles.visible = { - get() { - const builder = createBuilder(this, this._styler, true); - Object.defineProperty(this, 'visible', {value: builder}); - return builder; - } -}; - -const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; - -for (const model of usedModels) { - styles[model] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles$1.color[levelMapping[level]][model](...arguments_), ansiStyles$1.color.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} - -for (const model of usedModels) { - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const {level} = this; - return function (...arguments_) { - const styler = createStyler(ansiStyles$1.bgColor[levelMapping[level]][model](...arguments_), ansiStyles$1.bgColor.close, this._styler); - return createBuilder(this, styler, this._isEmpty); - }; - } - }; -} - -const proto = Object.defineProperties(() => {}, { - ...styles, - level: { - enumerable: true, - get() { - return this._generator.level; - }, - set(level) { - this._generator.level = level; - } - } -}); - -const createStyler = (open, close, parent) => { - let openAll; - let closeAll; - if (parent === undefined) { - openAll = open; - closeAll = close; - } else { - openAll = parent.openAll + open; - closeAll = close + parent.closeAll; - } - - return { - open, - close, - openAll, - closeAll, - parent - }; -}; - -const createBuilder = (self, _styler, _isEmpty) => { - const builder = (...arguments_) => { - if (isArray$2(arguments_[0]) && isArray$2(arguments_[0].raw)) { - // Called as a template literal, for example: chalk.red`2 + 3 = {bold ${2+3}}` - return applyStyle(builder, chalkTag(builder, ...arguments_)); - } - - // Single argument is hot path, implicit coercion is faster than anything - // eslint-disable-next-line no-implicit-coercion - return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); - }; - - // We alter the prototype because we must return a function, but there is - // no way to create a function with a different prototype - Object.setPrototypeOf(builder, proto); - - builder._generator = self; - builder._styler = _styler; - builder._isEmpty = _isEmpty; - - return builder; -}; - -const applyStyle = (self, string) => { - if (self.level <= 0 || !string) { - return self._isEmpty ? '' : string; - } - - let styler = self._styler; - - if (styler === undefined) { - return string; - } - - const {openAll, closeAll} = styler; - if (string.indexOf('\u001B') !== -1) { - while (styler !== undefined) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - string = stringReplaceAll(string, styler.close, styler.open); - - styler = styler.parent; - } - } - - // We can move both next actions out of loop, because remaining actions in loop won't have - // any/visible effect on parts we add here. Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 - const lfIndex = string.indexOf('\n'); - if (lfIndex !== -1) { - string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); - } - - return openAll + string + closeAll; -}; - -let template; -const chalkTag = (chalk, ...strings) => { - const [firstString] = strings; - - if (!isArray$2(firstString) || !isArray$2(firstString.raw)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return strings.join(' '); - } - - const arguments_ = strings.slice(1); - const parts = [firstString.raw[0]]; - - for (let i = 1; i < firstString.length; i++) { - parts.push( - String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), - String(firstString.raw[i]) - ); - } - - if (template === undefined) { - template = templates$1; - } - - return template(chalk, parts.join('')); -}; - -Object.defineProperties(Chalk.prototype, styles); - -const chalk$1 = Chalk(); // eslint-disable-line new-cap -chalk$1.supportsColor = stdoutColor; -chalk$1.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap -chalk$1.stderr.supportsColor = stderrColor; - -var source$1 = chalk$1; - -var chokidar = {}; - -var utils$7 = {}; - -const path$a = path$b; -const WIN_SLASH = '\\\\/'; -const WIN_NO_SLASH = `[^${WIN_SLASH}]`; - -/** - * Posix glob regex - */ - -const DOT_LITERAL = '\\.'; -const PLUS_LITERAL = '\\+'; -const QMARK_LITERAL = '\\?'; -const SLASH_LITERAL = '\\/'; -const ONE_CHAR = '(?=.)'; -const QMARK = '[^/]'; -const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; -const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; -const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; -const NO_DOT = `(?!${DOT_LITERAL})`; -const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; -const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; -const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; -const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; -const STAR$1 = `${QMARK}*?`; - -const POSIX_CHARS = { - DOT_LITERAL, - PLUS_LITERAL, - QMARK_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - QMARK, - END_ANCHOR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK_NO_DOT, - STAR: STAR$1, - START_ANCHOR -}; - -/** - * Windows glob regex - */ - -const WINDOWS_CHARS = { - ...POSIX_CHARS, - - SLASH_LITERAL: `[${WIN_SLASH}]`, - QMARK: WIN_NO_SLASH, - STAR: `${WIN_NO_SLASH}*?`, - DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, - NO_DOT: `(?!${DOT_LITERAL})`, - NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, - NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, - QMARK_NO_DOT: `[^.${WIN_SLASH}]`, - START_ANCHOR: `(?:^|[${WIN_SLASH}])`, - END_ANCHOR: `(?:[${WIN_SLASH}]|$)` -}; - -/** - * POSIX Bracket Regex - */ - -const POSIX_REGEX_SOURCE$1 = { - alnum: 'a-zA-Z0-9', - alpha: 'a-zA-Z', - ascii: '\\x00-\\x7F', - blank: ' \\t', - cntrl: '\\x00-\\x1F\\x7F', - digit: '0-9', - graph: '\\x21-\\x7E', - lower: 'a-z', - print: '\\x20-\\x7E ', - punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', - space: ' \\t\\r\\n\\v\\f', - upper: 'A-Z', - word: 'A-Za-z0-9_', - xdigit: 'A-Fa-f0-9' -}; - -var constants$5 = { - MAX_LENGTH: 1024 * 64, - POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1, - - // regular expressions - REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, - REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, - REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, - REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, - REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, - REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, - - // Replace globs with equivalent patterns to reduce parsing time. - REPLACEMENTS: { - '***': '*', - '**/**': '**', - '**/**/**': '**' - }, - - // Digits - CHAR_0: 48, /* 0 */ - CHAR_9: 57, /* 9 */ - - // Alphabet chars. - CHAR_UPPERCASE_A: 65, /* A */ - CHAR_LOWERCASE_A: 97, /* a */ - CHAR_UPPERCASE_Z: 90, /* Z */ - CHAR_LOWERCASE_Z: 122, /* z */ - - CHAR_LEFT_PARENTHESES: 40, /* ( */ - CHAR_RIGHT_PARENTHESES: 41, /* ) */ - - CHAR_ASTERISK: 42, /* * */ - - // Non-alphabetic chars. - CHAR_AMPERSAND: 38, /* & */ - CHAR_AT: 64, /* @ */ - CHAR_BACKWARD_SLASH: 92, /* \ */ - CHAR_CARRIAGE_RETURN: 13, /* \r */ - CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ - CHAR_COLON: 58, /* : */ - CHAR_COMMA: 44, /* , */ - CHAR_DOT: 46, /* . */ - CHAR_DOUBLE_QUOTE: 34, /* " */ - CHAR_EQUAL: 61, /* = */ - CHAR_EXCLAMATION_MARK: 33, /* ! */ - CHAR_FORM_FEED: 12, /* \f */ - CHAR_FORWARD_SLASH: 47, /* / */ - CHAR_GRAVE_ACCENT: 96, /* ` */ - CHAR_HASH: 35, /* # */ - CHAR_HYPHEN_MINUS: 45, /* - */ - CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ - CHAR_LEFT_CURLY_BRACE: 123, /* { */ - CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ - CHAR_LINE_FEED: 10, /* \n */ - CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ - CHAR_PERCENT: 37, /* % */ - CHAR_PLUS: 43, /* + */ - CHAR_QUESTION_MARK: 63, /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ - CHAR_RIGHT_CURLY_BRACE: 125, /* } */ - CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ - CHAR_SEMICOLON: 59, /* ; */ - CHAR_SINGLE_QUOTE: 39, /* ' */ - CHAR_SPACE: 32, /* */ - CHAR_TAB: 9, /* \t */ - CHAR_UNDERSCORE: 95, /* _ */ - CHAR_VERTICAL_LINE: 124, /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ - - SEP: path$a.sep, - - /** - * Create EXTGLOB_CHARS - */ - - extglobChars(chars) { - return { - '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, - '?': { type: 'qmark', open: '(?:', close: ')?' }, - '+': { type: 'plus', open: '(?:', close: ')+' }, - '*': { type: 'star', open: '(?:', close: ')*' }, - '@': { type: 'at', open: '(?:', close: ')' } - }; - }, - - /** - * Create GLOB_CHARS - */ - - globChars(win32) { - return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; - } -}; - -(function (exports) { - -const path = path$b; -const win32 = process.platform === 'win32'; -const { - REGEX_BACKSLASH, - REGEX_REMOVE_BACKSLASH, - REGEX_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_GLOBAL -} = constants$5; - -exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); -exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); -exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); -exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); -exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); - -exports.removeBackslashes = str => { - return str.replace(REGEX_REMOVE_BACKSLASH, match => { - return match === '\\' ? '' : match; - }); -}; - -exports.supportsLookbehinds = () => { - const segs = process.version.slice(1).split('.').map(Number); - if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { - return true; - } - return false; -}; - -exports.isWindows = options => { - if (options && typeof options.windows === 'boolean') { - return options.windows; - } - return win32 === true || path.sep === '\\'; -}; - -exports.escapeLast = (input, char, lastIdx) => { - const idx = input.lastIndexOf(char, lastIdx); - if (idx === -1) return input; - if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); - return `${input.slice(0, idx)}\\${input.slice(idx)}`; -}; - -exports.removePrefix = (input, state = {}) => { - let output = input; - if (output.startsWith('./')) { - output = output.slice(2); - state.prefix = './'; - } - return output; -}; - -exports.wrapOutput = (input, state = {}, options = {}) => { - const prepend = options.contains ? '' : '^'; - const append = options.contains ? '' : '$'; - - let output = `${prepend}(?:${input})${append}`; - if (state.negated === true) { - output = `(?:^(?!${output}).*$)`; - } - return output; -}; -}(utils$7)); - -const utils$6 = utils$7; -const { - CHAR_ASTERISK: CHAR_ASTERISK$1, /* * */ - CHAR_AT, /* @ */ - CHAR_BACKWARD_SLASH, /* \ */ - CHAR_COMMA: CHAR_COMMA$2, /* , */ - CHAR_DOT: CHAR_DOT$1, /* . */ - CHAR_EXCLAMATION_MARK, /* ! */ - CHAR_FORWARD_SLASH, /* / */ - CHAR_LEFT_CURLY_BRACE: CHAR_LEFT_CURLY_BRACE$1, /* { */ - CHAR_LEFT_PARENTHESES: CHAR_LEFT_PARENTHESES$1, /* ( */ - CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$2, /* [ */ - CHAR_PLUS, /* + */ - CHAR_QUESTION_MARK, /* ? */ - CHAR_RIGHT_CURLY_BRACE: CHAR_RIGHT_CURLY_BRACE$1, /* } */ - CHAR_RIGHT_PARENTHESES: CHAR_RIGHT_PARENTHESES$1, /* ) */ - CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$2 /* ] */ -} = constants$5; - -const isPathSeparator = code => { - return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; -}; - -const depth = token => { - if (token.isPrefix !== true) { - token.depth = token.isGlobstar ? Infinity : 1; - } -}; - -/** - * Quickly scans a glob pattern and returns an object with a handful of - * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), - * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not - * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). - * - * ```js - * const pm = require('picomatch'); - * console.log(pm.scan('foo/bar/*.js')); - * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {Object} Returns an object with tokens and regex source string. - * @api public - */ - -const scan$1 = (input, options) => { - const opts = options || {}; - - const length = input.length - 1; - const scanToEnd = opts.parts === true || opts.scanToEnd === true; - const slashes = []; - const tokens = []; - const parts = []; - - let str = input; - let index = -1; - let start = 0; - let lastIndex = 0; - let isBrace = false; - let isBracket = false; - let isGlob = false; - let isExtglob = false; - let isGlobstar = false; - let braceEscaped = false; - let backslashes = false; - let negated = false; - let negatedExtglob = false; - let finished = false; - let braces = 0; - let prev; - let code; - let token = { value: '', depth: 0, isGlob: false }; - - const eos = () => index >= length; - const peek = () => str.charCodeAt(index + 1); - const advance = () => { - prev = code; - return str.charCodeAt(++index); - }; - - while (index < length) { - code = advance(); - let next; - - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - - if (code === CHAR_LEFT_CURLY_BRACE$1) { - braceEscaped = true; - } - continue; - } - - if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE$1) { - braces++; - - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } - - if (code === CHAR_LEFT_CURLY_BRACE$1) { - braces++; - continue; - } - - if (braceEscaped !== true && code === CHAR_DOT$1 && (code = advance()) === CHAR_DOT$1) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (braceEscaped !== true && code === CHAR_COMMA$2) { - isBrace = token.isBrace = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (code === CHAR_RIGHT_CURLY_BRACE$1) { - braces--; - - if (braces === 0) { - braceEscaped = false; - isBrace = token.isBrace = true; - finished = true; - break; - } - } - } - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (code === CHAR_FORWARD_SLASH) { - slashes.push(index); - tokens.push(token); - token = { value: '', depth: 0, isGlob: false }; - - if (finished === true) continue; - if (prev === CHAR_DOT$1 && index === (start + 1)) { - start += 2; - continue; - } - - lastIndex = index + 1; - continue; - } - - if (opts.noext !== true) { - const isExtglobChar = code === CHAR_PLUS - || code === CHAR_AT - || code === CHAR_ASTERISK$1 - || code === CHAR_QUESTION_MARK - || code === CHAR_EXCLAMATION_MARK; - - if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES$1) { - isGlob = token.isGlob = true; - isExtglob = token.isExtglob = true; - finished = true; - if (code === CHAR_EXCLAMATION_MARK && index === start) { - negatedExtglob = true; - } - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - - if (code === CHAR_RIGHT_PARENTHESES$1) { - isGlob = token.isGlob = true; - finished = true; - break; - } - } - continue; - } - break; - } - } - - if (code === CHAR_ASTERISK$1) { - if (prev === CHAR_ASTERISK$1) isGlobstar = token.isGlobstar = true; - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_QUESTION_MARK) { - isGlob = token.isGlob = true; - finished = true; - - if (scanToEnd === true) { - continue; - } - break; - } - - if (code === CHAR_LEFT_SQUARE_BRACKET$2) { - while (eos() !== true && (next = advance())) { - if (next === CHAR_BACKWARD_SLASH) { - backslashes = token.backslashes = true; - advance(); - continue; - } - - if (next === CHAR_RIGHT_SQUARE_BRACKET$2) { - isBracket = token.isBracket = true; - isGlob = token.isGlob = true; - finished = true; - break; - } - } - - if (scanToEnd === true) { - continue; - } - - break; - } - - if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { - negated = token.negated = true; - start++; - continue; - } - - if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES$1) { - isGlob = token.isGlob = true; - - if (scanToEnd === true) { - while (eos() !== true && (code = advance())) { - if (code === CHAR_LEFT_PARENTHESES$1) { - backslashes = token.backslashes = true; - code = advance(); - continue; - } - - if (code === CHAR_RIGHT_PARENTHESES$1) { - finished = true; - break; - } - } - continue; - } - break; - } - - if (isGlob === true) { - finished = true; - - if (scanToEnd === true) { - continue; - } - - break; - } - } - - if (opts.noext === true) { - isExtglob = false; - isGlob = false; - } - - let base = str; - let prefix = ''; - let glob = ''; - - if (start > 0) { - prefix = str.slice(0, start); - str = str.slice(start); - lastIndex -= start; - } - - if (base && isGlob === true && lastIndex > 0) { - base = str.slice(0, lastIndex); - glob = str.slice(lastIndex); - } else if (isGlob === true) { - base = ''; - glob = str; - } else { - base = str; - } - - if (base && base !== '' && base !== '/' && base !== str) { - if (isPathSeparator(base.charCodeAt(base.length - 1))) { - base = base.slice(0, -1); - } - } - - if (opts.unescape === true) { - if (glob) glob = utils$6.removeBackslashes(glob); - - if (base && backslashes === true) { - base = utils$6.removeBackslashes(base); - } - } - - const state = { - prefix, - input, - start, - base, - glob, - isBrace, - isBracket, - isGlob, - isExtglob, - isGlobstar, - negated, - negatedExtglob - }; - - if (opts.tokens === true) { - state.maxDepth = 0; - if (!isPathSeparator(code)) { - tokens.push(token); - } - state.tokens = tokens; - } - - if (opts.parts === true || opts.tokens === true) { - let prevIndex; - - for (let idx = 0; idx < slashes.length; idx++) { - const n = prevIndex ? prevIndex + 1 : start; - const i = slashes[idx]; - const value = input.slice(n, i); - if (opts.tokens) { - if (idx === 0 && start !== 0) { - tokens[idx].isPrefix = true; - tokens[idx].value = prefix; - } else { - tokens[idx].value = value; - } - depth(tokens[idx]); - state.maxDepth += tokens[idx].depth; - } - if (idx !== 0 || value !== '') { - parts.push(value); - } - prevIndex = i; - } - - if (prevIndex && prevIndex + 1 < input.length) { - const value = input.slice(prevIndex + 1); - parts.push(value); - - if (opts.tokens) { - tokens[tokens.length - 1].value = value; - depth(tokens[tokens.length - 1]); - state.maxDepth += tokens[tokens.length - 1].depth; - } - } - - state.slashes = slashes; - state.parts = parts; - } - - return state; -}; - -var scan_1 = scan$1; - -const constants$4 = constants$5; -const utils$5 = utils$7; - -/** - * Constants - */ - -const { - MAX_LENGTH: MAX_LENGTH$4, - POSIX_REGEX_SOURCE, - REGEX_NON_SPECIAL_CHARS, - REGEX_SPECIAL_CHARS_BACKREF, - REPLACEMENTS -} = constants$4; - -/** - * Helpers - */ - -const expandRange = (args, options) => { - if (typeof options.expandRange === 'function') { - return options.expandRange(...args, options); - } - - args.sort(); - const value = `[${args.join('-')}]`; - - try { - /* eslint-disable-next-line no-new */ - new RegExp(value); - } catch (ex) { - return args.map(v => utils$5.escapeRegex(v)).join('..'); - } - - return value; -}; - -/** - * Create the message for a syntax error - */ - -const syntaxError$1 = (type, char) => { - return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; -}; - -/** - * Parse the given input string. - * @param {String} input - * @param {Object} options - * @return {Object} - */ - -const parse$e = (input, options) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } - - input = REPLACEMENTS[input] || input; - - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$4, opts.maxLength) : MAX_LENGTH$4; - - let len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } - - const bos = { type: 'bos', value: '', output: opts.prepend || '' }; - const tokens = [bos]; - - const capture = opts.capture ? '' : '?:'; - const win32 = utils$5.isWindows(options); - - // create constants based on platform, for windows or posix - const PLATFORM_CHARS = constants$4.globChars(win32); - const EXTGLOB_CHARS = constants$4.extglobChars(PLATFORM_CHARS); - - const { - DOT_LITERAL, - PLUS_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOT_SLASH, - NO_DOTS_SLASH, - QMARK, - QMARK_NO_DOT, - STAR, - START_ANCHOR - } = PLATFORM_CHARS; - - const globstar = opts => { - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; - - const nodot = opts.dot ? '' : NO_DOT; - const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; - let star = opts.bash === true ? globstar(opts) : STAR; - - if (opts.capture) { - star = `(${star})`; - } - - // minimatch options support - if (typeof opts.noext === 'boolean') { - opts.noextglob = opts.noext; - } - - const state = { - input, - index: -1, - start: 0, - dot: opts.dot === true, - consumed: '', - output: '', - prefix: '', - backtrack: false, - negated: false, - brackets: 0, - braces: 0, - parens: 0, - quotes: 0, - globstar: false, - tokens - }; - - input = utils$5.removePrefix(input, state); - len = input.length; - - const extglobs = []; - const braces = []; - const stack = []; - let prev = bos; - let value; - - /** - * Tokenizing helpers - */ - - const eos = () => state.index === len - 1; - const peek = state.peek = (n = 1) => input[state.index + n]; - const advance = state.advance = () => input[++state.index] || ''; - const remaining = () => input.slice(state.index + 1); - const consume = (value = '', num = 0) => { - state.consumed += value; - state.index += num; - }; - - const append = token => { - state.output += token.output != null ? token.output : token.value; - consume(token.value); - }; - - const negate = () => { - let count = 1; - - while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { - advance(); - state.start++; - count++; - } - - if (count % 2 === 0) { - return false; - } - - state.negated = true; - state.start++; - return true; - }; - - const increment = type => { - state[type]++; - stack.push(type); - }; - - const decrement = type => { - state[type]--; - stack.pop(); - }; - - /** - * Push tokens onto the tokens array. This helper speeds up - * tokenizing by 1) helping us avoid backtracking as much as possible, - * and 2) helping us avoid creating extra tokens when consecutive - * characters are plain text. This improves performance and simplifies - * lookbehinds. - */ - - const push = tok => { - if (prev.type === 'globstar') { - const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); - const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); - - if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { - state.output = state.output.slice(0, -prev.output.length); - prev.type = 'star'; - prev.value = '*'; - prev.output = star; - state.output += prev.output; - } - } - - if (extglobs.length && tok.type !== 'paren') { - extglobs[extglobs.length - 1].inner += tok.value; - } - - if (tok.value || tok.output) append(tok); - if (prev && prev.type === 'text' && tok.type === 'text') { - prev.value += tok.value; - prev.output = (prev.output || '') + tok.value; - return; - } - - tok.prev = prev; - tokens.push(tok); - prev = tok; - }; - - const extglobOpen = (type, value) => { - const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; - - token.prev = prev; - token.parens = state.parens; - token.output = state.output; - const output = (opts.capture ? '(' : '') + token.open; - - increment('parens'); - push({ type, value, output: state.output ? '' : ONE_CHAR }); - push({ type: 'paren', extglob: true, value: advance(), output }); - extglobs.push(token); - }; - - const extglobClose = token => { - let output = token.close + (opts.capture ? ')' : ''); - let rest; - - if (token.type === 'negate') { - let extglobStar = star; - - if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { - extglobStar = globstar(opts); - } - - if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { - output = token.close = `)$))${extglobStar}`; - } - - if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { - output = token.close = `)${rest})${extglobStar})`; - } - - if (token.prev.type === 'bos') { - state.negatedExtglob = true; - } - } - - push({ type: 'paren', extglob: true, value, output }); - decrement('parens'); - }; - - /** - * Fast paths - */ - - if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { - let backslashes = false; - - let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { - if (first === '\\') { - backslashes = true; - return m; - } - - if (first === '?') { - if (esc) { - return esc + first + (rest ? QMARK.repeat(rest.length) : ''); - } - if (index === 0) { - return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); - } - return QMARK.repeat(chars.length); - } - - if (first === '.') { - return DOT_LITERAL.repeat(chars.length); - } - - if (first === '*') { - if (esc) { - return esc + first + (rest ? star : ''); - } - return star; - } - return esc ? m : `\\${m}`; - }); - - if (backslashes === true) { - if (opts.unescape === true) { - output = output.replace(/\\/g, ''); - } else { - output = output.replace(/\\+/g, m => { - return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); - }); - } - } - - if (output === input && opts.contains === true) { - state.output = input; - return state; - } - - state.output = utils$5.wrapOutput(output, state, options); - return state; - } - - /** - * Tokenize input until we reach end-of-string - */ - - while (!eos()) { - value = advance(); - - if (value === '\u0000') { - continue; - } - - /** - * Escaped characters - */ - - if (value === '\\') { - const next = peek(); - - if (next === '/' && opts.bash !== true) { - continue; - } - - if (next === '.' || next === ';') { - continue; - } - - if (!next) { - value += '\\'; - push({ type: 'text', value }); - continue; - } - - // collapse slashes to reduce potential for exploits - const match = /^\\+/.exec(remaining()); - let slashes = 0; - - if (match && match[0].length > 2) { - slashes = match[0].length; - state.index += slashes; - if (slashes % 2 !== 0) { - value += '\\'; - } - } - - if (opts.unescape === true) { - value = advance(); - } else { - value += advance(); - } - - if (state.brackets === 0) { - push({ type: 'text', value }); - continue; - } - } - - /** - * If we're inside a regex character class, continue - * until we reach the closing bracket. - */ - - if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { - if (opts.posix !== false && value === ':') { - const inner = prev.value.slice(1); - if (inner.includes('[')) { - prev.posix = true; - - if (inner.includes(':')) { - const idx = prev.value.lastIndexOf('['); - const pre = prev.value.slice(0, idx); - const rest = prev.value.slice(idx + 2); - const posix = POSIX_REGEX_SOURCE[rest]; - if (posix) { - prev.value = pre + posix; - state.backtrack = true; - advance(); - - if (!bos.output && tokens.indexOf(prev) === 1) { - bos.output = ONE_CHAR; - } - continue; - } - } - } - } - - if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { - value = `\\${value}`; - } - - if (value === ']' && (prev.value === '[' || prev.value === '[^')) { - value = `\\${value}`; - } - - if (opts.posix === true && value === '!' && prev.value === '[') { - value = '^'; - } - - prev.value += value; - append({ value }); - continue; - } - - /** - * If we're inside a quoted string, continue - * until we reach the closing double quote. - */ - - if (state.quotes === 1 && value !== '"') { - value = utils$5.escapeRegex(value); - prev.value += value; - append({ value }); - continue; - } - - /** - * Double quotes - */ - - if (value === '"') { - state.quotes = state.quotes === 1 ? 0 : 1; - if (opts.keepQuotes === true) { - push({ type: 'text', value }); - } - continue; - } - - /** - * Parentheses - */ - - if (value === '(') { - increment('parens'); - push({ type: 'paren', value }); - continue; - } - - if (value === ')') { - if (state.parens === 0 && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError$1('opening', '(')); - } - - const extglob = extglobs[extglobs.length - 1]; - if (extglob && state.parens === extglob.parens + 1) { - extglobClose(extglobs.pop()); - continue; - } - - push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); - decrement('parens'); - continue; - } - - /** - * Square brackets - */ - - if (value === '[') { - if (opts.nobracket === true || !remaining().includes(']')) { - if (opts.nobracket !== true && opts.strictBrackets === true) { - throw new SyntaxError(syntaxError$1('closing', ']')); - } - - value = `\\${value}`; - } else { - increment('brackets'); - } - - push({ type: 'bracket', value }); - continue; - } - - if (value === ']') { - if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { - push({ type: 'text', value, output: `\\${value}` }); - continue; - } - - if (state.brackets === 0) { - if (opts.strictBrackets === true) { - throw new SyntaxError(syntaxError$1('opening', '[')); - } - - push({ type: 'text', value, output: `\\${value}` }); - continue; - } - - decrement('brackets'); - - const prevValue = prev.value.slice(1); - if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { - value = `/${value}`; - } - - prev.value += value; - append({ value }); - - // when literal brackets are explicitly disabled - // assume we should match with a regex character class - if (opts.literalBrackets === false || utils$5.hasRegexChars(prevValue)) { - continue; - } - - const escaped = utils$5.escapeRegex(prev.value); - state.output = state.output.slice(0, -prev.value.length); - - // when literal brackets are explicitly enabled - // assume we should escape the brackets to match literal characters - if (opts.literalBrackets === true) { - state.output += escaped; - prev.value = escaped; - continue; - } - - // when the user specifies nothing, try to match both - prev.value = `(${capture}${escaped}|${prev.value})`; - state.output += prev.value; - continue; - } - - /** - * Braces - */ - - if (value === '{' && opts.nobrace !== true) { - increment('braces'); - - const open = { - type: 'brace', - value, - output: '(', - outputIndex: state.output.length, - tokensIndex: state.tokens.length - }; - - braces.push(open); - push(open); - continue; - } - - if (value === '}') { - const brace = braces[braces.length - 1]; - - if (opts.nobrace === true || !brace) { - push({ type: 'text', value, output: value }); - continue; - } - - let output = ')'; - - if (brace.dots === true) { - const arr = tokens.slice(); - const range = []; - - for (let i = arr.length - 1; i >= 0; i--) { - tokens.pop(); - if (arr[i].type === 'brace') { - break; - } - if (arr[i].type !== 'dots') { - range.unshift(arr[i].value); - } - } - - output = expandRange(range, opts); - state.backtrack = true; - } - - if (brace.comma !== true && brace.dots !== true) { - const out = state.output.slice(0, brace.outputIndex); - const toks = state.tokens.slice(brace.tokensIndex); - brace.value = brace.output = '\\{'; - value = output = '\\}'; - state.output = out; - for (const t of toks) { - state.output += (t.output || t.value); - } - } - - push({ type: 'brace', value, output }); - decrement('braces'); - braces.pop(); - continue; - } - - /** - * Pipes - */ - - if (value === '|') { - if (extglobs.length > 0) { - extglobs[extglobs.length - 1].conditions++; - } - push({ type: 'text', value }); - continue; - } - - /** - * Commas - */ - - if (value === ',') { - let output = value; - - const brace = braces[braces.length - 1]; - if (brace && stack[stack.length - 1] === 'braces') { - brace.comma = true; - output = '|'; - } - - push({ type: 'comma', value, output }); - continue; - } - - /** - * Slashes - */ - - if (value === '/') { - // if the beginning of the glob is "./", advance the start - // to the current index, and don't add the "./" characters - // to the state. This greatly simplifies lookbehinds when - // checking for BOS characters like "!" and "." (not "./") - if (prev.type === 'dot' && state.index === state.start + 1) { - state.start = state.index + 1; - state.consumed = ''; - state.output = ''; - tokens.pop(); - prev = bos; // reset "prev" to the first token - continue; - } - - push({ type: 'slash', value, output: SLASH_LITERAL }); - continue; - } - - /** - * Dots - */ - - if (value === '.') { - if (state.braces > 0 && prev.type === 'dot') { - if (prev.value === '.') prev.output = DOT_LITERAL; - const brace = braces[braces.length - 1]; - prev.type = 'dots'; - prev.output += value; - prev.value += value; - brace.dots = true; - continue; - } - - if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { - push({ type: 'text', value, output: DOT_LITERAL }); - continue; - } - - push({ type: 'dot', value, output: DOT_LITERAL }); - continue; - } - - /** - * Question marks - */ - - if (value === '?') { - const isGroup = prev && prev.value === '('; - if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('qmark', value); - continue; - } - - if (prev && prev.type === 'paren') { - const next = peek(); - let output = value; - - if (next === '<' && !utils$5.supportsLookbehinds()) { - throw new Error('Node.js v10 or higher is required for regex lookbehinds'); - } - - if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { - output = `\\${value}`; - } - - push({ type: 'text', value, output }); - continue; - } - - if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { - push({ type: 'qmark', value, output: QMARK_NO_DOT }); - continue; - } - - push({ type: 'qmark', value, output: QMARK }); - continue; - } - - /** - * Exclamation - */ - - if (value === '!') { - if (opts.noextglob !== true && peek() === '(') { - if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { - extglobOpen('negate', value); - continue; - } - } - - if (opts.nonegate !== true && state.index === 0) { - negate(); - continue; - } - } - - /** - * Plus - */ - - if (value === '+') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - extglobOpen('plus', value); - continue; - } - - if ((prev && prev.value === '(') || opts.regex === false) { - push({ type: 'plus', value, output: PLUS_LITERAL }); - continue; - } - - if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { - push({ type: 'plus', value }); - continue; - } - - push({ type: 'plus', value: PLUS_LITERAL }); - continue; - } - - /** - * Plain text - */ - - if (value === '@') { - if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { - push({ type: 'at', extglob: true, value, output: '' }); - continue; - } - - push({ type: 'text', value }); - continue; - } - - /** - * Plain text - */ - - if (value !== '*') { - if (value === '$' || value === '^') { - value = `\\${value}`; - } - - const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); - if (match) { - value += match[0]; - state.index += match[0].length; - } - - push({ type: 'text', value }); - continue; - } - - /** - * Stars - */ - - if (prev && (prev.type === 'globstar' || prev.star === true)) { - prev.type = 'star'; - prev.star = true; - prev.value += value; - prev.output = star; - state.backtrack = true; - state.globstar = true; - consume(value); - continue; - } - - let rest = remaining(); - if (opts.noextglob !== true && /^\([^?]/.test(rest)) { - extglobOpen('star', value); - continue; - } - - if (prev.type === 'star') { - if (opts.noglobstar === true) { - consume(value); - continue; - } - - const prior = prev.prev; - const before = prior.prev; - const isStart = prior.type === 'slash' || prior.type === 'bos'; - const afterStar = before && (before.type === 'star' || before.type === 'globstar'); - - if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { - push({ type: 'star', value, output: '' }); - continue; - } - - const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); - const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); - if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { - push({ type: 'star', value, output: '' }); - continue; - } - - // strip consecutive `/**/` - while (rest.slice(0, 3) === '/**') { - const after = input[state.index + 4]; - if (after && after !== '/') { - break; - } - rest = rest.slice(3); - consume('/**', 3); - } - - if (prior.type === 'bos' && eos()) { - prev.type = 'globstar'; - prev.value += value; - prev.output = globstar(opts); - state.output = prev.output; - state.globstar = true; - consume(value); - continue; - } - - if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; - - prev.type = 'globstar'; - prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); - prev.value += value; - state.globstar = true; - state.output += prior.output + prev.output; - consume(value); - continue; - } - - if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { - const end = rest[1] !== void 0 ? '|$' : ''; - - state.output = state.output.slice(0, -(prior.output + prev.output).length); - prior.output = `(?:${prior.output}`; - - prev.type = 'globstar'; - prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; - prev.value += value; - - state.output += prior.output + prev.output; - state.globstar = true; - - consume(value + advance()); - - push({ type: 'slash', value: '/', output: '' }); - continue; - } - - if (prior.type === 'bos' && rest[0] === '/') { - prev.type = 'globstar'; - prev.value += value; - prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; - state.output = prev.output; - state.globstar = true; - consume(value + advance()); - push({ type: 'slash', value: '/', output: '' }); - continue; - } - - // remove single star from output - state.output = state.output.slice(0, -prev.output.length); - - // reset previous token to globstar - prev.type = 'globstar'; - prev.output = globstar(opts); - prev.value += value; - - // reset output with globstar - state.output += prev.output; - state.globstar = true; - consume(value); - continue; - } - - const token = { type: 'star', value, output: star }; - - if (opts.bash === true) { - token.output = '.*?'; - if (prev.type === 'bos' || prev.type === 'slash') { - token.output = nodot + token.output; - } - push(token); - continue; - } - - if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { - token.output = value; - push(token); - continue; - } - - if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { - if (prev.type === 'dot') { - state.output += NO_DOT_SLASH; - prev.output += NO_DOT_SLASH; - - } else if (opts.dot === true) { - state.output += NO_DOTS_SLASH; - prev.output += NO_DOTS_SLASH; - - } else { - state.output += nodot; - prev.output += nodot; - } - - if (peek() !== '*') { - state.output += ONE_CHAR; - prev.output += ONE_CHAR; - } - } - - push(token); - } - - while (state.brackets > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', ']')); - state.output = utils$5.escapeLast(state.output, '['); - decrement('brackets'); - } - - while (state.parens > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', ')')); - state.output = utils$5.escapeLast(state.output, '('); - decrement('parens'); - } - - while (state.braces > 0) { - if (opts.strictBrackets === true) throw new SyntaxError(syntaxError$1('closing', '}')); - state.output = utils$5.escapeLast(state.output, '{'); - decrement('braces'); - } - - if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { - push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); - } - - // rebuild the output if we had to backtrack at any point - if (state.backtrack === true) { - state.output = ''; - - for (const token of state.tokens) { - state.output += token.output != null ? token.output : token.value; - - if (token.suffix) { - state.output += token.suffix; - } - } - } - - return state; -}; - -/** - * Fast paths for creating regular expressions for common glob patterns. - * This can significantly speed up processing and has very little downside - * impact when none of the fast paths match. - */ - -parse$e.fastpaths = (input, options) => { - const opts = { ...options }; - const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$4, opts.maxLength) : MAX_LENGTH$4; - const len = input.length; - if (len > max) { - throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); - } - - input = REPLACEMENTS[input] || input; - const win32 = utils$5.isWindows(options); - - // create constants based on platform, for windows or posix - const { - DOT_LITERAL, - SLASH_LITERAL, - ONE_CHAR, - DOTS_SLASH, - NO_DOT, - NO_DOTS, - NO_DOTS_SLASH, - STAR, - START_ANCHOR - } = constants$4.globChars(win32); - - const nodot = opts.dot ? NO_DOTS : NO_DOT; - const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; - const capture = opts.capture ? '' : '?:'; - const state = { negated: false, prefix: '' }; - let star = opts.bash === true ? '.*?' : STAR; - - if (opts.capture) { - star = `(${star})`; - } - - const globstar = opts => { - if (opts.noglobstar === true) return star; - return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; - }; - - const create = str => { - switch (str) { - case '*': - return `${nodot}${ONE_CHAR}${star}`; - - case '.*': - return `${DOT_LITERAL}${ONE_CHAR}${star}`; - - case '*.*': - return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - - case '*/*': - return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; - - case '**': - return nodot + globstar(opts); - - case '**/*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; - - case '**/*.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; - - case '**/.*': - return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; - - default: { - const match = /^(.*?)\.(\w+)$/.exec(str); - if (!match) return; - - const source = create(match[1]); - if (!source) return; - - return source + DOT_LITERAL + match[2]; - } - } - }; - - const output = utils$5.removePrefix(input, state); - let source = create(output); - - if (source && opts.strictSlashes !== true) { - source += `${SLASH_LITERAL}?`; - } - - return source; -}; - -var parse_1$2 = parse$e; - -const path$9 = path$b; -const scan = scan_1; -const parse$d = parse_1$2; -const utils$4 = utils$7; -const constants$3 = constants$5; -const isObject$3 = val => val && typeof val === 'object' && !Array.isArray(val); - -/** - * Creates a matcher function from one or more glob patterns. The - * returned function takes a string to match as its first argument, - * and returns true if the string is a match. The returned matcher - * function also takes a boolean as the second argument that, when true, - * returns an object with additional information. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch(glob[, options]); - * - * const isMatch = picomatch('*.!(*a)'); - * console.log(isMatch('a.a')); //=> false - * console.log(isMatch('a.b')); //=> true - * ``` - * @name picomatch - * @param {String|Array} `globs` One or more glob patterns. - * @param {Object=} `options` - * @return {Function=} Returns a matcher function. - * @api public - */ - -const picomatch$3 = (glob, options, returnState = false) => { - if (Array.isArray(glob)) { - const fns = glob.map(input => picomatch$3(input, options, returnState)); - const arrayMatcher = str => { - for (const isMatch of fns) { - const state = isMatch(str); - if (state) return state; - } - return false; - }; - return arrayMatcher; - } - - const isState = isObject$3(glob) && glob.tokens && glob.input; - - if (glob === '' || (typeof glob !== 'string' && !isState)) { - throw new TypeError('Expected pattern to be a non-empty string'); - } - - const opts = options || {}; - const posix = utils$4.isWindows(options); - const regex = isState - ? picomatch$3.compileRe(glob, options) - : picomatch$3.makeRe(glob, options, false, true); - - const state = regex.state; - delete regex.state; - - let isIgnored = () => false; - if (opts.ignore) { - const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; - isIgnored = picomatch$3(opts.ignore, ignoreOpts, returnState); - } - - const matcher = (input, returnObject = false) => { - const { isMatch, match, output } = picomatch$3.test(input, regex, options, { glob, posix }); - const result = { glob, state, regex, posix, input, output, match, isMatch }; - - if (typeof opts.onResult === 'function') { - opts.onResult(result); - } - - if (isMatch === false) { - result.isMatch = false; - return returnObject ? result : false; - } - - if (isIgnored(input)) { - if (typeof opts.onIgnore === 'function') { - opts.onIgnore(result); - } - result.isMatch = false; - return returnObject ? result : false; - } - - if (typeof opts.onMatch === 'function') { - opts.onMatch(result); - } - return returnObject ? result : true; - }; - - if (returnState) { - matcher.state = state; - } - - return matcher; -}; - -/** - * Test `input` with the given `regex`. This is used by the main - * `picomatch()` function to test the input string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.test(input, regex[, options]); - * - * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); - * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } - * ``` - * @param {String} `input` String to test. - * @param {RegExp} `regex` - * @return {Object} Returns an object with matching info. - * @api public - */ - -picomatch$3.test = (input, regex, options, { glob, posix } = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected input to be a string'); - } - - if (input === '') { - return { isMatch: false, output: '' }; - } - - const opts = options || {}; - const format = opts.format || (posix ? utils$4.toPosixSlashes : null); - let match = input === glob; - let output = (match && format) ? format(input) : input; - - if (match === false) { - output = format ? format(input) : input; - match = output === glob; - } - - if (match === false || opts.capture === true) { - if (opts.matchBase === true || opts.basename === true) { - match = picomatch$3.matchBase(input, regex, options, posix); - } else { - match = regex.exec(output); - } - } - - return { isMatch: Boolean(match), match, output }; -}; - -/** - * Match the basename of a filepath. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.matchBase(input, glob[, options]); - * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true - * ``` - * @param {String} `input` String to test. - * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). - * @return {Boolean} - * @api public - */ - -picomatch$3.matchBase = (input, glob, options, posix = utils$4.isWindows(options)) => { - const regex = glob instanceof RegExp ? glob : picomatch$3.makeRe(glob, options); - return regex.test(path$9.basename(input)); -}; - -/** - * Returns true if **any** of the given glob `patterns` match the specified `string`. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.isMatch(string, patterns[, options]); - * - * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true - * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false - * ``` - * @param {String|Array} str The string to test. - * @param {String|Array} patterns One or more glob patterns to use for matching. - * @param {Object} [options] See available [options](#options). - * @return {Boolean} Returns true if any patterns match `str` - * @api public - */ - -picomatch$3.isMatch = (str, patterns, options) => picomatch$3(patterns, options)(str); - -/** - * Parse a glob pattern to create the source string for a regular - * expression. - * - * ```js - * const picomatch = require('picomatch'); - * const result = picomatch.parse(pattern[, options]); - * ``` - * @param {String} `pattern` - * @param {Object} `options` - * @return {Object} Returns an object with useful properties and output to be used as a regex source string. - * @api public - */ - -picomatch$3.parse = (pattern, options) => { - if (Array.isArray(pattern)) return pattern.map(p => picomatch$3.parse(p, options)); - return parse$d(pattern, { ...options, fastpaths: false }); -}; - -/** - * Scan a glob pattern to separate the pattern into segments. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.scan(input[, options]); - * - * const result = picomatch.scan('!./foo/*.js'); - * console.log(result); - * { prefix: '!./', - * input: '!./foo/*.js', - * start: 3, - * base: 'foo', - * glob: '*.js', - * isBrace: false, - * isBracket: false, - * isGlob: true, - * isExtglob: false, - * isGlobstar: false, - * negated: true } - * ``` - * @param {String} `input` Glob pattern to scan. - * @param {Object} `options` - * @return {Object} Returns an object with - * @api public - */ - -picomatch$3.scan = (input, options) => scan(input, options); - -/** - * Compile a regular expression from the `state` object returned by the - * [parse()](#parse) method. - * - * @param {Object} `state` - * @param {Object} `options` - * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. - * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. - * @return {RegExp} - * @api public - */ - -picomatch$3.compileRe = (state, options, returnOutput = false, returnState = false) => { - if (returnOutput === true) { - return state.output; - } - - const opts = options || {}; - const prepend = opts.contains ? '' : '^'; - const append = opts.contains ? '' : '$'; - - let source = `${prepend}(?:${state.output})${append}`; - if (state && state.negated === true) { - source = `^(?!${source}).*$`; - } - - const regex = picomatch$3.toRegex(source, options); - if (returnState === true) { - regex.state = state; - } - - return regex; -}; - -/** - * Create a regular expression from a parsed glob pattern. - * - * ```js - * const picomatch = require('picomatch'); - * const state = picomatch.parse('*.js'); - * // picomatch.compileRe(state[, options]); - * - * console.log(picomatch.compileRe(state)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `state` The object returned from the `.parse` method. - * @param {Object} `options` - * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. - * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. - * @return {RegExp} Returns a regex created from the given pattern. - * @api public - */ - -picomatch$3.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { - if (!input || typeof input !== 'string') { - throw new TypeError('Expected a non-empty string'); - } - - let parsed = { negated: false, fastpaths: true }; - - if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { - parsed.output = parse$d.fastpaths(input, options); - } - - if (!parsed.output) { - parsed = parse$d(input, options); - } - - return picomatch$3.compileRe(parsed, options, returnOutput, returnState); -}; - -/** - * Create a regular expression from the given regex source string. - * - * ```js - * const picomatch = require('picomatch'); - * // picomatch.toRegex(source[, options]); - * - * const { output } = picomatch.parse('*.js'); - * console.log(picomatch.toRegex(output)); - * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ - * ``` - * @param {String} `source` Regular expression source string. - * @param {Object} `options` - * @return {RegExp} - * @api public - */ - -picomatch$3.toRegex = (source, options) => { - try { - const opts = options || {}; - return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); - } catch (err) { - if (options && options.debug === true) throw err; - return /$^/; - } -}; - -/** - * Picomatch constants. - * @return {Object} - */ - -picomatch$3.constants = constants$3; - -/** - * Expose "picomatch" - */ - -var picomatch_1 = picomatch$3; - -var picomatch$2 = picomatch_1; - -const fs$9 = require$$0$3; -const { Readable } = require$$1; -const sysPath$3 = path$b; -const { promisify: promisify$3 } = require$$0$4; -const picomatch$1 = picomatch$2; - -const readdir$1 = promisify$3(fs$9.readdir); -const stat$3 = promisify$3(fs$9.stat); -const lstat$2 = promisify$3(fs$9.lstat); -const realpath$2 = promisify$3(fs$9.realpath); - -/** - * @typedef {Object} EntryInfo - * @property {String} path - * @property {String} fullPath - * @property {fs.Stats=} stats - * @property {fs.Dirent=} dirent - * @property {String} basename - */ - -const BANG$2 = '!'; -const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR'; -const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]); -const FILE_TYPE = 'files'; -const DIR_TYPE = 'directories'; -const FILE_DIR_TYPE = 'files_directories'; -const EVERYTHING_TYPE = 'all'; -const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]; - -const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code); -const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10)); -const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5)); - -const normalizeFilter = filter => { - if (filter === undefined) return; - if (typeof filter === 'function') return filter; - - if (typeof filter === 'string') { - const glob = picomatch$1(filter.trim()); - return entry => glob(entry.basename); - } - - if (Array.isArray(filter)) { - const positive = []; - const negative = []; - for (const item of filter) { - const trimmed = item.trim(); - if (trimmed.charAt(0) === BANG$2) { - negative.push(picomatch$1(trimmed.slice(1))); - } else { - positive.push(picomatch$1(trimmed)); - } - } - - if (negative.length > 0) { - if (positive.length > 0) { - return entry => - positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); - } - return entry => !negative.some(f => f(entry.basename)); - } - return entry => positive.some(f => f(entry.basename)); - } -}; - -class ReaddirpStream extends Readable { - static get defaultOptions() { - return { - root: '.', - /* eslint-disable no-unused-vars */ - fileFilter: (path) => true, - directoryFilter: (path) => true, - /* eslint-enable no-unused-vars */ - type: FILE_TYPE, - lstat: false, - depth: 2147483648, - alwaysStat: false - }; - } - - constructor(options = {}) { - super({ - objectMode: true, - autoDestroy: true, - highWaterMark: options.highWaterMark || 4096 - }); - const opts = { ...ReaddirpStream.defaultOptions, ...options }; - const { root, type } = opts; - - this._fileFilter = normalizeFilter(opts.fileFilter); - this._directoryFilter = normalizeFilter(opts.directoryFilter); - - const statMethod = opts.lstat ? lstat$2 : stat$3; - // Use bigint stats if it's windows and stat() supports options (node 10+). - if (wantBigintFsStats) { - this._stat = path => statMethod(path, { bigint: true }); - } else { - this._stat = statMethod; - } - - this._maxDepth = opts.depth; - this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); - this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); - this._wantsEverything = type === EVERYTHING_TYPE; - this._root = sysPath$3.resolve(root); - this._isDirent = ('Dirent' in fs$9) && !opts.alwaysStat; - this._statsProp = this._isDirent ? 'dirent' : 'stats'; - this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent }; - - // Launch stream with one parent, the root dir. - this.parents = [this._exploreDir(root, 1)]; - this.reading = false; - this.parent = undefined; - } - - async _read(batch) { - if (this.reading) return; - this.reading = true; - - try { - while (!this.destroyed && batch > 0) { - const { path, depth, files = [] } = this.parent || {}; - - if (files.length > 0) { - const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path)); - for (const entry of await Promise.all(slice)) { - if (this.destroyed) return; - - const entryType = await this._getEntryType(entry); - if (entryType === 'directory' && this._directoryFilter(entry)) { - if (depth <= this._maxDepth) { - this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); - } - - if (this._wantsDir) { - this.push(entry); - batch--; - } - } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) { - if (this._wantsFile) { - this.push(entry); - batch--; - } - } - } - } else { - const parent = this.parents.pop(); - if (!parent) { - this.push(null); - break; - } - this.parent = await parent; - if (this.destroyed) return; - } - } - } catch (error) { - this.destroy(error); - } finally { - this.reading = false; - } - } - - async _exploreDir(path, depth) { - let files; - try { - files = await readdir$1(path, this._rdOptions); - } catch (error) { - this._onError(error); - } - return { files, depth, path }; - } - - async _formatEntry(dirent, path) { - let entry; - try { - const basename = this._isDirent ? dirent.name : dirent; - const fullPath = sysPath$3.resolve(sysPath$3.join(path, basename)); - entry = { path: sysPath$3.relative(this._root, fullPath), fullPath, basename }; - entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); - } catch (err) { - this._onError(err); - } - return entry; - } - - _onError(err) { - if (isNormalFlowError(err) && !this.destroyed) { - this.emit('warn', err); - } else { - this.destroy(err); - } - } - - async _getEntryType(entry) { - // entry may be undefined, because a warning or an error were emitted - // and the statsProp is undefined - const stats = entry && entry[this._statsProp]; - if (!stats) { - return; - } - if (stats.isFile()) { - return 'file'; - } - if (stats.isDirectory()) { - return 'directory'; - } - if (stats && stats.isSymbolicLink()) { - const full = entry.fullPath; - try { - const entryRealPath = await realpath$2(full); - const entryRealPathStats = await lstat$2(entryRealPath); - if (entryRealPathStats.isFile()) { - return 'file'; - } - if (entryRealPathStats.isDirectory()) { - const len = entryRealPath.length; - if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath$3.sep) { - const recursiveError = new Error( - `Circular symlink detected: "${full}" points to "${entryRealPath}"` - ); - recursiveError.code = RECURSIVE_ERROR_CODE; - return this._onError(recursiveError); - } - return 'directory'; - } - } catch (error) { - this._onError(error); - } - } - } - - _includeAsFile(entry) { - const stats = entry && entry[this._statsProp]; - - return stats && this._wantsEverything && !stats.isDirectory(); - } -} - -/** - * @typedef {Object} ReaddirpArguments - * @property {Function=} fileFilter - * @property {Function=} directoryFilter - * @property {String=} type - * @property {Number=} depth - * @property {String=} root - * @property {Boolean=} lstat - * @property {Boolean=} bigint - */ - -/** - * Main function which ends up calling readdirRec and reads all files and directories in given root recursively. - * @param {String} root Root directory - * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth - */ -const readdirp$1 = (root, options = {}) => { - let type = options.entryType || options.type; - if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility - if (type) options.type = type; - if (!root) { - throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)'); - } else if (typeof root !== 'string') { - throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)'); - } else if (type && !ALL_TYPES.includes(type)) { - throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`); - } - - options.root = root; - return new ReaddirpStream(options); -}; - -const readdirpPromise = (root, options = {}) => { - return new Promise((resolve, reject) => { - const files = []; - readdirp$1(root, options) - .on('data', entry => files.push(entry)) - .on('end', () => resolve(files)) - .on('error', error => reject(error)); - }); -}; - -readdirp$1.promise = readdirpPromise; -readdirp$1.ReaddirpStream = ReaddirpStream; -readdirp$1.default = readdirp$1; - -var readdirp_1 = readdirp$1; - -var anymatch$2 = {exports: {}}; - -/*! - * normalize-path - * - * Copyright (c) 2014-2018, Jon Schlinkert. - * Released under the MIT License. - */ - -var normalizePath$2 = function(path, stripTrailing) { - if (typeof path !== 'string') { - throw new TypeError('expected path to be a string'); - } - - if (path === '\\' || path === '/') return '/'; - - var len = path.length; - if (len <= 1) return path; - - // ensure that win32 namespaces has two leading slashes, so that the path is - // handled properly by the win32 version of path.parse() after being normalized - // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces - var prefix = ''; - if (len > 4 && path[3] === '\\') { - var ch = path[2]; - if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') { - path = path.slice(2); - prefix = '//'; - } - } - - var segs = path.split(/[/\\]+/); - if (stripTrailing !== false && segs[segs.length - 1] === '') { - segs.pop(); - } - return prefix + segs.join('/'); -}; - -Object.defineProperty(anymatch$2.exports, "__esModule", { value: true }); - -const picomatch = picomatch$2; -const normalizePath$1 = normalizePath$2; - -/** - * @typedef {(testString: string) => boolean} AnymatchFn - * @typedef {string|RegExp|AnymatchFn} AnymatchPattern - * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher - */ -const BANG$1 = '!'; -const DEFAULT_OPTIONS = {returnIndex: false}; -const arrify$1 = (item) => Array.isArray(item) ? item : [item]; - -/** - * @param {AnymatchPattern} matcher - * @param {object} options - * @returns {AnymatchFn} - */ -const createPattern = (matcher, options) => { - if (typeof matcher === 'function') { - return matcher; - } - if (typeof matcher === 'string') { - const glob = picomatch(matcher, options); - return (string) => matcher === string || glob(string); - } - if (matcher instanceof RegExp) { - return (string) => matcher.test(string); - } - return (string) => false; -}; - -/** - * @param {Array} patterns - * @param {Array} negPatterns - * @param {String|Array} args - * @param {Boolean} returnIndex - * @returns {boolean|number} - */ -const matchPatterns = (patterns, negPatterns, args, returnIndex) => { - const isList = Array.isArray(args); - const _path = isList ? args[0] : args; - if (!isList && typeof _path !== 'string') { - throw new TypeError('anymatch: second argument must be a string: got ' + - Object.prototype.toString.call(_path)) - } - const path = normalizePath$1(_path); - - for (let index = 0; index < negPatterns.length; index++) { - const nglob = negPatterns[index]; - if (nglob(path)) { - return returnIndex ? -1 : false; - } - } - - const applied = isList && [path].concat(args.slice(1)); - for (let index = 0; index < patterns.length; index++) { - const pattern = patterns[index]; - if (isList ? pattern(...applied) : pattern(path)) { - return returnIndex ? index : true; - } - } - - return returnIndex ? -1 : false; -}; - -/** - * @param {AnymatchMatcher} matchers - * @param {Array|string} testString - * @param {object} options - * @returns {boolean|number|Function} - */ -const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => { - if (matchers == null) { - throw new TypeError('anymatch: specify first argument'); - } - const opts = typeof options === 'boolean' ? {returnIndex: options} : options; - const returnIndex = opts.returnIndex || false; - - // Early cache for matchers. - const mtchers = arrify$1(matchers); - const negatedGlobs = mtchers - .filter(item => typeof item === 'string' && item.charAt(0) === BANG$1) - .map(item => item.slice(1)) - .map(item => picomatch(item, opts)); - const patterns = mtchers - .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG$1)) - .map(matcher => createPattern(matcher, opts)); - - if (testString == null) { - return (testString, ri = false) => { - const returnIndex = typeof ri === 'boolean' ? ri : false; - return matchPatterns(patterns, negatedGlobs, testString, returnIndex); - } - } - - return matchPatterns(patterns, negatedGlobs, testString, returnIndex); -}; - -anymatch$1.default = anymatch$1; -anymatch$2.exports = anymatch$1; - -/*! - * is-extglob - * - * Copyright (c) 2014-2016, Jon Schlinkert. - * Licensed under the MIT License. - */ - -var isExtglob$1 = function isExtglob(str) { - if (typeof str !== 'string' || str === '') { - return false; - } - - var match; - while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { - if (match[2]) return true; - str = str.slice(match.index + match[0].length); - } - - return false; -}; - -/*! - * is-glob - * - * Copyright (c) 2014-2017, Jon Schlinkert. - * Released under the MIT License. - */ - -var isExtglob = isExtglob$1; -var chars$1 = { '{': '}', '(': ')', '[': ']'}; -var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; -var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; - -var isGlob$2 = function isGlob(str, options) { - if (typeof str !== 'string' || str === '') { - return false; - } - - if (isExtglob(str)) { - return true; - } - - var regex = strictRegex; - var match; - - // optionally relax regex - if (options && options.strict === false) { - regex = relaxedRegex; - } - - while ((match = regex.exec(str))) { - if (match[2]) return true; - var idx = match.index + match[0].length; - - // if an open bracket/brace/paren is escaped, - // set the index to the next closing character - var open = match[1]; - var close = open ? chars$1[open] : null; - if (open && close) { - var n = str.indexOf(close, idx); - if (n !== -1) { - idx = n + 1; - } - } - - str = str.slice(idx); - } - return false; -}; - -var isGlob$1 = isGlob$2; -var pathPosixDirname = path$b.posix.dirname; -var isWin32 = require$$0$2.platform() === 'win32'; - -var slash = '/'; -var backslash = /\\/g; -var enclosure = /[\{\[].*[\}\]]$/; -var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; -var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; - -/** - * @param {string} str - * @param {Object} opts - * @param {boolean} [opts.flipBackslashes=true] - * @returns {string} - */ -var globParent$1 = function globParent(str, opts) { - var options = Object.assign({ flipBackslashes: true }, opts); - - // flip windows path separators - if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { - str = str.replace(backslash, slash); - } - - // special case for strings ending in enclosure containing path separator - if (enclosure.test(str)) { - str += slash; - } - - // preserves full path in case of trailing path separator - str += 'a'; - - // remove path parts that are globby - do { - str = pathPosixDirname(str); - } while (isGlob$1(str) || globby.test(str)); - - // remove escape chars and return result - return str.replace(escaped, '$1'); -}; - -var utils$3 = {}; - -(function (exports) { - -exports.isInteger = num => { - if (typeof num === 'number') { - return Number.isInteger(num); - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isInteger(Number(num)); - } - return false; -}; - -/** - * Find a node of the given type - */ - -exports.find = (node, type) => node.nodes.find(node => node.type === type); - -/** - * Find a node of the given type - */ - -exports.exceedsLimit = (min, max, step = 1, limit) => { - if (limit === false) return false; - if (!exports.isInteger(min) || !exports.isInteger(max)) return false; - return ((Number(max) - Number(min)) / Number(step)) >= limit; -}; - -/** - * Escape the given node with '\\' before node.value - */ - -exports.escapeNode = (block, n = 0, type) => { - let node = block.nodes[n]; - if (!node) return; - - if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { - if (node.escaped !== true) { - node.value = '\\' + node.value; - node.escaped = true; - } - } -}; - -/** - * Returns true if the given brace node should be enclosed in literal braces - */ - -exports.encloseBrace = node => { - if (node.type !== 'brace') return false; - if ((node.commas >> 0 + node.ranges >> 0) === 0) { - node.invalid = true; - return true; - } - return false; -}; - -/** - * Returns true if a brace node is invalid. - */ - -exports.isInvalidBrace = block => { - if (block.type !== 'brace') return false; - if (block.invalid === true || block.dollar) return true; - if ((block.commas >> 0 + block.ranges >> 0) === 0) { - block.invalid = true; - return true; - } - if (block.open !== true || block.close !== true) { - block.invalid = true; - return true; - } - return false; -}; - -/** - * Returns true if a node is an open or close node - */ - -exports.isOpenOrClose = node => { - if (node.type === 'open' || node.type === 'close') { - return true; - } - return node.open === true || node.close === true; -}; - -/** - * Reduce an array of text nodes. - */ - -exports.reduce = nodes => nodes.reduce((acc, node) => { - if (node.type === 'text') acc.push(node.value); - if (node.type === 'range') node.type = 'text'; - return acc; -}, []); - -/** - * Flatten an array - */ - -exports.flatten = (...args) => { - const result = []; - const flat = arr => { - for (let i = 0; i < arr.length; i++) { - let ele = arr[i]; - Array.isArray(ele) ? flat(ele) : ele !== void 0 && result.push(ele); - } - return result; - }; - flat(args); - return result; -}; -}(utils$3)); - -const utils$2 = utils$3; - -var stringify$6 = (ast, options = {}) => { - let stringify = (node, parent = {}) => { - let invalidBlock = options.escapeInvalid && utils$2.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let output = ''; - - if (node.value) { - if ((invalidBlock || invalidNode) && utils$2.isOpenOrClose(node)) { - return '\\' + node.value; - } - return node.value; - } - - if (node.value) { - return node.value; - } - - if (node.nodes) { - for (let child of node.nodes) { - output += stringify(child); - } - } - return output; - }; - - return stringify(ast); -}; - -/*! - * is-number - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Released under the MIT License. - */ - -var isNumber$3 = function(num) { - if (typeof num === 'number') { - return num - num === 0; - } - if (typeof num === 'string' && num.trim() !== '') { - return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); - } - return false; -}; - -/*! - * to-regex-range - * - * Copyright (c) 2015-present, Jon Schlinkert. - * Released under the MIT License. - */ - -const isNumber$2 = isNumber$3; - -const toRegexRange$1 = (min, max, options) => { - if (isNumber$2(min) === false) { - throw new TypeError('toRegexRange: expected the first argument to be a number'); - } - - if (max === void 0 || min === max) { - return String(min); - } - - if (isNumber$2(max) === false) { - throw new TypeError('toRegexRange: expected the second argument to be a number.'); - } - - let opts = { relaxZeros: true, ...options }; - if (typeof opts.strictZeros === 'boolean') { - opts.relaxZeros = opts.strictZeros === false; - } - - let relax = String(opts.relaxZeros); - let shorthand = String(opts.shorthand); - let capture = String(opts.capture); - let wrap = String(opts.wrap); - let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; - - if (toRegexRange$1.cache.hasOwnProperty(cacheKey)) { - return toRegexRange$1.cache[cacheKey].result; - } - - let a = Math.min(min, max); - let b = Math.max(min, max); - - if (Math.abs(a - b) === 1) { - let result = min + '|' + max; - if (opts.capture) { - return `(${result})`; - } - if (opts.wrap === false) { - return result; - } - return `(?:${result})`; - } - - let isPadded = hasPadding(min) || hasPadding(max); - let state = { min, max, a, b }; - let positives = []; - let negatives = []; - - if (isPadded) { - state.isPadded = isPadded; - state.maxLen = String(state.max).length; - } - - if (a < 0) { - let newMin = b < 0 ? Math.abs(b) : 1; - negatives = splitToPatterns(newMin, Math.abs(a), state, opts); - a = state.a = 0; - } - - if (b >= 0) { - positives = splitToPatterns(a, b, state, opts); - } - - state.negatives = negatives; - state.positives = positives; - state.result = collatePatterns(negatives, positives); - - if (opts.capture === true) { - state.result = `(${state.result})`; - } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { - state.result = `(?:${state.result})`; - } - - toRegexRange$1.cache[cacheKey] = state; - return state.result; -}; - -function collatePatterns(neg, pos, options) { - let onlyNegative = filterPatterns(neg, pos, '-', false) || []; - let onlyPositive = filterPatterns(pos, neg, '', false) || []; - let intersected = filterPatterns(neg, pos, '-?', true) || []; - let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); - return subpatterns.join('|'); -} - -function splitToRanges(min, max) { - let nines = 1; - let zeros = 1; - - let stop = countNines(min, nines); - let stops = new Set([max]); - - while (min <= stop && stop <= max) { - stops.add(stop); - nines += 1; - stop = countNines(min, nines); - } - - stop = countZeros(max + 1, zeros) - 1; - - while (min < stop && stop <= max) { - stops.add(stop); - zeros += 1; - stop = countZeros(max + 1, zeros) - 1; - } - - stops = [...stops]; - stops.sort(compare$c); - return stops; -} - -/** - * Convert a range to a regex pattern - * @param {Number} `start` - * @param {Number} `stop` - * @return {String} - */ - -function rangeToPattern(start, stop, options) { - if (start === stop) { - return { pattern: start, count: [], digits: 0 }; - } - - let zipped = zip(start, stop); - let digits = zipped.length; - let pattern = ''; - let count = 0; - - for (let i = 0; i < digits; i++) { - let [startDigit, stopDigit] = zipped[i]; - - if (startDigit === stopDigit) { - pattern += startDigit; - - } else if (startDigit !== '0' || stopDigit !== '9') { - pattern += toCharacterClass(startDigit, stopDigit); - - } else { - count++; - } - } - - if (count) { - pattern += options.shorthand === true ? '\\d' : '[0-9]'; - } - - return { pattern, count: [count], digits }; -} - -function splitToPatterns(min, max, tok, options) { - let ranges = splitToRanges(min, max); - let tokens = []; - let start = min; - let prev; - - for (let i = 0; i < ranges.length; i++) { - let max = ranges[i]; - let obj = rangeToPattern(String(start), String(max), options); - let zeros = ''; - - if (!tok.isPadded && prev && prev.pattern === obj.pattern) { - if (prev.count.length > 1) { - prev.count.pop(); - } - - prev.count.push(obj.count[0]); - prev.string = prev.pattern + toQuantifier(prev.count); - start = max + 1; - continue; - } - - if (tok.isPadded) { - zeros = padZeros(max, tok, options); - } - - obj.string = zeros + obj.pattern + toQuantifier(obj.count); - tokens.push(obj); - start = max + 1; - prev = obj; - } - - return tokens; -} - -function filterPatterns(arr, comparison, prefix, intersection, options) { - let result = []; - - for (let ele of arr) { - let { string } = ele; - - // only push if _both_ are negative... - if (!intersection && !contains(comparison, 'string', string)) { - result.push(prefix + string); - } - - // or _both_ are positive - if (intersection && contains(comparison, 'string', string)) { - result.push(prefix + string); - } - } - return result; -} - -/** - * Zip strings - */ - -function zip(a, b) { - let arr = []; - for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); - return arr; -} - -function compare$c(a, b) { - return a > b ? 1 : b > a ? -1 : 0; -} - -function contains(arr, key, val) { - return arr.some(ele => ele[key] === val); -} - -function countNines(min, len) { - return Number(String(min).slice(0, -len) + '9'.repeat(len)); -} - -function countZeros(integer, zeros) { - return integer - (integer % Math.pow(10, zeros)); -} - -function toQuantifier(digits) { - let [start = 0, stop = ''] = digits; - if (stop || start > 1) { - return `{${start + (stop ? ',' + stop : '')}}`; - } - return ''; -} - -function toCharacterClass(a, b, options) { - return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; -} - -function hasPadding(str) { - return /^-?(0+)\d/.test(str); -} - -function padZeros(value, tok, options) { - if (!tok.isPadded) { - return value; - } - - let diff = Math.abs(tok.maxLen - String(value).length); - let relax = options.relaxZeros !== false; - - switch (diff) { - case 0: - return ''; - case 1: - return relax ? '0?' : '0'; - case 2: - return relax ? '0{0,2}' : '00'; - default: { - return relax ? `0{0,${diff}}` : `0{${diff}}`; - } - } -} - -/** - * Cache - */ - -toRegexRange$1.cache = {}; -toRegexRange$1.clearCache = () => (toRegexRange$1.cache = {}); - -/** - * Expose `toRegexRange` - */ - -var toRegexRange_1 = toRegexRange$1; - -/*! - * fill-range - * - * Copyright (c) 2014-present, Jon Schlinkert. - * Licensed under the MIT License. - */ - -const util$3 = require$$0$4; -const toRegexRange = toRegexRange_1; - -const isObject$2 = val => val !== null && typeof val === 'object' && !Array.isArray(val); - -const transform$3 = toNumber => { - return value => toNumber === true ? Number(value) : String(value); -}; - -const isValidValue = value => { - return typeof value === 'number' || (typeof value === 'string' && value !== ''); -}; - -const isNumber$1 = num => Number.isInteger(+num); - -const zeros = input => { - let value = `${input}`; - let index = -1; - if (value[0] === '-') value = value.slice(1); - if (value === '0') return false; - while (value[++index] === '0'); - return index > 0; -}; - -const stringify$5 = (start, end, options) => { - if (typeof start === 'string' || typeof end === 'string') { - return true; - } - return options.stringify === true; -}; - -const pad = (input, maxLength, toNumber) => { - if (maxLength > 0) { - let dash = input[0] === '-' ? '-' : ''; - if (dash) input = input.slice(1); - input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); - } - if (toNumber === false) { - return String(input); - } - return input; -}; - -const toMaxLen = (input, maxLength) => { - let negative = input[0] === '-' ? '-' : ''; - if (negative) { - input = input.slice(1); - maxLength--; - } - while (input.length < maxLength) input = '0' + input; - return negative ? ('-' + input) : input; -}; - -const toSequence = (parts, options) => { - parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); - - let prefix = options.capture ? '' : '?:'; - let positives = ''; - let negatives = ''; - let result; - - if (parts.positives.length) { - positives = parts.positives.join('|'); - } - - if (parts.negatives.length) { - negatives = `-(${prefix}${parts.negatives.join('|')})`; - } - - if (positives && negatives) { - result = `${positives}|${negatives}`; - } else { - result = positives || negatives; - } - - if (options.wrap) { - return `(${prefix}${result})`; - } - - return result; -}; - -const toRange = (a, b, isNumbers, options) => { - if (isNumbers) { - return toRegexRange(a, b, { wrap: false, ...options }); - } - - let start = String.fromCharCode(a); - if (a === b) return start; - - let stop = String.fromCharCode(b); - return `[${start}-${stop}]`; -}; - -const toRegex = (start, end, options) => { - if (Array.isArray(start)) { - let wrap = options.wrap === true; - let prefix = options.capture ? '' : '?:'; - return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); - } - return toRegexRange(start, end, options); -}; - -const rangeError = (...args) => { - return new RangeError('Invalid range arguments: ' + util$3.inspect(...args)); -}; - -const invalidRange = (start, end, options) => { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; -}; - -const invalidStep = (step, options) => { - if (options.strictRanges === true) { - throw new TypeError(`Expected step "${step}" to be a number`); - } - return []; -}; - -const fillNumbers = (start, end, step = 1, options = {}) => { - let a = Number(start); - let b = Number(end); - - if (!Number.isInteger(a) || !Number.isInteger(b)) { - if (options.strictRanges === true) throw rangeError([start, end]); - return []; - } - - // fix negative zero - if (a === 0) a = 0; - if (b === 0) b = 0; - - let descending = a > b; - let startString = String(start); - let endString = String(end); - let stepString = String(step); - step = Math.max(Math.abs(step), 1); - - let padded = zeros(startString) || zeros(endString) || zeros(stepString); - let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; - let toNumber = padded === false && stringify$5(start, end, options) === false; - let format = options.transform || transform$3(toNumber); - - if (options.toRegex && step === 1) { - return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); - } - - let parts = { negatives: [], positives: [] }; - let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); - let range = []; - let index = 0; - - while (descending ? a >= b : a <= b) { - if (options.toRegex === true && step > 1) { - push(a); - } else { - range.push(pad(format(a, index), maxLen, toNumber)); - } - a = descending ? a - step : a + step; - index++; - } - - if (options.toRegex === true) { - return step > 1 - ? toSequence(parts, options) - : toRegex(range, null, { wrap: false, ...options }); - } - - return range; -}; - -const fillLetters = (start, end, step = 1, options = {}) => { - if ((!isNumber$1(start) && start.length > 1) || (!isNumber$1(end) && end.length > 1)) { - return invalidRange(start, end, options); - } - - - let format = options.transform || (val => String.fromCharCode(val)); - let a = `${start}`.charCodeAt(0); - let b = `${end}`.charCodeAt(0); - - let descending = a > b; - let min = Math.min(a, b); - let max = Math.max(a, b); - - if (options.toRegex && step === 1) { - return toRange(min, max, false, options); - } - - let range = []; - let index = 0; - - while (descending ? a >= b : a <= b) { - range.push(format(a, index)); - a = descending ? a - step : a + step; - index++; - } - - if (options.toRegex === true) { - return toRegex(range, null, { wrap: false, options }); - } - - return range; -}; - -const fill$2 = (start, end, step, options = {}) => { - if (end == null && isValidValue(start)) { - return [start]; - } - - if (!isValidValue(start) || !isValidValue(end)) { - return invalidRange(start, end, options); - } - - if (typeof step === 'function') { - return fill$2(start, end, 1, { transform: step }); - } - - if (isObject$2(step)) { - return fill$2(start, end, 0, step); - } - - let opts = { ...options }; - if (opts.capture === true) opts.wrap = true; - step = step || opts.step || 1; - - if (!isNumber$1(step)) { - if (step != null && !isObject$2(step)) return invalidStep(step, opts); - return fill$2(start, end, 1, step); - } - - if (isNumber$1(start) && isNumber$1(end)) { - return fillNumbers(start, end, step, opts); - } - - return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); -}; - -var fillRange = fill$2; - -const fill$1 = fillRange; -const utils$1 = utils$3; - -const compile$1 = (ast, options = {}) => { - let walk = (node, parent = {}) => { - let invalidBlock = utils$1.isInvalidBrace(parent); - let invalidNode = node.invalid === true && options.escapeInvalid === true; - let invalid = invalidBlock === true || invalidNode === true; - let prefix = options.escapeInvalid === true ? '\\' : ''; - let output = ''; - - if (node.isOpen === true) { - return prefix + node.value; - } - if (node.isClose === true) { - return prefix + node.value; - } - - if (node.type === 'open') { - return invalid ? (prefix + node.value) : '('; - } - - if (node.type === 'close') { - return invalid ? (prefix + node.value) : ')'; - } - - if (node.type === 'comma') { - return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); - } - - if (node.value) { - return node.value; - } - - if (node.nodes && node.ranges > 0) { - let args = utils$1.reduce(node.nodes); - let range = fill$1(...args, { ...options, wrap: false, toRegex: true }); - - if (range.length !== 0) { - return args.length > 1 && range.length > 1 ? `(${range})` : range; - } - } - - if (node.nodes) { - for (let child of node.nodes) { - output += walk(child, node); - } - } - return output; - }; - - return walk(ast); -}; - -var compile_1 = compile$1; - -const fill = fillRange; -const stringify$4 = stringify$6; -const utils = utils$3; - -const append = (queue = '', stash = '', enclose = false) => { - let result = []; - - queue = [].concat(queue); - stash = [].concat(stash); - - if (!stash.length) return queue; - if (!queue.length) { - return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; - } - - for (let item of queue) { - if (Array.isArray(item)) { - for (let value of item) { - result.push(append(value, stash, enclose)); - } - } else { - for (let ele of stash) { - if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; - result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); - } - } - } - return utils.flatten(result); -}; - -const expand$4 = (ast, options = {}) => { - let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; - - let walk = (node, parent = {}) => { - node.queue = []; - - let p = parent; - let q = parent.queue; - - while (p.type !== 'brace' && p.type !== 'root' && p.parent) { - p = p.parent; - q = p.queue; - } - - if (node.invalid || node.dollar) { - q.push(append(q.pop(), stringify$4(node, options))); - return; - } - - if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { - q.push(append(q.pop(), ['{}'])); - return; - } - - if (node.nodes && node.ranges > 0) { - let args = utils.reduce(node.nodes); - - if (utils.exceedsLimit(...args, options.step, rangeLimit)) { - throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); - } - - let range = fill(...args, options); - if (range.length === 0) { - range = stringify$4(node, options); - } - - q.push(append(q.pop(), range)); - node.nodes = []; - return; - } - - let enclose = utils.encloseBrace(node); - let queue = node.queue; - let block = node; - - while (block.type !== 'brace' && block.type !== 'root' && block.parent) { - block = block.parent; - queue = block.queue; - } - - for (let i = 0; i < node.nodes.length; i++) { - let child = node.nodes[i]; - - if (child.type === 'comma' && node.type === 'brace') { - if (i === 1) queue.push(''); - queue.push(''); - continue; - } - - if (child.type === 'close') { - q.push(append(q.pop(), queue, enclose)); - continue; - } - - if (child.value && child.type !== 'open') { - queue.push(append(queue.pop(), child.value)); - continue; - } - - if (child.nodes) { - walk(child, node); - } - } - - return queue; - }; - - return utils.flatten(walk(ast)); -}; - -var expand_1 = expand$4; - -var constants$2 = { - MAX_LENGTH: 1024 * 64, - - // Digits - CHAR_0: '0', /* 0 */ - CHAR_9: '9', /* 9 */ - - // Alphabet chars. - CHAR_UPPERCASE_A: 'A', /* A */ - CHAR_LOWERCASE_A: 'a', /* a */ - CHAR_UPPERCASE_Z: 'Z', /* Z */ - CHAR_LOWERCASE_Z: 'z', /* z */ - - CHAR_LEFT_PARENTHESES: '(', /* ( */ - CHAR_RIGHT_PARENTHESES: ')', /* ) */ - - CHAR_ASTERISK: '*', /* * */ - - // Non-alphabetic chars. - CHAR_AMPERSAND: '&', /* & */ - CHAR_AT: '@', /* @ */ - CHAR_BACKSLASH: '\\', /* \ */ - CHAR_BACKTICK: '`', /* ` */ - CHAR_CARRIAGE_RETURN: '\r', /* \r */ - CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ - CHAR_COLON: ':', /* : */ - CHAR_COMMA: ',', /* , */ - CHAR_DOLLAR: '$', /* . */ - CHAR_DOT: '.', /* . */ - CHAR_DOUBLE_QUOTE: '"', /* " */ - CHAR_EQUAL: '=', /* = */ - CHAR_EXCLAMATION_MARK: '!', /* ! */ - CHAR_FORM_FEED: '\f', /* \f */ - CHAR_FORWARD_SLASH: '/', /* / */ - CHAR_HASH: '#', /* # */ - CHAR_HYPHEN_MINUS: '-', /* - */ - CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ - CHAR_LEFT_CURLY_BRACE: '{', /* { */ - CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ - CHAR_LINE_FEED: '\n', /* \n */ - CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ - CHAR_PERCENT: '%', /* % */ - CHAR_PLUS: '+', /* + */ - CHAR_QUESTION_MARK: '?', /* ? */ - CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ - CHAR_RIGHT_CURLY_BRACE: '}', /* } */ - CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ - CHAR_SEMICOLON: ';', /* ; */ - CHAR_SINGLE_QUOTE: '\'', /* ' */ - CHAR_SPACE: ' ', /* */ - CHAR_TAB: '\t', /* \t */ - CHAR_UNDERSCORE: '_', /* _ */ - CHAR_VERTICAL_LINE: '|', /* | */ - CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ -}; - -const stringify$3 = stringify$6; - -/** - * Constants - */ - -const { - MAX_LENGTH: MAX_LENGTH$3, - CHAR_BACKSLASH, /* \ */ - CHAR_BACKTICK, /* ` */ - CHAR_COMMA: CHAR_COMMA$1, /* , */ - CHAR_DOT, /* . */ - CHAR_LEFT_PARENTHESES, /* ( */ - CHAR_RIGHT_PARENTHESES, /* ) */ - CHAR_LEFT_CURLY_BRACE, /* { */ - CHAR_RIGHT_CURLY_BRACE, /* } */ - CHAR_LEFT_SQUARE_BRACKET: CHAR_LEFT_SQUARE_BRACKET$1, /* [ */ - CHAR_RIGHT_SQUARE_BRACKET: CHAR_RIGHT_SQUARE_BRACKET$1, /* ] */ - CHAR_DOUBLE_QUOTE: CHAR_DOUBLE_QUOTE$1, /* " */ - CHAR_SINGLE_QUOTE: CHAR_SINGLE_QUOTE$1, /* ' */ - CHAR_NO_BREAK_SPACE, - CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = constants$2; - -/** - * parse - */ - -const parse$c = (input, options = {}) => { - if (typeof input !== 'string') { - throw new TypeError('Expected a string'); - } - - let opts = options || {}; - let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH$3, opts.maxLength) : MAX_LENGTH$3; - if (input.length > max) { - throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); - } - - let ast = { type: 'root', input, nodes: [] }; - let stack = [ast]; - let block = ast; - let prev = ast; - let brackets = 0; - let length = input.length; - let index = 0; - let depth = 0; - let value; - - /** - * Helpers - */ - - const advance = () => input[index++]; - const push = node => { - if (node.type === 'text' && prev.type === 'dot') { - prev.type = 'text'; - } - - if (prev && prev.type === 'text' && node.type === 'text') { - prev.value += node.value; - return; - } - - block.nodes.push(node); - node.parent = block; - node.prev = prev; - prev = node; - return node; - }; - - push({ type: 'bos' }); - - while (index < length) { - block = stack[stack.length - 1]; - value = advance(); - - /** - * Invalid chars - */ - - if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { - continue; - } - - /** - * Escaped chars - */ - - if (value === CHAR_BACKSLASH) { - push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); - continue; - } - - /** - * Right square bracket (literal): ']' - */ - - if (value === CHAR_RIGHT_SQUARE_BRACKET$1) { - push({ type: 'text', value: '\\' + value }); - continue; - } - - /** - * Left square bracket: '[' - */ - - if (value === CHAR_LEFT_SQUARE_BRACKET$1) { - brackets++; - let next; - - while (index < length && (next = advance())) { - value += next; - - if (next === CHAR_LEFT_SQUARE_BRACKET$1) { - brackets++; - continue; - } - - if (next === CHAR_BACKSLASH) { - value += advance(); - continue; - } - - if (next === CHAR_RIGHT_SQUARE_BRACKET$1) { - brackets--; - - if (brackets === 0) { - break; - } - } - } - - push({ type: 'text', value }); - continue; - } - - /** - * Parentheses - */ - - if (value === CHAR_LEFT_PARENTHESES) { - block = push({ type: 'paren', nodes: [] }); - stack.push(block); - push({ type: 'text', value }); - continue; - } - - if (value === CHAR_RIGHT_PARENTHESES) { - if (block.type !== 'paren') { - push({ type: 'text', value }); - continue; - } - block = stack.pop(); - push({ type: 'text', value }); - block = stack[stack.length - 1]; - continue; - } - - /** - * Quotes: '|"|` - */ - - if (value === CHAR_DOUBLE_QUOTE$1 || value === CHAR_SINGLE_QUOTE$1 || value === CHAR_BACKTICK) { - let open = value; - let next; - - if (options.keepQuotes !== true) { - value = ''; - } - - while (index < length && (next = advance())) { - if (next === CHAR_BACKSLASH) { - value += next + advance(); - continue; - } - - if (next === open) { - if (options.keepQuotes === true) value += next; - break; - } - - value += next; - } - - push({ type: 'text', value }); - continue; - } - - /** - * Left curly brace: '{' - */ - - if (value === CHAR_LEFT_CURLY_BRACE) { - depth++; - - let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; - let brace = { - type: 'brace', - open: true, - close: false, - dollar, - depth, - commas: 0, - ranges: 0, - nodes: [] - }; - - block = push(brace); - stack.push(block); - push({ type: 'open', value }); - continue; - } - - /** - * Right curly brace: '}' - */ - - if (value === CHAR_RIGHT_CURLY_BRACE) { - if (block.type !== 'brace') { - push({ type: 'text', value }); - continue; - } - - let type = 'close'; - block = stack.pop(); - block.close = true; - - push({ type, value }); - depth--; - - block = stack[stack.length - 1]; - continue; - } - - /** - * Comma: ',' - */ - - if (value === CHAR_COMMA$1 && depth > 0) { - if (block.ranges > 0) { - block.ranges = 0; - let open = block.nodes.shift(); - block.nodes = [open, { type: 'text', value: stringify$3(block) }]; - } - - push({ type: 'comma', value }); - block.commas++; - continue; - } - - /** - * Dot: '.' - */ - - if (value === CHAR_DOT && depth > 0 && block.commas === 0) { - let siblings = block.nodes; - - if (depth === 0 || siblings.length === 0) { - push({ type: 'text', value }); - continue; - } - - if (prev.type === 'dot') { - block.range = []; - prev.value += value; - prev.type = 'range'; - - if (block.nodes.length !== 3 && block.nodes.length !== 5) { - block.invalid = true; - block.ranges = 0; - prev.type = 'text'; - continue; - } - - block.ranges++; - block.args = []; - continue; - } - - if (prev.type === 'range') { - siblings.pop(); - - let before = siblings[siblings.length - 1]; - before.value += prev.value + value; - prev = before; - block.ranges--; - continue; - } - - push({ type: 'dot', value }); - continue; - } - - /** - * Text - */ - - push({ type: 'text', value }); - } - - // Mark imbalanced braces and brackets as invalid - do { - block = stack.pop(); - - if (block.type !== 'root') { - block.nodes.forEach(node => { - if (!node.nodes) { - if (node.type === 'open') node.isOpen = true; - if (node.type === 'close') node.isClose = true; - if (!node.nodes) node.type = 'text'; - node.invalid = true; - } - }); - - // get the location of the block on parent.nodes (block's siblings) - let parent = stack[stack.length - 1]; - let index = parent.nodes.indexOf(block); - // replace the (invalid) block with it's nodes - parent.nodes.splice(index, 1, ...block.nodes); - } - } while (stack.length > 0); - - push({ type: 'eos' }); - return ast; -}; - -var parse_1$1 = parse$c; - -const stringify$2 = stringify$6; -const compile = compile_1; -const expand$3 = expand_1; -const parse$b = parse_1$1; - -/** - * Expand the given pattern or create a regex-compatible string. - * - * ```js - * const braces = require('braces'); - * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] - * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] - * ``` - * @param {String} `str` - * @param {Object} `options` - * @return {String} - * @api public - */ - -const braces$1 = (input, options = {}) => { - let output = []; - - if (Array.isArray(input)) { - for (let pattern of input) { - let result = braces$1.create(pattern, options); - if (Array.isArray(result)) { - output.push(...result); - } else { - output.push(result); - } - } - } else { - output = [].concat(braces$1.create(input, options)); - } - - if (options && options.expand === true && options.nodupes === true) { - output = [...new Set(output)]; - } - return output; -}; - -/** - * Parse the given `str` with the given `options`. - * - * ```js - * // braces.parse(pattern, [, options]); - * const ast = braces.parse('a/{b,c}/d'); - * console.log(ast); - * ``` - * @param {String} pattern Brace pattern to parse - * @param {Object} options - * @return {Object} Returns an AST - * @api public - */ - -braces$1.parse = (input, options = {}) => parse$b(input, options); - -/** - * Creates a braces string from an AST, or an AST node. - * - * ```js - * const braces = require('braces'); - * let ast = braces.parse('foo/{a,b}/bar'); - * console.log(stringify(ast.nodes[2])); //=> '{a,b}' - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.stringify = (input, options = {}) => { - if (typeof input === 'string') { - return stringify$2(braces$1.parse(input, options), options); - } - return stringify$2(input, options); -}; - -/** - * Compiles a brace pattern into a regex-compatible, optimized string. - * This method is called by the main [braces](#braces) function by default. - * - * ```js - * const braces = require('braces'); - * console.log(braces.compile('a/{b,c}/d')); - * //=> ['a/(b|c)/d'] - * ``` - * @param {String} `input` Brace pattern or AST. - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.compile = (input, options = {}) => { - if (typeof input === 'string') { - input = braces$1.parse(input, options); - } - return compile(input, options); -}; - -/** - * Expands a brace pattern into an array. This method is called by the - * main [braces](#braces) function when `options.expand` is true. Before - * using this method it's recommended that you read the [performance notes](#performance)) - * and advantages of using [.compile](#compile) instead. - * - * ```js - * const braces = require('braces'); - * console.log(braces.expand('a/{b,c}/d')); - * //=> ['a/b/d', 'a/c/d']; - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.expand = (input, options = {}) => { - if (typeof input === 'string') { - input = braces$1.parse(input, options); - } - - let result = expand$3(input, options); - - // filter out empty strings if specified - if (options.noempty === true) { - result = result.filter(Boolean); - } - - // filter out duplicates if specified - if (options.nodupes === true) { - result = [...new Set(result)]; - } - - return result; -}; - -/** - * Processes a brace pattern and returns either an expanded array - * (if `options.expand` is true), a highly optimized regex-compatible string. - * This method is called by the main [braces](#braces) function. - * - * ```js - * const braces = require('braces'); - * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) - * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' - * ``` - * @param {String} `pattern` Brace pattern - * @param {Object} `options` - * @return {Array} Returns an array of expanded values. - * @api public - */ - -braces$1.create = (input, options = {}) => { - if (input === '' || input.length < 3) { - return [input]; - } - - return options.expand !== true - ? braces$1.compile(input, options) - : braces$1.expand(input, options); -}; - -/** - * Expose "braces" - */ - -var braces_1 = braces$1; - -var require$$0$1 = [ - "3dm", - "3ds", - "3g2", - "3gp", - "7z", - "a", - "aac", - "adp", - "ai", - "aif", - "aiff", - "alz", - "ape", - "apk", - "appimage", - "ar", - "arj", - "asf", - "au", - "avi", - "bak", - "baml", - "bh", - "bin", - "bk", - "bmp", - "btif", - "bz2", - "bzip2", - "cab", - "caf", - "cgm", - "class", - "cmx", - "cpio", - "cr2", - "cur", - "dat", - "dcm", - "deb", - "dex", - "djvu", - "dll", - "dmg", - "dng", - "doc", - "docm", - "docx", - "dot", - "dotm", - "dra", - "DS_Store", - "dsk", - "dts", - "dtshd", - "dvb", - "dwg", - "dxf", - "ecelp4800", - "ecelp7470", - "ecelp9600", - "egg", - "eol", - "eot", - "epub", - "exe", - "f4v", - "fbs", - "fh", - "fla", - "flac", - "flatpak", - "fli", - "flv", - "fpx", - "fst", - "fvt", - "g3", - "gh", - "gif", - "graffle", - "gz", - "gzip", - "h261", - "h263", - "h264", - "icns", - "ico", - "ief", - "img", - "ipa", - "iso", - "jar", - "jpeg", - "jpg", - "jpgv", - "jpm", - "jxr", - "key", - "ktx", - "lha", - "lib", - "lvp", - "lz", - "lzh", - "lzma", - "lzo", - "m3u", - "m4a", - "m4v", - "mar", - "mdi", - "mht", - "mid", - "midi", - "mj2", - "mka", - "mkv", - "mmr", - "mng", - "mobi", - "mov", - "movie", - "mp3", - "mp4", - "mp4a", - "mpeg", - "mpg", - "mpga", - "mxu", - "nef", - "npx", - "numbers", - "nupkg", - "o", - "odp", - "ods", - "odt", - "oga", - "ogg", - "ogv", - "otf", - "ott", - "pages", - "pbm", - "pcx", - "pdb", - "pdf", - "pea", - "pgm", - "pic", - "png", - "pnm", - "pot", - "potm", - "potx", - "ppa", - "ppam", - "ppm", - "pps", - "ppsm", - "ppsx", - "ppt", - "pptm", - "pptx", - "psd", - "pya", - "pyc", - "pyo", - "pyv", - "qt", - "rar", - "ras", - "raw", - "resources", - "rgb", - "rip", - "rlc", - "rmf", - "rmvb", - "rpm", - "rtf", - "rz", - "s3m", - "s7z", - "scpt", - "sgi", - "shar", - "snap", - "sil", - "sketch", - "slk", - "smv", - "snk", - "so", - "stl", - "suo", - "sub", - "swf", - "tar", - "tbz", - "tbz2", - "tga", - "tgz", - "thmx", - "tif", - "tiff", - "tlz", - "ttc", - "ttf", - "txz", - "udf", - "uvh", - "uvi", - "uvm", - "uvp", - "uvs", - "uvu", - "viv", - "vob", - "war", - "wav", - "wax", - "wbmp", - "wdp", - "weba", - "webm", - "webp", - "whl", - "wim", - "wm", - "wma", - "wmv", - "wmx", - "woff", - "woff2", - "wrm", - "wvx", - "xbm", - "xif", - "xla", - "xlam", - "xls", - "xlsb", - "xlsm", - "xlsx", - "xlt", - "xltm", - "xltx", - "xm", - "xmind", - "xpi", - "xpm", - "xwd", - "xz", - "z", - "zip", - "zipx" -]; - -var binaryExtensions$1 = require$$0$1; - -const path$8 = path$b; -const binaryExtensions = binaryExtensions$1; - -const extensions = new Set(binaryExtensions); - -var isBinaryPath$1 = filePath => extensions.has(path$8.extname(filePath).slice(1).toLowerCase()); - -var constants$1 = {}; - -(function (exports) { - -const {sep} = path$b; -const {platform} = process; -const os = require$$0$2; - -exports.EV_ALL = 'all'; -exports.EV_READY = 'ready'; -exports.EV_ADD = 'add'; -exports.EV_CHANGE = 'change'; -exports.EV_ADD_DIR = 'addDir'; -exports.EV_UNLINK = 'unlink'; -exports.EV_UNLINK_DIR = 'unlinkDir'; -exports.EV_RAW = 'raw'; -exports.EV_ERROR = 'error'; - -exports.STR_DATA = 'data'; -exports.STR_END = 'end'; -exports.STR_CLOSE = 'close'; - -exports.FSEVENT_CREATED = 'created'; -exports.FSEVENT_MODIFIED = 'modified'; -exports.FSEVENT_DELETED = 'deleted'; -exports.FSEVENT_MOVED = 'moved'; -exports.FSEVENT_CLONED = 'cloned'; -exports.FSEVENT_UNKNOWN = 'unknown'; -exports.FSEVENT_TYPE_FILE = 'file'; -exports.FSEVENT_TYPE_DIRECTORY = 'directory'; -exports.FSEVENT_TYPE_SYMLINK = 'symlink'; - -exports.KEY_LISTENERS = 'listeners'; -exports.KEY_ERR = 'errHandlers'; -exports.KEY_RAW = 'rawEmitters'; -exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW]; - -exports.DOT_SLASH = `.${sep}`; - -exports.BACK_SLASH_RE = /\\/g; -exports.DOUBLE_SLASH_RE = /\/\//; -exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/; -exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; -exports.REPLACER_RE = /^\.[/\\]/; - -exports.SLASH = '/'; -exports.SLASH_SLASH = '//'; -exports.BRACE_START = '{'; -exports.BANG = '!'; -exports.ONE_DOT = '.'; -exports.TWO_DOTS = '..'; -exports.STAR = '*'; -exports.GLOBSTAR = '**'; -exports.ROOT_GLOBSTAR = '/**/*'; -exports.SLASH_GLOBSTAR = '/**'; -exports.DIR_SUFFIX = 'Dir'; -exports.ANYMATCH_OPTS = {dot: true}; -exports.STRING_TYPE = 'string'; -exports.FUNCTION_TYPE = 'function'; -exports.EMPTY_STR = ''; -exports.EMPTY_FN = () => {}; -exports.IDENTITY_FN = val => val; - -exports.isWindows = platform === 'win32'; -exports.isMacos = platform === 'darwin'; -exports.isLinux = platform === 'linux'; -exports.isIBMi = os.type() === 'OS400'; -}(constants$1)); - -const fs$8 = require$$0$3; -const sysPath$2 = path$b; -const { promisify: promisify$2 } = require$$0$4; -const isBinaryPath = isBinaryPath$1; -const { - isWindows: isWindows$3, - isLinux, - EMPTY_FN: EMPTY_FN$2, - EMPTY_STR: EMPTY_STR$1, - KEY_LISTENERS, - KEY_ERR, - KEY_RAW, - HANDLER_KEYS, - EV_CHANGE: EV_CHANGE$2, - EV_ADD: EV_ADD$2, - EV_ADD_DIR: EV_ADD_DIR$2, - EV_ERROR: EV_ERROR$2, - STR_DATA: STR_DATA$1, - STR_END: STR_END$2, - BRACE_START: BRACE_START$1, - STAR -} = constants$1; - -const THROTTLE_MODE_WATCH = 'watch'; - -const open = promisify$2(fs$8.open); -const stat$2 = promisify$2(fs$8.stat); -const lstat$1 = promisify$2(fs$8.lstat); -const close = promisify$2(fs$8.close); -const fsrealpath = promisify$2(fs$8.realpath); - -const statMethods$1 = { lstat: lstat$1, stat: stat$2 }; - -// TODO: emit errors properly. Example: EMFILE on Macos. -const foreach = (val, fn) => { - if (val instanceof Set) { - val.forEach(fn); - } else { - fn(val); - } -}; - -const addAndConvert = (main, prop, item) => { - let container = main[prop]; - if (!(container instanceof Set)) { - main[prop] = container = new Set([container]); - } - container.add(item); -}; - -const clearItem = cont => key => { - const set = cont[key]; - if (set instanceof Set) { - set.clear(); - } else { - delete cont[key]; - } -}; - -const delFromSet = (main, prop, item) => { - const container = main[prop]; - if (container instanceof Set) { - container.delete(item); - } else if (container === item) { - delete main[prop]; - } -}; - -const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val; - -/** - * @typedef {String} Path - */ - -// fs_watch helpers - -// object to hold per-process fs_watch instances -// (may be shared across chokidar FSWatcher instances) - -/** - * @typedef {Object} FsWatchContainer - * @property {Set} listeners - * @property {Set} errHandlers - * @property {Set} rawEmitters - * @property {fs.FSWatcher=} watcher - * @property {Boolean=} watcherUnusable - */ - -/** - * @type {Map} - */ -const FsWatchInstances = new Map(); - -/** - * Instantiates the fs_watch interface - * @param {String} path to be watched - * @param {Object} options to be passed to fs_watch - * @param {Function} listener main event handler - * @param {Function} errHandler emits info about errors - * @param {Function} emitRaw emits raw event data - * @returns {fs.FSWatcher} new fsevents instance - */ -function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { - const handleEvent = (rawEvent, evPath) => { - listener(path); - emitRaw(rawEvent, evPath, {watchedPath: path}); - - // emit based on events occurring for files from a directory's watcher in - // case the file's watcher misses it (and rely on throttling to de-dupe) - if (evPath && path !== evPath) { - fsWatchBroadcast( - sysPath$2.resolve(path, evPath), KEY_LISTENERS, sysPath$2.join(path, evPath) - ); - } - }; - try { - return fs$8.watch(path, options, handleEvent); - } catch (error) { - errHandler(error); - } -} - -/** - * Helper for passing fs_watch event data to a collection of listeners - * @param {Path} fullPath absolute path bound to fs_watch instance - * @param {String} type listener type - * @param {*=} val1 arguments to be passed to listeners - * @param {*=} val2 - * @param {*=} val3 - */ -const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => { - const cont = FsWatchInstances.get(fullPath); - if (!cont) return; - foreach(cont[type], (listener) => { - listener(val1, val2, val3); - }); -}; - -/** - * Instantiates the fs_watch interface or binds listeners - * to an existing one covering the same file system entry - * @param {String} path - * @param {String} fullPath absolute path - * @param {Object} options to be passed to fs_watch - * @param {Object} handlers container for event listener functions - */ -const setFsWatchListener = (path, fullPath, options, handlers) => { - const {listener, errHandler, rawEmitter} = handlers; - let cont = FsWatchInstances.get(fullPath); - - /** @type {fs.FSWatcher=} */ - let watcher; - if (!options.persistent) { - watcher = createFsWatchInstance( - path, options, listener, errHandler, rawEmitter - ); - return watcher.close.bind(watcher); - } - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_ERR, errHandler); - addAndConvert(cont, KEY_RAW, rawEmitter); - } else { - watcher = createFsWatchInstance( - path, - options, - fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), - errHandler, // no need to use broadcast here - fsWatchBroadcast.bind(null, fullPath, KEY_RAW) - ); - if (!watcher) return; - watcher.on(EV_ERROR$2, async (error) => { - const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); - cont.watcherUnusable = true; // documented since Node 10.4.1 - // Workaround for https://github.com/joyent/node/issues/4337 - if (isWindows$3 && error.code === 'EPERM') { - try { - const fd = await open(path, 'r'); - await close(fd); - broadcastErr(error); - } catch (err) {} - } else { - broadcastErr(error); - } - }); - cont = { - listeners: listener, - errHandlers: errHandler, - rawEmitters: rawEmitter, - watcher - }; - FsWatchInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - - // removes this instance's listeners and closes the underlying fs_watch - // instance if there are no more listeners left - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_ERR, errHandler); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - // Check to protect against issue gh-730. - // if (cont.watcherUnusable) { - cont.watcher.close(); - // } - FsWatchInstances.delete(fullPath); - HANDLER_KEYS.forEach(clearItem(cont)); - cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; - -// fs_watchFile helpers - -// object to hold per-process fs_watchFile instances -// (may be shared across chokidar FSWatcher instances) -const FsWatchFileInstances = new Map(); - -/** - * Instantiates the fs_watchFile interface or binds listeners - * to an existing one covering the same file system entry - * @param {String} path to be watched - * @param {String} fullPath absolute path - * @param {Object} options options to be passed to fs_watchFile - * @param {Object} handlers container for event listener functions - * @returns {Function} closer - */ -const setFsWatchFileListener = (path, fullPath, options, handlers) => { - const {listener, rawEmitter} = handlers; - let cont = FsWatchFileInstances.get(fullPath); - - const copts = cont && cont.options; - if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { - fs$8.unwatchFile(fullPath); - cont = undefined; - } - - /* eslint-enable no-unused-vars, prefer-destructuring */ - - if (cont) { - addAndConvert(cont, KEY_LISTENERS, listener); - addAndConvert(cont, KEY_RAW, rawEmitter); - } else { - // TODO - // listeners.add(listener); - // rawEmitters.add(rawEmitter); - cont = { - listeners: listener, - rawEmitters: rawEmitter, - options, - watcher: fs$8.watchFile(fullPath, options, (curr, prev) => { - foreach(cont.rawEmitters, (rawEmitter) => { - rawEmitter(EV_CHANGE$2, fullPath, {curr, prev}); - }); - const currmtime = curr.mtimeMs; - if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { - foreach(cont.listeners, (listener) => listener(path, curr)); - } - }) - }; - FsWatchFileInstances.set(fullPath, cont); - } - // const index = cont.listeners.indexOf(listener); - - // Removes this instance's listeners and closes the underlying fs_watchFile - // instance if there are no more listeners left. - return () => { - delFromSet(cont, KEY_LISTENERS, listener); - delFromSet(cont, KEY_RAW, rawEmitter); - if (isEmptySet(cont.listeners)) { - FsWatchFileInstances.delete(fullPath); - fs$8.unwatchFile(fullPath); - cont.options = cont.watcher = undefined; - Object.freeze(cont); - } - }; -}; - -/** - * @mixin - */ -class NodeFsHandler$1 { - -/** - * @param {import("../index").FSWatcher} fsW - */ -constructor(fsW) { - this.fsw = fsW; - this._boundHandleError = (error) => fsW._handleError(error); -} - -/** - * Watch file for changes with fs_watchFile or fs_watch. - * @param {String} path to file or dir - * @param {Function} listener on fs change - * @returns {Function} closer for the watcher instance - */ -_watchWithNodeFs(path, listener) { - const opts = this.fsw.options; - const directory = sysPath$2.dirname(path); - const basename = sysPath$2.basename(path); - const parent = this.fsw._getWatchedDir(directory); - parent.add(basename); - const absolutePath = sysPath$2.resolve(path); - const options = {persistent: opts.persistent}; - if (!listener) listener = EMPTY_FN$2; - - let closer; - if (opts.usePolling) { - options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ? - opts.binaryInterval : opts.interval; - closer = setFsWatchFileListener(path, absolutePath, options, { - listener, - rawEmitter: this.fsw._emitRaw - }); - } else { - closer = setFsWatchListener(path, absolutePath, options, { - listener, - errHandler: this._boundHandleError, - rawEmitter: this.fsw._emitRaw - }); - } - return closer; -} - -/** - * Watch a file and emit add event if warranted. - * @param {Path} file Path - * @param {fs.Stats} stats result of fs_stat - * @param {Boolean} initialAdd was the file added at watch instantiation? - * @returns {Function} closer for the watcher instance - */ -_handleFile(file, stats, initialAdd) { - if (this.fsw.closed) { - return; - } - const dirname = sysPath$2.dirname(file); - const basename = sysPath$2.basename(file); - const parent = this.fsw._getWatchedDir(dirname); - // stats is always present - let prevStats = stats; - - // if the file is already being watched, do nothing - if (parent.has(basename)) return; - - const listener = async (path, newStats) => { - if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return; - if (!newStats || newStats.mtimeMs === 0) { - try { - const newStats = await stat$2(file); - if (this.fsw.closed) return; - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV_CHANGE$2, file, newStats); - } - if (isLinux && prevStats.ino !== newStats.ino) { - this.fsw._closeFile(path); - prevStats = newStats; - this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener)); - } else { - prevStats = newStats; - } - } catch (error) { - // Fix issues where mtime is null but file is still present - this.fsw._remove(dirname, basename); - } - // add is about to be emitted if file not already tracked in parent - } else if (parent.has(basename)) { - // Check that change event was not fired because of changed only accessTime. - const at = newStats.atimeMs; - const mt = newStats.mtimeMs; - if (!at || at <= mt || mt !== prevStats.mtimeMs) { - this.fsw._emit(EV_CHANGE$2, file, newStats); - } - prevStats = newStats; - } - }; - // kick off the watcher - const closer = this._watchWithNodeFs(file, listener); - - // emit an add event if we're supposed to - if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { - if (!this.fsw._throttle(EV_ADD$2, file, 0)) return; - this.fsw._emit(EV_ADD$2, file, stats); - } - - return closer; -} - -/** - * Handle symlinks encountered while reading a dir. - * @param {Object} entry returned by readdirp - * @param {String} directory path of dir being read - * @param {String} path of this item - * @param {String} item basename of this item - * @returns {Promise} true if no more processing is needed for this entry. - */ -async _handleSymlink(entry, directory, path, item) { - if (this.fsw.closed) { - return; - } - const full = entry.fullPath; - const dir = this.fsw._getWatchedDir(directory); - - if (!this.fsw.options.followSymlinks) { - // watch symlink directly (don't follow) and detect changes - this.fsw._incrReadyCount(); - const linkPath = await fsrealpath(path); - if (this.fsw.closed) return; - if (dir.has(item)) { - if (this.fsw._symlinkPaths.get(full) !== linkPath) { - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV_CHANGE$2, path, entry.stats); - } - } else { - dir.add(item); - this.fsw._symlinkPaths.set(full, linkPath); - this.fsw._emit(EV_ADD$2, path, entry.stats); - } - this.fsw._emitReady(); - return true; - } - - // don't follow the same symlink more than once - if (this.fsw._symlinkPaths.has(full)) { - return true; - } - - this.fsw._symlinkPaths.set(full, true); -} - -_handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { - // Normalize the directory name on Windows - directory = sysPath$2.join(directory, EMPTY_STR$1); - - if (!wh.hasGlob) { - throttler = this.fsw._throttle('readdir', directory, 1000); - if (!throttler) return; - } - - const previous = this.fsw._getWatchedDir(wh.path); - const current = new Set(); - - let stream = this.fsw._readdirp(directory, { - fileFilter: entry => wh.filterPath(entry), - directoryFilter: entry => wh.filterDir(entry), - depth: 0 - }).on(STR_DATA$1, async (entry) => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const item = entry.path; - let path = sysPath$2.join(directory, item); - current.add(item); - - if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) { - return; - } - - if (this.fsw.closed) { - stream = undefined; - return; - } - // Files that present in current directory snapshot - // but absent in previous are added to watch list and - // emit `add` event. - if (item === target || !target && !previous.has(item)) { - this.fsw._incrReadyCount(); - - // ensure relativeness of path is preserved in case of watcher reuse - path = sysPath$2.join(dir, sysPath$2.relative(dir, path)); - - this._addToNodeFs(path, initialAdd, wh, depth + 1); - } - }).on(EV_ERROR$2, this._boundHandleError); - - return new Promise(resolve => - stream.once(STR_END$2, () => { - if (this.fsw.closed) { - stream = undefined; - return; - } - const wasThrottled = throttler ? throttler.clear() : false; - - resolve(); - - // Files that absent in current directory snapshot - // but present in previous emit `remove` event - // and are removed from @watched[directory]. - previous.getChildren().filter((item) => { - return item !== directory && - !current.has(item) && - // in case of intersecting globs; - // a path may have been filtered out of this readdir, but - // shouldn't be removed because it matches a different glob - (!wh.hasGlob || wh.filterPath({ - fullPath: sysPath$2.resolve(directory, item) - })); - }).forEach((item) => { - this.fsw._remove(directory, item); - }); - - stream = undefined; - - // one more time for any missed in case changes came in extremely quickly - if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler); - }) - ); -} - -/** - * Read directory to add / remove files from `@watched` list and re-read it on change. - * @param {String} dir fs path - * @param {fs.Stats} stats - * @param {Boolean} initialAdd - * @param {Number} depth relative to user-supplied path - * @param {String} target child path targeted for watch - * @param {Object} wh Common watch helpers for this path - * @param {String} realpath - * @returns {Promise} closer for the watcher instance. - */ -async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { - const parentDir = this.fsw._getWatchedDir(sysPath$2.dirname(dir)); - const tracked = parentDir.has(sysPath$2.basename(dir)); - if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { - if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR$2, dir, stats); - } - - // ensure dir is tracked (harmless if redundant) - parentDir.add(sysPath$2.basename(dir)); - this.fsw._getWatchedDir(dir); - let throttler; - let closer; - - const oDepth = this.fsw.options.depth; - if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { - if (!target) { - await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); - if (this.fsw.closed) return; - } - - closer = this._watchWithNodeFs(dir, (dirPath, stats) => { - // if current directory is removed, do nothing - if (stats && stats.mtimeMs === 0) return; - - this._handleRead(dirPath, false, wh, target, dir, depth, throttler); - }); - } - return closer; -} - -/** - * Handle added file, directory, or glob pattern. - * Delegates call to _handleFile / _handleDir after checks. - * @param {String} path to file or ir - * @param {Boolean} initialAdd was the file added at watch instantiation? - * @param {Object} priorWh depth relative to user-supplied path - * @param {Number} depth Child path actually targeted for watch - * @param {String=} target Child path actually targeted for watch - * @returns {Promise} - */ -async _addToNodeFs(path, initialAdd, priorWh, depth, target) { - const ready = this.fsw._emitReady; - if (this.fsw._isIgnored(path) || this.fsw.closed) { - ready(); - return false; - } - - const wh = this.fsw._getWatchHelpers(path, depth); - if (!wh.hasGlob && priorWh) { - wh.hasGlob = priorWh.hasGlob; - wh.globFilter = priorWh.globFilter; - wh.filterPath = entry => priorWh.filterPath(entry); - wh.filterDir = entry => priorWh.filterDir(entry); - } - - // evaluate what is at the path we're being asked to watch - try { - const stats = await statMethods$1[wh.statMethod](wh.watchPath); - if (this.fsw.closed) return; - if (this.fsw._isIgnored(wh.watchPath, stats)) { - ready(); - return false; - } - - const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START$1); - let closer; - if (stats.isDirectory()) { - const absPath = sysPath$2.resolve(path); - const targetPath = follow ? await fsrealpath(path) : path; - if (this.fsw.closed) return; - closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); - if (this.fsw.closed) return; - // preserve this symlink's target path - if (absPath !== targetPath && targetPath !== undefined) { - this.fsw._symlinkPaths.set(absPath, targetPath); - } - } else if (stats.isSymbolicLink()) { - const targetPath = follow ? await fsrealpath(path) : path; - if (this.fsw.closed) return; - const parent = sysPath$2.dirname(wh.watchPath); - this.fsw._getWatchedDir(parent).add(wh.watchPath); - this.fsw._emit(EV_ADD$2, wh.watchPath, stats); - closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); - if (this.fsw.closed) return; - - // preserve this symlink's target path - if (targetPath !== undefined) { - this.fsw._symlinkPaths.set(sysPath$2.resolve(path), targetPath); - } - } else { - closer = this._handleFile(wh.watchPath, stats, initialAdd); - } - ready(); - - this.fsw._addPathCloser(path, closer); - return false; - - } catch (error) { - if (this.fsw._handleError(error)) { - ready(); - return path; - } - } -} - -} - -var nodefsHandler = NodeFsHandler$1; - -var fseventsHandler = {exports: {}}; - -const fs$7 = require$$0$3; -const sysPath$1 = path$b; -const { promisify: promisify$1 } = require$$0$4; - -let fsevents; -try { - fsevents = undefined; -} catch (error) { - if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error); -} - -if (fsevents) { - // TODO: real check - const mtch = process.version.match(/v(\d+)\.(\d+)/); - if (mtch && mtch[1] && mtch[2]) { - const maj = Number.parseInt(mtch[1], 10); - const min = Number.parseInt(mtch[2], 10); - if (maj === 8 && min < 16) { - fsevents = undefined; - } - } -} - -const { - EV_ADD: EV_ADD$1, - EV_CHANGE: EV_CHANGE$1, - EV_ADD_DIR: EV_ADD_DIR$1, - EV_UNLINK: EV_UNLINK$1, - EV_ERROR: EV_ERROR$1, - STR_DATA, - STR_END: STR_END$1, - FSEVENT_CREATED, - FSEVENT_MODIFIED, - FSEVENT_DELETED, - FSEVENT_MOVED, - // FSEVENT_CLONED, - FSEVENT_UNKNOWN, - FSEVENT_TYPE_FILE, - FSEVENT_TYPE_DIRECTORY, - FSEVENT_TYPE_SYMLINK, - - ROOT_GLOBSTAR, - DIR_SUFFIX, - DOT_SLASH, - FUNCTION_TYPE: FUNCTION_TYPE$1, - EMPTY_FN: EMPTY_FN$1, - IDENTITY_FN -} = constants$1; - -const Depth = (value) => isNaN(value) ? {} : {depth: value}; - -const stat$1 = promisify$1(fs$7.stat); -const lstat = promisify$1(fs$7.lstat); -const realpath$1 = promisify$1(fs$7.realpath); - -const statMethods = { stat: stat$1, lstat }; - -/** - * @typedef {String} Path - */ - -/** - * @typedef {Object} FsEventsWatchContainer - * @property {Set} listeners - * @property {Function} rawEmitter - * @property {{stop: Function}} watcher - */ - -// fsevents instance helper functions -/** - * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances) - * @type {Map} - */ -const FSEventsWatchers = new Map(); - -// Threshold of duplicate path prefixes at which to start -// consolidating going forward -const consolidateThreshhold = 10; - -const wrongEventFlags = new Set([ - 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912 -]); - -/** - * Instantiates the fsevents interface - * @param {Path} path path to be watched - * @param {Function} callback called when fsevents is bound and ready - * @returns {{stop: Function}} new fsevents instance - */ -const createFSEventsInstance = (path, callback) => { - const stop = fsevents.watch(path, callback); - return {stop}; -}; - -/** - * Instantiates the fsevents interface or binds listeners to an existing one covering - * the same file tree. - * @param {Path} path - to be watched - * @param {Path} realPath - real path for symlinks - * @param {Function} listener - called when fsevents emits events - * @param {Function} rawEmitter - passes data to listeners of the 'raw' event - * @returns {Function} closer - */ -function setFSEventsListener(path, realPath, listener, rawEmitter) { - let watchPath = sysPath$1.extname(realPath) ? sysPath$1.dirname(realPath) : realPath; - - const parentPath = sysPath$1.dirname(watchPath); - let cont = FSEventsWatchers.get(watchPath); - - // If we've accumulated a substantial number of paths that - // could have been consolidated by watching one directory - // above the current one, create a watcher on the parent - // path instead, so that we do consolidate going forward. - if (couldConsolidate(parentPath)) { - watchPath = parentPath; - } - - const resolvedPath = sysPath$1.resolve(path); - const hasSymlink = resolvedPath !== realPath; - - const filteredListener = (fullPath, flags, info) => { - if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath); - if ( - fullPath === resolvedPath || - !fullPath.indexOf(resolvedPath + sysPath$1.sep) - ) listener(fullPath, flags, info); - }; - - // check if there is already a watcher on a parent path - // modifies `watchPath` to the parent path when it finds a match - let watchedParent = false; - for (const watchedPath of FSEventsWatchers.keys()) { - if (realPath.indexOf(sysPath$1.resolve(watchedPath) + sysPath$1.sep) === 0) { - watchPath = watchedPath; - cont = FSEventsWatchers.get(watchPath); - watchedParent = true; - break; - } - } - - if (cont || watchedParent) { - cont.listeners.add(filteredListener); - } else { - cont = { - listeners: new Set([filteredListener]), - rawEmitter, - watcher: createFSEventsInstance(watchPath, (fullPath, flags) => { - if (!cont.listeners.size) return; - const info = fsevents.getInfo(fullPath, flags); - cont.listeners.forEach(list => { - list(fullPath, flags, info); - }); - - cont.rawEmitter(info.event, fullPath, info); - }) - }; - FSEventsWatchers.set(watchPath, cont); - } - - // removes this instance's listeners and closes the underlying fsevents - // instance if there are no more listeners left - return () => { - const lst = cont.listeners; - - lst.delete(filteredListener); - if (!lst.size) { - FSEventsWatchers.delete(watchPath); - if (cont.watcher) return cont.watcher.stop().then(() => { - cont.rawEmitter = cont.watcher = undefined; - Object.freeze(cont); - }); - } - }; -} - -// Decide whether or not we should start a new higher-level -// parent watcher -const couldConsolidate = (path) => { - let count = 0; - for (const watchPath of FSEventsWatchers.keys()) { - if (watchPath.indexOf(path) === 0) { - count++; - if (count >= consolidateThreshhold) { - return true; - } - } - } - - return false; -}; - -// returns boolean indicating whether fsevents can be used -const canUse = () => fsevents && FSEventsWatchers.size < 128; - -// determines subdirectory traversal levels from root to path -const calcDepth = (path, root) => { - let i = 0; - while (!path.indexOf(root) && (path = sysPath$1.dirname(path)) !== root) i++; - return i; -}; - -// returns boolean indicating whether the fsevents' event info has the same type -// as the one returned by fs.stat -const sameTypes = (info, stats) => ( - info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() || - info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() || - info.type === FSEVENT_TYPE_FILE && stats.isFile() -); - -/** - * @mixin - */ -class FsEventsHandler$1 { - -/** - * @param {import('../index').FSWatcher} fsw - */ -constructor(fsw) { - this.fsw = fsw; -} -checkIgnored(path, stats) { - const ipaths = this.fsw._ignoredPaths; - if (this.fsw._isIgnored(path, stats)) { - ipaths.add(path); - if (stats && stats.isDirectory()) { - ipaths.add(path + ROOT_GLOBSTAR); - } - return true; - } - - ipaths.delete(path); - ipaths.delete(path + ROOT_GLOBSTAR); -} - -addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) { - const event = watchedDir.has(item) ? EV_CHANGE$1 : EV_ADD$1; - this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts); -} - -async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) { - try { - const stats = await stat$1(path); - if (this.fsw.closed) return; - if (sameTypes(info, stats)) { - this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } else { - this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } catch (error) { - if (error.code === 'EACCES') { - this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } else { - this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } -} - -handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) { - if (this.fsw.closed || this.checkIgnored(path)) return; - - if (event === EV_UNLINK$1) { - const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY; - // suppress unlink events on never before seen files - if (isDirectory || watchedDir.has(item)) { - this.fsw._remove(parent, item, isDirectory); - } - } else { - if (event === EV_ADD$1) { - // track new directories - if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path); - - if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) { - // push symlinks back to the top of the stack to get handled - const curDepth = opts.depth === undefined ? - undefined : calcDepth(fullPath, realPath) + 1; - return this._addToFsEvents(path, false, true, curDepth); - } - - // track new paths - // (other than symlinks being followed, which will be tracked soon) - this.fsw._getWatchedDir(parent).add(item); - } - /** - * @type {'add'|'addDir'|'unlink'|'unlinkDir'} - */ - const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event; - this.fsw._emit(eventName, path); - if (eventName === EV_ADD_DIR$1) this._addToFsEvents(path, false, true); - } -} - -/** - * Handle symlinks encountered during directory scan - * @param {String} watchPath - file/dir path to be watched with fsevents - * @param {String} realPath - real path (in case of symlinks) - * @param {Function} transform - path transformer - * @param {Function} globFilter - path filter in case a glob pattern was provided - * @returns {Function} closer for the watcher instance -*/ -_watchWithFsEvents(watchPath, realPath, transform, globFilter) { - if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return; - const opts = this.fsw.options; - const watchCallback = async (fullPath, flags, info) => { - if (this.fsw.closed) return; - if ( - opts.depth !== undefined && - calcDepth(fullPath, realPath) > opts.depth - ) return; - const path = transform(sysPath$1.join( - watchPath, sysPath$1.relative(watchPath, fullPath) - )); - if (globFilter && !globFilter(path)) return; - // ensure directories are tracked - const parent = sysPath$1.dirname(path); - const item = sysPath$1.basename(path); - const watchedDir = this.fsw._getWatchedDir( - info.type === FSEVENT_TYPE_DIRECTORY ? path : parent - ); - - // correct for wrong events emitted - if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) { - if (typeof opts.ignored === FUNCTION_TYPE$1) { - let stats; - try { - stats = await stat$1(path); - } catch (error) {} - if (this.fsw.closed) return; - if (this.checkIgnored(path, stats)) return; - if (sameTypes(info, stats)) { - this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } else { - this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } else { - this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } else { - switch (info.event) { - case FSEVENT_CREATED: - case FSEVENT_MODIFIED: - return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); - case FSEVENT_DELETED: - case FSEVENT_MOVED: - return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); - } - } - }; - - const closer = setFSEventsListener( - watchPath, - realPath, - watchCallback, - this.fsw._emitRaw - ); - - this.fsw._emitReady(); - return closer; -} - -/** - * Handle symlinks encountered during directory scan - * @param {String} linkPath path to symlink - * @param {String} fullPath absolute path to the symlink - * @param {Function} transform pre-existing path transformer - * @param {Number} curDepth level of subdirectories traversed to where symlink is - * @returns {Promise} - */ -async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) { - // don't follow the same symlink more than once - if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return; - - this.fsw._symlinkPaths.set(fullPath, true); - this.fsw._incrReadyCount(); - - try { - const linkTarget = await realpath$1(linkPath); - if (this.fsw.closed) return; - if (this.fsw._isIgnored(linkTarget)) { - return this.fsw._emitReady(); - } - - this.fsw._incrReadyCount(); - - // add the linkTarget for watching with a wrapper for transform - // that causes emitted paths to incorporate the link's path - this._addToFsEvents(linkTarget || linkPath, (path) => { - let aliasedPath = linkPath; - if (linkTarget && linkTarget !== DOT_SLASH) { - aliasedPath = path.replace(linkTarget, linkPath); - } else if (path !== DOT_SLASH) { - aliasedPath = sysPath$1.join(linkPath, path); - } - return transform(aliasedPath); - }, false, curDepth); - } catch(error) { - if (this.fsw._handleError(error)) { - return this.fsw._emitReady(); - } - } -} - -/** - * - * @param {Path} newPath - * @param {fs.Stats} stats - */ -emitAdd(newPath, stats, processPath, opts, forceAdd) { - const pp = processPath(newPath); - const isDir = stats.isDirectory(); - const dirObj = this.fsw._getWatchedDir(sysPath$1.dirname(pp)); - const base = sysPath$1.basename(pp); - - // ensure empty dirs get tracked - if (isDir) this.fsw._getWatchedDir(pp); - if (dirObj.has(base)) return; - dirObj.add(base); - - if (!opts.ignoreInitial || forceAdd === true) { - this.fsw._emit(isDir ? EV_ADD_DIR$1 : EV_ADD$1, pp, stats); - } -} - -initWatch(realPath, path, wh, processPath) { - if (this.fsw.closed) return; - const closer = this._watchWithFsEvents( - wh.watchPath, - sysPath$1.resolve(realPath || wh.watchPath), - processPath, - wh.globFilter - ); - this.fsw._addPathCloser(path, closer); -} - -/** - * Handle added path with fsevents - * @param {String} path file/dir path or glob pattern - * @param {Function|Boolean=} transform converts working path to what the user expects - * @param {Boolean=} forceAdd ensure add is emitted - * @param {Number=} priorDepth Level of subdirectories already traversed. - * @returns {Promise} - */ -async _addToFsEvents(path, transform, forceAdd, priorDepth) { - if (this.fsw.closed) { - return; - } - const opts = this.fsw.options; - const processPath = typeof transform === FUNCTION_TYPE$1 ? transform : IDENTITY_FN; - - const wh = this.fsw._getWatchHelpers(path); - - // evaluate what is at the path we're being asked to watch - try { - const stats = await statMethods[wh.statMethod](wh.watchPath); - if (this.fsw.closed) return; - if (this.fsw._isIgnored(wh.watchPath, stats)) { - throw null; - } - if (stats.isDirectory()) { - // emit addDir unless this is a glob parent - if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd); - - // don't recurse further if it would exceed depth setting - if (priorDepth && priorDepth > opts.depth) return; - - // scan the contents of the dir - this.fsw._readdirp(wh.watchPath, { - fileFilter: entry => wh.filterPath(entry), - directoryFilter: entry => wh.filterDir(entry), - ...Depth(opts.depth - (priorDepth || 0)) - }).on(STR_DATA, (entry) => { - // need to check filterPath on dirs b/c filterDir is less restrictive - if (this.fsw.closed) { - return; - } - if (entry.stats.isDirectory() && !wh.filterPath(entry)) return; - - const joinedPath = sysPath$1.join(wh.watchPath, entry.path); - const {fullPath} = entry; - - if (wh.followSymlinks && entry.stats.isSymbolicLink()) { - // preserve the current depth here since it can't be derived from - // real paths past the symlink - const curDepth = opts.depth === undefined ? - undefined : calcDepth(joinedPath, sysPath$1.resolve(wh.watchPath)) + 1; - - this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth); - } else { - this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd); - } - }).on(EV_ERROR$1, EMPTY_FN$1).on(STR_END$1, () => { - this.fsw._emitReady(); - }); - } else { - this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd); - this.fsw._emitReady(); - } - } catch (error) { - if (!error || this.fsw._handleError(error)) { - // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__- - this.fsw._emitReady(); - this.fsw._emitReady(); - } - } - - if (opts.persistent && forceAdd !== true) { - if (typeof transform === FUNCTION_TYPE$1) { - // realpath has already been resolved - this.initWatch(undefined, path, wh, processPath); - } else { - let realPath; - try { - realPath = await realpath$1(wh.watchPath); - } catch (e) {} - this.initWatch(realPath, path, wh, processPath); - } - } -} - -} - -fseventsHandler.exports = FsEventsHandler$1; -fseventsHandler.exports.canUse = canUse; - -const { EventEmitter } = require$$0$5; -const fs$6 = require$$0$3; -const sysPath = path$b; -const { promisify } = require$$0$4; -const readdirp = readdirp_1; -const anymatch = anymatch$2.exports.default; -const globParent = globParent$1; -const isGlob = isGlob$2; -const braces = braces_1; -const normalizePath = normalizePath$2; - -const NodeFsHandler = nodefsHandler; -const FsEventsHandler = fseventsHandler.exports; -const { - EV_ALL, - EV_READY, - EV_ADD, - EV_CHANGE, - EV_UNLINK, - EV_ADD_DIR, - EV_UNLINK_DIR, - EV_RAW, - EV_ERROR, - - STR_CLOSE, - STR_END, - - BACK_SLASH_RE, - DOUBLE_SLASH_RE, - SLASH_OR_BACK_SLASH_RE, - DOT_RE, - REPLACER_RE, - - SLASH: SLASH$1, - SLASH_SLASH, - BRACE_START, - BANG, - ONE_DOT, - TWO_DOTS, - GLOBSTAR: GLOBSTAR$1, - SLASH_GLOBSTAR, - ANYMATCH_OPTS, - STRING_TYPE, - FUNCTION_TYPE, - EMPTY_STR, - EMPTY_FN, - - isWindows: isWindows$2, - isMacos, - isIBMi -} = constants$1; - -const stat = promisify(fs$6.stat); -const readdir = promisify(fs$6.readdir); - -/** - * @typedef {String} Path - * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName - * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType - */ - -/** - * - * @typedef {Object} WatchHelpers - * @property {Boolean} followSymlinks - * @property {'stat'|'lstat'} statMethod - * @property {Path} path - * @property {Path} watchPath - * @property {Function} entryPath - * @property {Boolean} hasGlob - * @property {Object} globFilter - * @property {Function} filterPath - * @property {Function} filterDir - */ - -const arrify = (value = []) => Array.isArray(value) ? value : [value]; -const flatten$1 = (list, result = []) => { - list.forEach(item => { - if (Array.isArray(item)) { - flatten$1(item, result); - } else { - result.push(item); - } - }); - return result; -}; - -const unifyPaths = (paths_) => { - /** - * @type {Array} - */ - const paths = flatten$1(arrify(paths_)); - if (!paths.every(p => typeof p === STRING_TYPE)) { - throw new TypeError(`Non-string provided as watch path: ${paths}`); - } - return paths.map(normalizePathToUnix); -}; - -// If SLASH_SLASH occurs at the beginning of path, it is not replaced -// because "//StoragePC/DrivePool/Movies" is a valid network path -const toUnix = (string) => { - let str = string.replace(BACK_SLASH_RE, SLASH$1); - let prepend = false; - if (str.startsWith(SLASH_SLASH)) { - prepend = true; - } - while (str.match(DOUBLE_SLASH_RE)) { - str = str.replace(DOUBLE_SLASH_RE, SLASH$1); - } - if (prepend) { - str = SLASH$1 + str; - } - return str; -}; - -// Our version of upath.normalize -// TODO: this is not equal to path-normalize module - investigate why -const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); - -const normalizeIgnored = (cwd = EMPTY_STR) => (path) => { - if (typeof path !== STRING_TYPE) return path; - return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); -}; - -const getAbsolutePath = (path, cwd) => { - if (sysPath.isAbsolute(path)) { - return path; - } - if (path.startsWith(BANG)) { - return BANG + sysPath.join(cwd, path.slice(1)); - } - return sysPath.join(cwd, path); -}; - -const undef = (opts, key) => opts[key] === undefined; - -/** - * Directory entry. - * @property {Path} path - * @property {Set} items - */ -class DirEntry { - /** - * @param {Path} dir - * @param {Function} removeWatcher - */ - constructor(dir, removeWatcher) { - this.path = dir; - this._removeWatcher = removeWatcher; - /** @type {Set} */ - this.items = new Set(); - } - - add(item) { - const {items} = this; - if (!items) return; - if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item); - } - - async remove(item) { - const {items} = this; - if (!items) return; - items.delete(item); - if (items.size > 0) return; - - const dir = this.path; - try { - await readdir(dir); - } catch (err) { - if (this._removeWatcher) { - this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); - } - } - } - - has(item) { - const {items} = this; - if (!items) return; - return items.has(item); - } - - /** - * @returns {Array} - */ - getChildren() { - const {items} = this; - if (!items) return; - return [...items.values()]; - } - - dispose() { - this.items.clear(); - delete this.path; - delete this._removeWatcher; - delete this.items; - Object.freeze(this); - } -} - -const STAT_METHOD_F = 'stat'; -const STAT_METHOD_L = 'lstat'; -class WatchHelper { - constructor(path, watchPath, follow, fsw) { - this.fsw = fsw; - this.path = path = path.replace(REPLACER_RE, EMPTY_STR); - this.watchPath = watchPath; - this.fullWatchPath = sysPath.resolve(watchPath); - this.hasGlob = watchPath !== path; - /** @type {object|boolean} */ - if (path === EMPTY_STR) this.hasGlob = false; - this.globSymlink = this.hasGlob && follow ? undefined : false; - this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false; - this.dirParts = this.getDirParts(path); - this.dirParts.forEach((parts) => { - if (parts.length > 1) parts.pop(); - }); - this.followSymlinks = follow; - this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; - } - - checkGlobSymlink(entry) { - // only need to resolve once - // first entry should always have entry.parentDir === EMPTY_STR - if (this.globSymlink === undefined) { - this.globSymlink = entry.fullParentDir === this.fullWatchPath ? - false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath}; - } - - if (this.globSymlink) { - return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath); - } - - return entry.fullPath; - } - - entryPath(entry) { - return sysPath.join(this.watchPath, - sysPath.relative(this.watchPath, this.checkGlobSymlink(entry)) - ); - } - - filterPath(entry) { - const {stats} = entry; - if (stats && stats.isSymbolicLink()) return this.filterDir(entry); - const resolvedPath = this.entryPath(entry); - const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? - this.globFilter(resolvedPath) : true; - return matchesGlob && - this.fsw._isntIgnored(resolvedPath, stats) && - this.fsw._hasReadPermissions(stats); - } - - getDirParts(path) { - if (!this.hasGlob) return []; - const parts = []; - const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path]; - expandedPath.forEach((path) => { - parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE)); - }); - return parts; - } - - filterDir(entry) { - if (this.hasGlob) { - const entryParts = this.getDirParts(this.checkGlobSymlink(entry)); - let globstar = false; - this.unmatchedGlob = !this.dirParts.some((parts) => { - return parts.every((part, i) => { - if (part === GLOBSTAR$1) globstar = true; - return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS); - }); - }); - } - return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats); - } -} - -/** - * Watches files & directories for changes. Emitted events: - * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` - * - * new FSWatcher() - * .add(directories) - * .on('add', path => log('File', path, 'was added')) - */ -class FSWatcher extends EventEmitter { -// Not indenting methods for history sake; for now. -constructor(_opts) { - super(); - - const opts = {}; - if (_opts) Object.assign(opts, _opts); // for frozen objects - - /** @type {Map} */ - this._watched = new Map(); - /** @type {Map} */ - this._closers = new Map(); - /** @type {Set} */ - this._ignoredPaths = new Set(); - - /** @type {Map} */ - this._throttled = new Map(); - - /** @type {Map} */ - this._symlinkPaths = new Map(); - - this._streams = new Set(); - this.closed = false; - - // Set up default options. - if (undef(opts, 'persistent')) opts.persistent = true; - if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false; - if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false; - if (undef(opts, 'interval')) opts.interval = 100; - if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300; - if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false; - opts.enableBinaryInterval = opts.binaryInterval !== opts.interval; - - // Enable fsevents on OS X when polling isn't explicitly enabled. - if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling; - - // If we can't use fsevents, ensure the options reflect it's disabled. - const canUseFsEvents = FsEventsHandler.canUse(); - if (!canUseFsEvents) opts.useFsEvents = false; - - // Use polling on Mac if not using fsevents. - // Other platforms use non-polling fs_watch. - if (undef(opts, 'usePolling') && !opts.useFsEvents) { - opts.usePolling = isMacos; - } - - // Always default to polling on IBM i because fs.watch() is not available on IBM i. - if(isIBMi) { - opts.usePolling = true; - } - - // Global override (useful for end-developers that need to force polling for all - // instances of chokidar, regardless of usage/dependency depth) - const envPoll = process.env.CHOKIDAR_USEPOLLING; - if (envPoll !== undefined) { - const envLower = envPoll.toLowerCase(); - - if (envLower === 'false' || envLower === '0') { - opts.usePolling = false; - } else if (envLower === 'true' || envLower === '1') { - opts.usePolling = true; - } else { - opts.usePolling = !!envLower; - } - } - const envInterval = process.env.CHOKIDAR_INTERVAL; - if (envInterval) { - opts.interval = Number.parseInt(envInterval, 10); - } - - // Editor atomic write normalization enabled by default with fs.watch - if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents; - if (opts.atomic) this._pendingUnlinks = new Map(); - - if (undef(opts, 'followSymlinks')) opts.followSymlinks = true; - - if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false; - if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {}; - const awf = opts.awaitWriteFinish; - if (awf) { - if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000; - if (!awf.pollInterval) awf.pollInterval = 100; - this._pendingWrites = new Map(); - } - if (opts.ignored) opts.ignored = arrify(opts.ignored); - - let readyCalls = 0; - this._emitReady = () => { - readyCalls++; - if (readyCalls >= this._readyCount) { - this._emitReady = EMPTY_FN; - this._readyEmitted = true; - // use process.nextTick to allow time for listener to be bound - process.nextTick(() => this.emit(EV_READY)); - } - }; - this._emitRaw = (...args) => this.emit(EV_RAW, ...args); - this._readyEmitted = false; - this.options = opts; - - // Initialize with proper watcher. - if (opts.useFsEvents) { - this._fsEventsHandler = new FsEventsHandler(this); - } else { - this._nodeFsHandler = new NodeFsHandler(this); - } - - // You’re frozen when your heart’s not open. - Object.freeze(opts); -} - -// Public methods - -/** - * Adds paths to be watched on an existing FSWatcher instance - * @param {Path|Array} paths_ - * @param {String=} _origAdd private; for handling non-existent paths to be watched - * @param {Boolean=} _internal private; indicates a non-user add - * @returns {FSWatcher} for chaining - */ -add(paths_, _origAdd, _internal) { - const {cwd, disableGlobbing} = this.options; - this.closed = false; - let paths = unifyPaths(paths_); - if (cwd) { - paths = paths.map((path) => { - const absPath = getAbsolutePath(path, cwd); - - // Check `path` instead of `absPath` because the cwd portion can't be a glob - if (disableGlobbing || !isGlob(path)) { - return absPath; - } - return normalizePath(absPath); - }); - } - - // set aside negated glob strings - paths = paths.filter((path) => { - if (path.startsWith(BANG)) { - this._ignoredPaths.add(path.slice(1)); - return false; - } - - // if a path is being added that was previously ignored, stop ignoring it - this._ignoredPaths.delete(path); - this._ignoredPaths.delete(path + SLASH_GLOBSTAR); - - // reset the cached userIgnored anymatch fn - // to make ignoredPaths changes effective - this._userIgnored = undefined; - - return true; - }); - - if (this.options.useFsEvents && this._fsEventsHandler) { - if (!this._readyCount) this._readyCount = paths.length; - if (this.options.persistent) this._readyCount *= 2; - paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path)); - } else { - if (!this._readyCount) this._readyCount = 0; - this._readyCount += paths.length; - Promise.all( - paths.map(async path => { - const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd); - if (res) this._emitReady(); - return res; - }) - ).then(results => { - if (this.closed) return; - results.filter(item => item).forEach(item => { - this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); - }); - }); - } - - return this; -} - -/** - * Close watchers or start ignoring events from specified paths. - * @param {Path|Array} paths_ - string or array of strings, file/directory paths and/or globs - * @returns {FSWatcher} for chaining -*/ -unwatch(paths_) { - if (this.closed) return this; - const paths = unifyPaths(paths_); - const {cwd} = this.options; - - paths.forEach((path) => { - // convert to absolute path unless relative path already matches - if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { - if (cwd) path = sysPath.join(cwd, path); - path = sysPath.resolve(path); - } - - this._closePath(path); - - this._ignoredPaths.add(path); - if (this._watched.has(path)) { - this._ignoredPaths.add(path + SLASH_GLOBSTAR); - } - - // reset the cached userIgnored anymatch fn - // to make ignoredPaths changes effective - this._userIgnored = undefined; - }); - - return this; -} - -/** - * Close watchers and remove all listeners from watched paths. - * @returns {Promise}. -*/ -close() { - if (this.closed) return this._closePromise; - this.closed = true; - - // Memory management. - this.removeAllListeners(); - const closers = []; - this._closers.forEach(closerList => closerList.forEach(closer => { - const promise = closer(); - if (promise instanceof Promise) closers.push(promise); - })); - this._streams.forEach(stream => stream.destroy()); - this._userIgnored = undefined; - this._readyCount = 0; - this._readyEmitted = false; - this._watched.forEach(dirent => dirent.dispose()); - ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => { - this[`_${key}`].clear(); - }); - - this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve(); - return this._closePromise; -} - -/** - * Expose list of watched paths - * @returns {Object} for chaining -*/ -getWatched() { - const watchList = {}; - this._watched.forEach((entry, dir) => { - const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; - watchList[key || ONE_DOT] = entry.getChildren().sort(); - }); - return watchList; -} - -emitWithAll(event, args) { - this.emit(...args); - if (event !== EV_ERROR) this.emit(EV_ALL, ...args); -} - -// Common helpers -// -------------- - -/** - * Normalize and emit events. - * Calling _emit DOES NOT MEAN emit() would be called! - * @param {EventName} event Type of event - * @param {Path} path File or directory path - * @param {*=} val1 arguments to be passed with event - * @param {*=} val2 - * @param {*=} val3 - * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ -async _emit(event, path, val1, val2, val3) { - if (this.closed) return; - - const opts = this.options; - if (isWindows$2) path = sysPath.normalize(path); - if (opts.cwd) path = sysPath.relative(opts.cwd, path); - /** @type Array */ - const args = [event, path]; - if (val3 !== undefined) args.push(val1, val2, val3); - else if (val2 !== undefined) args.push(val1, val2); - else if (val1 !== undefined) args.push(val1); - - const awf = opts.awaitWriteFinish; - let pw; - if (awf && (pw = this._pendingWrites.get(path))) { - pw.lastChange = new Date(); - return this; - } - - if (opts.atomic) { - if (event === EV_UNLINK) { - this._pendingUnlinks.set(path, args); - setTimeout(() => { - this._pendingUnlinks.forEach((entry, path) => { - this.emit(...entry); - this.emit(EV_ALL, ...entry); - this._pendingUnlinks.delete(path); - }); - }, typeof opts.atomic === 'number' ? opts.atomic : 100); - return this; - } - if (event === EV_ADD && this._pendingUnlinks.has(path)) { - event = args[0] = EV_CHANGE; - this._pendingUnlinks.delete(path); - } - } - - if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) { - const awfEmit = (err, stats) => { - if (err) { - event = args[0] = EV_ERROR; - args[1] = err; - this.emitWithAll(event, args); - } else if (stats) { - // if stats doesn't exist the file must have been deleted - if (args.length > 2) { - args[2] = stats; - } else { - args.push(stats); - } - this.emitWithAll(event, args); - } - }; - - this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); - return this; - } - - if (event === EV_CHANGE) { - const isThrottled = !this._throttle(EV_CHANGE, path, 50); - if (isThrottled) return this; - } - - if (opts.alwaysStat && val1 === undefined && - (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE) - ) { - const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; - let stats; - try { - stats = await stat(fullPath); - } catch (err) {} - // Suppress event when fs_stat fails, to avoid sending undefined 'stat' - if (!stats || this.closed) return; - args.push(stats); - } - this.emitWithAll(event, args); - - return this; -} - -/** - * Common handler for errors - * @param {Error} error - * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag - */ -_handleError(error) { - const code = error && error.code; - if (error && code !== 'ENOENT' && code !== 'ENOTDIR' && - (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES')) - ) { - this.emit(EV_ERROR, error); - } - return error || this.closed; -} - -/** - * Helper utility for throttling - * @param {ThrottleType} actionType type being throttled - * @param {Path} path being acted upon - * @param {Number} timeout duration of time to suppress duplicate actions - * @returns {Object|false} tracking object or false if action should be suppressed - */ -_throttle(actionType, path, timeout) { - if (!this._throttled.has(actionType)) { - this._throttled.set(actionType, new Map()); - } - - /** @type {Map} */ - const action = this._throttled.get(actionType); - /** @type {Object} */ - const actionPath = action.get(path); - - if (actionPath) { - actionPath.count++; - return false; - } - - let timeoutObject; - const clear = () => { - const item = action.get(path); - const count = item ? item.count : 0; - action.delete(path); - clearTimeout(timeoutObject); - if (item) clearTimeout(item.timeoutObject); - return count; - }; - timeoutObject = setTimeout(clear, timeout); - const thr = {timeoutObject, clear, count: 0}; - action.set(path, thr); - return thr; -} - -_incrReadyCount() { - return this._readyCount++; -} - -/** - * Awaits write operation to finish. - * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. - * @param {Path} path being acted upon - * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished - * @param {EventName} event - * @param {Function} awfEmit Callback to be called when ready for event to be emitted. - */ -_awaitWriteFinish(path, threshold, event, awfEmit) { - let timeoutHandler; - - let fullPath = path; - if (this.options.cwd && !sysPath.isAbsolute(path)) { - fullPath = sysPath.join(this.options.cwd, path); - } - - const now = new Date(); - - const awaitWriteFinish = (prevStat) => { - fs$6.stat(fullPath, (err, curStat) => { - if (err || !this._pendingWrites.has(path)) { - if (err && err.code !== 'ENOENT') awfEmit(err); - return; - } - - const now = Number(new Date()); - - if (prevStat && curStat.size !== prevStat.size) { - this._pendingWrites.get(path).lastChange = now; - } - const pw = this._pendingWrites.get(path); - const df = now - pw.lastChange; - - if (df >= threshold) { - this._pendingWrites.delete(path); - awfEmit(undefined, curStat); - } else { - timeoutHandler = setTimeout( - awaitWriteFinish, - this.options.awaitWriteFinish.pollInterval, - curStat - ); - } - }); - }; - - if (!this._pendingWrites.has(path)) { - this._pendingWrites.set(path, { - lastChange: now, - cancelWait: () => { - this._pendingWrites.delete(path); - clearTimeout(timeoutHandler); - return event; - } - }); - timeoutHandler = setTimeout( - awaitWriteFinish, - this.options.awaitWriteFinish.pollInterval - ); - } -} - -_getGlobIgnored() { - return [...this._ignoredPaths.values()]; -} - -/** - * Determines whether user has asked to ignore this path. - * @param {Path} path filepath or dir - * @param {fs.Stats=} stats result of fs.stat - * @returns {Boolean} - */ -_isIgnored(path, stats) { - if (this.options.atomic && DOT_RE.test(path)) return true; - if (!this._userIgnored) { - const {cwd} = this.options; - const ign = this.options.ignored; - - const ignored = ign && ign.map(normalizeIgnored(cwd)); - const paths = arrify(ignored) - .filter((path) => typeof path === STRING_TYPE && !isGlob(path)) - .map((path) => path + SLASH_GLOBSTAR); - const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths); - this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS); - } - - return this._userIgnored([path, stats]); -} - -_isntIgnored(path, stat) { - return !this._isIgnored(path, stat); -} - -/** - * Provides a set of common helpers and properties relating to symlink and glob handling. - * @param {Path} path file, directory, or glob pattern being watched - * @param {Number=} depth at any depth > 0, this isn't a glob - * @returns {WatchHelper} object containing helpers for this path - */ -_getWatchHelpers(path, depth) { - const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path); - const follow = this.options.followSymlinks; - - return new WatchHelper(path, watchPath, follow, this); -} - -// Directory helpers -// ----------------- - -/** - * Provides directory tracking objects - * @param {String} directory path of the directory - * @returns {DirEntry} the directory's tracking object - */ -_getWatchedDir(directory) { - if (!this._boundRemove) this._boundRemove = this._remove.bind(this); - const dir = sysPath.resolve(directory); - if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove)); - return this._watched.get(dir); -} - -// File helpers -// ------------ - -/** - * Check for read permissions. - * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405 - * @param {fs.Stats} stats - object, result of fs_stat - * @returns {Boolean} indicates whether the file can be read -*/ -_hasReadPermissions(stats) { - if (this.options.ignorePermissionErrors) return true; - - // stats.mode may be bigint - const md = stats && Number.parseInt(stats.mode, 10); - const st = md & 0o777; - const it = Number.parseInt(st.toString(8)[0], 10); - return Boolean(4 & it); -} - -/** - * Handles emitting unlink events for - * files and directories, and via recursion, for - * files and directories within directories that are unlinked - * @param {String} directory within which the following item is located - * @param {String} item base path of item/directory - * @returns {void} -*/ -_remove(directory, item, isDirectory) { - // if what is being deleted is a directory, get that directory's paths - // for recursive deleting and cleaning of watched object - // if it is not a directory, nestedDirectoryChildren will be empty array - const path = sysPath.join(directory, item); - const fullPath = sysPath.resolve(path); - isDirectory = isDirectory != null - ? isDirectory - : this._watched.has(path) || this._watched.has(fullPath); - - // prevent duplicate handling in case of arriving here nearly simultaneously - // via multiple paths (such as _handleFile and _handleDir) - if (!this._throttle('remove', path, 100)) return; - - // if the only watched file is removed, watch for its return - if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) { - this.add(directory, item, true); - } - - // This will create a new entry in the watched object in either case - // so we got to do the directory check beforehand - const wp = this._getWatchedDir(path); - const nestedDirectoryChildren = wp.getChildren(); - - // Recursively remove children directories / files. - nestedDirectoryChildren.forEach(nested => this._remove(path, nested)); - - // Check if item was on the watched list and remove it - const parent = this._getWatchedDir(directory); - const wasTracked = parent.has(item); - parent.remove(item); - - // Fixes issue #1042 -> Relative paths were detected and added as symlinks - // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), - // but never removed from the map in case the path was deleted. - // This leads to an incorrect state if the path was recreated: - // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 - if (this._symlinkPaths.has(fullPath)) { - this._symlinkPaths.delete(fullPath); - } - - // If we wait for this file to be fully written, cancel the wait. - let relPath = path; - if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path); - if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { - const event = this._pendingWrites.get(relPath).cancelWait(); - if (event === EV_ADD) return; - } - - // The Entry will either be a directory that just got removed - // or a bogus entry to a file, in either case we have to remove it - this._watched.delete(path); - this._watched.delete(fullPath); - const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK; - if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path); - - // Avoid conflicts if we later create another file with the same name - if (!this.options.useFsEvents) { - this._closePath(path); - } -} - -/** - * Closes all watchers for a path - * @param {Path} path - */ -_closePath(path) { - this._closeFile(path); - const dir = sysPath.dirname(path); - this._getWatchedDir(dir).remove(sysPath.basename(path)); -} - -/** - * Closes only file-specific watchers - * @param {Path} path - */ -_closeFile(path) { - const closers = this._closers.get(path); - if (!closers) return; - closers.forEach(closer => closer()); - this._closers.delete(path); -} - -/** - * - * @param {Path} path - * @param {Function} closer - */ -_addPathCloser(path, closer) { - if (!closer) return; - let list = this._closers.get(path); - if (!list) { - list = []; - this._closers.set(path, list); - } - list.push(closer); -} - -_readdirp(root, opts) { - if (this.closed) return; - const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts}; - let stream = readdirp(root, options); - this._streams.add(stream); - stream.once(STR_CLOSE, () => { - stream = undefined; - }); - stream.once(STR_END, () => { - if (stream) { - this._streams.delete(stream); - stream = undefined; - } - }); - return stream; -} - -} - -// Export FSWatcher class -chokidar.FSWatcher = FSWatcher; - -/** - * Instantiates watcher with paths to be tracked. - * @param {String|Array} paths file/directory paths and/or globs - * @param {Object=} options chokidar opts - * @returns an instance of FSWatcher for chaining. - */ -const watch = (paths, options) => { - const watcher = new FSWatcher(options); - watcher.add(paths); - return watcher; -}; - -chokidar.watch = watch; - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * - * @typedef Statistics - * @property {number} fatal Fatal errors (`fatal: true`) - * @property {number} warn warning errors (`fatal: false`) - * @property {number} info informational messages (`fatal: null|undefined`) - * @property {number} nonfatal warning + info - * @property {number} total nonfatal + fatal - */ - -/** - * Get stats for a file, list of files, or list of messages. - * - * @param {Array.|VFile|VFileMessage} [value] - * @returns {Statistics} - */ -function statistics(value) { - var result = {true: 0, false: 0, null: 0}; - - if (value) { - if (Array.isArray(value)) { - list(value); - } else { - one(value); - } - } - - return { - fatal: result.true, - nonfatal: result.false + result.null, - warn: result.false, - info: result.null, - total: result.true + result.false + result.null - } - - /** - * @param {Array.} value - * @returns {void} - */ - function list(value) { - var index = -1; - - while (++index < value.length) { - one(value[index]); - } - } - - /** - * @param {VFile|VFileMessage} value - * @returns {void} - */ - function one(value) { - if ('messages' in value) return list(value.messages) - - result[ - value.fatal === undefined || value.fatal === null - ? null - : Boolean(value.fatal) - ]++; - } -} - -/** - * @typedef {(error?: Error|null|undefined, ...output: any[]) => void} Callback - * @typedef {(...input: any[]) => any} Middleware - * - * @typedef {(...input: any[]) => void} Run Call all middleware. - * @typedef {(fn: Middleware) => Pipeline} Use Add `fn` (middleware) to the list. - * @typedef {{run: Run, use: Use}} Pipeline - */ - -/** - * Create new middleware. - * - * @returns {Pipeline} - */ -function trough() { - /** @type {Middleware[]} */ - const fns = []; - /** @type {Pipeline} */ - const pipeline = {run, use}; - - return pipeline - - /** @type {Run} */ - function run(...values) { - let middlewareIndex = -1; - /** @type {Callback} */ - const callback = values.pop(); - - if (typeof callback !== 'function') { - throw new TypeError('Expected function as last argument, not ' + callback) - } - - next(null, ...values); - - /** - * Run the next `fn`, or we’re done. - * - * @param {Error|null|undefined} error - * @param {any[]} output - */ - function next(error, ...output) { - const fn = fns[++middlewareIndex]; - let index = -1; - - if (error) { - callback(error); - return - } - - // Copy non-nullish input into values. - while (++index < values.length) { - if (output[index] === null || output[index] === undefined) { - output[index] = values[index]; - } - } - - // Save the newly created `output` for the next call. - values = output; - - // Next or done. - if (fn) { - wrap(fn, next)(...output); - } else { - callback(null, ...output); - } - } - } - - /** @type {Use} */ - function use(middelware) { - if (typeof middelware !== 'function') { - throw new TypeError( - 'Expected `middelware` to be a function, not ' + middelware - ) - } - - fns.push(middelware); - return pipeline - } -} - -/** - * Wrap `middleware`. - * Can be sync or async; return a promise, receive a callback, or return new - * values and errors. - * - * @param {Middleware} middleware - * @param {Callback} callback - */ -function wrap(middleware, callback) { - /** @type {boolean} */ - let called; - - return wrapped - - /** - * Call `middleware`. - * @param {any[]} parameters - * @returns {void} - */ - function wrapped(...parameters) { - const fnExpectsCallback = middleware.length > parameters.length; - /** @type {any} */ - let result; - - if (fnExpectsCallback) { - parameters.push(done); - } - - try { - result = middleware(...parameters); - } catch (error) { - /** @type {Error} */ - const exception = error; - - // Well, this is quite the pickle. - // `middleware` received a callback and called it synchronously, but that - // threw an error. - // The only thing left to do is to throw the thing instead. - if (fnExpectsCallback && called) { - throw exception - } - - return done(exception) - } - - if (!fnExpectsCallback) { - if (result instanceof Promise) { - result.then(then, done); - } else if (result instanceof Error) { - done(result); - } else { - then(result); - } - } - } - - /** - * Call `callback`, only once. - * @type {Callback} - */ - function done(error, ...output) { - if (!called) { - called = true; - callback(error, ...output); - } - } - - /** - * Call `done` with one value. - * - * @param {any} [value] - */ - function then(value) { - done(null, value); - } -} - -/*! js-yaml 4.1.0 https://github.com/nodeca/js-yaml @license MIT */ -function isNothing(subject) { - return (typeof subject === 'undefined') || (subject === null); -} - - -function isObject$1(subject) { - return (typeof subject === 'object') && (subject !== null); -} - - -function toArray(sequence) { - if (Array.isArray(sequence)) return sequence; - else if (isNothing(sequence)) return []; - - return [ sequence ]; -} - - -function extend$2(target, source) { - var index, length, key, sourceKeys; - - if (source) { - sourceKeys = Object.keys(source); - - for (index = 0, length = sourceKeys.length; index < length; index += 1) { - key = sourceKeys[index]; - target[key] = source[key]; - } - } - - return target; -} - - -function repeat(string, count) { - var result = '', cycle; - - for (cycle = 0; cycle < count; cycle += 1) { - result += string; - } - - return result; -} - - -function isNegativeZero(number) { - return (number === 0) && (Number.NEGATIVE_INFINITY === 1 / number); -} - - -var isNothing_1 = isNothing; -var isObject_1 = isObject$1; -var toArray_1 = toArray; -var repeat_1 = repeat; -var isNegativeZero_1 = isNegativeZero; -var extend_1 = extend$2; - -var common$4 = { - isNothing: isNothing_1, - isObject: isObject_1, - toArray: toArray_1, - repeat: repeat_1, - isNegativeZero: isNegativeZero_1, - extend: extend_1 -}; - -// YAML error class. http://stackoverflow.com/questions/8458984 - - -function formatError(exception, compact) { - var where = '', message = exception.reason || '(unknown reason)'; - - if (!exception.mark) return message; - - if (exception.mark.name) { - where += 'in "' + exception.mark.name + '" '; - } - - where += '(' + (exception.mark.line + 1) + ':' + (exception.mark.column + 1) + ')'; - - if (!compact && exception.mark.snippet) { - where += '\n\n' + exception.mark.snippet; - } - - return message + ' ' + where; -} - - -function YAMLException$1(reason, mark) { - // Super constructor - Error.call(this); - - this.name = 'YAMLException'; - this.reason = reason; - this.mark = mark; - this.message = formatError(this, false); - - // Include stack trace in error object - if (Error.captureStackTrace) { - // Chrome and NodeJS - Error.captureStackTrace(this, this.constructor); - } else { - // FF, IE 10+ and Safari 6+. Fallback for others - this.stack = (new Error()).stack || ''; - } -} - - -// Inherit from Error -YAMLException$1.prototype = Object.create(Error.prototype); -YAMLException$1.prototype.constructor = YAMLException$1; - - -YAMLException$1.prototype.toString = function toString(compact) { - return this.name + ': ' + formatError(this, compact); -}; - - -var exception = YAMLException$1; - -// get snippet for a single line, respecting maxLength -function getLine(buffer, lineStart, lineEnd, position, maxLineLength) { - var head = ''; - var tail = ''; - var maxHalfLength = Math.floor(maxLineLength / 2) - 1; - - if (position - lineStart > maxHalfLength) { - head = ' ... '; - lineStart = position - maxHalfLength + head.length; - } - - if (lineEnd - position > maxHalfLength) { - tail = ' ...'; - lineEnd = position + maxHalfLength - tail.length; - } - - return { - str: head + buffer.slice(lineStart, lineEnd).replace(/\t/g, '→') + tail, - pos: position - lineStart + head.length // relative position - }; -} - - -function padStart(string, max) { - return common$4.repeat(' ', max - string.length) + string; -} - - -function makeSnippet(mark, options) { - options = Object.create(options || null); - - if (!mark.buffer) return null; - - if (!options.maxLength) options.maxLength = 79; - if (typeof options.indent !== 'number') options.indent = 1; - if (typeof options.linesBefore !== 'number') options.linesBefore = 3; - if (typeof options.linesAfter !== 'number') options.linesAfter = 2; - - var re = /\r?\n|\r|\0/g; - var lineStarts = [ 0 ]; - var lineEnds = []; - var match; - var foundLineNo = -1; - - while ((match = re.exec(mark.buffer))) { - lineEnds.push(match.index); - lineStarts.push(match.index + match[0].length); - - if (mark.position <= match.index && foundLineNo < 0) { - foundLineNo = lineStarts.length - 2; - } - } - - if (foundLineNo < 0) foundLineNo = lineStarts.length - 1; - - var result = '', i, line; - var lineNoLength = Math.min(mark.line + options.linesAfter, lineEnds.length).toString().length; - var maxLineLength = options.maxLength - (options.indent + lineNoLength + 3); - - for (i = 1; i <= options.linesBefore; i++) { - if (foundLineNo - i < 0) break; - line = getLine( - mark.buffer, - lineStarts[foundLineNo - i], - lineEnds[foundLineNo - i], - mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo - i]), - maxLineLength - ); - result = common$4.repeat(' ', options.indent) + padStart((mark.line - i + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n' + result; - } - - line = getLine(mark.buffer, lineStarts[foundLineNo], lineEnds[foundLineNo], mark.position, maxLineLength); - result += common$4.repeat(' ', options.indent) + padStart((mark.line + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n'; - result += common$4.repeat('-', options.indent + lineNoLength + 3 + line.pos) + '^' + '\n'; - - for (i = 1; i <= options.linesAfter; i++) { - if (foundLineNo + i >= lineEnds.length) break; - line = getLine( - mark.buffer, - lineStarts[foundLineNo + i], - lineEnds[foundLineNo + i], - mark.position - (lineStarts[foundLineNo] - lineStarts[foundLineNo + i]), - maxLineLength - ); - result += common$4.repeat(' ', options.indent) + padStart((mark.line + i + 1).toString(), lineNoLength) + - ' | ' + line.str + '\n'; - } - - return result.replace(/\n$/, ''); -} - - -var snippet = makeSnippet; - -var TYPE_CONSTRUCTOR_OPTIONS = [ - 'kind', - 'multi', - 'resolve', - 'construct', - 'instanceOf', - 'predicate', - 'represent', - 'representName', - 'defaultStyle', - 'styleAliases' -]; - -var YAML_NODE_KINDS = [ - 'scalar', - 'sequence', - 'mapping' -]; - -function compileStyleAliases(map) { - var result = {}; - - if (map !== null) { - Object.keys(map).forEach(function (style) { - map[style].forEach(function (alias) { - result[String(alias)] = style; - }); - }); - } - - return result; -} - -function Type$1(tag, options) { - options = options || {}; - - Object.keys(options).forEach(function (name) { - if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) { - throw new exception('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.'); - } - }); - - // TODO: Add tag format check. - this.options = options; // keep original options in case user wants to extend this type later - this.tag = tag; - this.kind = options['kind'] || null; - this.resolve = options['resolve'] || function () { return true; }; - this.construct = options['construct'] || function (data) { return data; }; - this.instanceOf = options['instanceOf'] || null; - this.predicate = options['predicate'] || null; - this.represent = options['represent'] || null; - this.representName = options['representName'] || null; - this.defaultStyle = options['defaultStyle'] || null; - this.multi = options['multi'] || false; - this.styleAliases = compileStyleAliases(options['styleAliases'] || null); - - if (YAML_NODE_KINDS.indexOf(this.kind) === -1) { - throw new exception('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.'); - } -} - -var type$1 = Type$1; - -/*eslint-disable max-len*/ - - - - - -function compileList(schema, name) { - var result = []; - - schema[name].forEach(function (currentType) { - var newIndex = result.length; - - result.forEach(function (previousType, previousIndex) { - if (previousType.tag === currentType.tag && - previousType.kind === currentType.kind && - previousType.multi === currentType.multi) { - - newIndex = previousIndex; - } - }); - - result[newIndex] = currentType; - }); - - return result; -} - - -function compileMap(/* lists... */) { - var result = { - scalar: {}, - sequence: {}, - mapping: {}, - fallback: {}, - multi: { - scalar: [], - sequence: [], - mapping: [], - fallback: [] - } - }, index, length; - - function collectType(type) { - if (type.multi) { - result.multi[type.kind].push(type); - result.multi['fallback'].push(type); - } else { - result[type.kind][type.tag] = result['fallback'][type.tag] = type; - } - } - - for (index = 0, length = arguments.length; index < length; index += 1) { - arguments[index].forEach(collectType); - } - return result; -} - - -function Schema$1(definition) { - return this.extend(definition); -} - - -Schema$1.prototype.extend = function extend(definition) { - var implicit = []; - var explicit = []; - - if (definition instanceof type$1) { - // Schema.extend(type) - explicit.push(definition); - - } else if (Array.isArray(definition)) { - // Schema.extend([ type1, type2, ... ]) - explicit = explicit.concat(definition); - - } else if (definition && (Array.isArray(definition.implicit) || Array.isArray(definition.explicit))) { - // Schema.extend({ explicit: [ type1, type2, ... ], implicit: [ type1, type2, ... ] }) - if (definition.implicit) implicit = implicit.concat(definition.implicit); - if (definition.explicit) explicit = explicit.concat(definition.explicit); - - } else { - throw new exception('Schema.extend argument should be a Type, [ Type ], ' + - 'or a schema definition ({ implicit: [...], explicit: [...] })'); - } - - implicit.forEach(function (type$1$1) { - if (!(type$1$1 instanceof type$1)) { - throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); - } - - if (type$1$1.loadKind && type$1$1.loadKind !== 'scalar') { - throw new exception('There is a non-scalar type in the implicit list of a schema. Implicit resolving of such types is not supported.'); - } - - if (type$1$1.multi) { - throw new exception('There is a multi type in the implicit list of a schema. Multi tags can only be listed as explicit.'); - } - }); - - explicit.forEach(function (type$1$1) { - if (!(type$1$1 instanceof type$1)) { - throw new exception('Specified list of YAML types (or a single Type object) contains a non-Type object.'); - } - }); - - var result = Object.create(Schema$1.prototype); - - result.implicit = (this.implicit || []).concat(implicit); - result.explicit = (this.explicit || []).concat(explicit); - - result.compiledImplicit = compileList(result, 'implicit'); - result.compiledExplicit = compileList(result, 'explicit'); - result.compiledTypeMap = compileMap(result.compiledImplicit, result.compiledExplicit); - - return result; -}; - - -var schema$1 = Schema$1; - -var str = new type$1('tag:yaml.org,2002:str', { - kind: 'scalar', - construct: function (data) { return data !== null ? data : ''; } -}); - -var seq = new type$1('tag:yaml.org,2002:seq', { - kind: 'sequence', - construct: function (data) { return data !== null ? data : []; } -}); - -var map$3 = new type$1('tag:yaml.org,2002:map', { - kind: 'mapping', - construct: function (data) { return data !== null ? data : {}; } -}); - -var failsafe = new schema$1({ - explicit: [ - str, - seq, - map$3 - ] -}); - -function resolveYamlNull(data) { - if (data === null) return true; - - var max = data.length; - - return (max === 1 && data === '~') || - (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); -} - -function constructYamlNull() { - return null; -} - -function isNull(object) { - return object === null; -} - -var _null = new type$1('tag:yaml.org,2002:null', { - kind: 'scalar', - resolve: resolveYamlNull, - construct: constructYamlNull, - predicate: isNull, - represent: { - canonical: function () { return '~'; }, - lowercase: function () { return 'null'; }, - uppercase: function () { return 'NULL'; }, - camelcase: function () { return 'Null'; }, - empty: function () { return ''; } - }, - defaultStyle: 'lowercase' -}); - -function resolveYamlBoolean(data) { - if (data === null) return false; - - var max = data.length; - - return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) || - (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE')); -} - -function constructYamlBoolean(data) { - return data === 'true' || - data === 'True' || - data === 'TRUE'; -} - -function isBoolean(object) { - return Object.prototype.toString.call(object) === '[object Boolean]'; -} - -var bool = new type$1('tag:yaml.org,2002:bool', { - kind: 'scalar', - resolve: resolveYamlBoolean, - construct: constructYamlBoolean, - predicate: isBoolean, - represent: { - lowercase: function (object) { return object ? 'true' : 'false'; }, - uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; }, - camelcase: function (object) { return object ? 'True' : 'False'; } - }, - defaultStyle: 'lowercase' -}); - -function isHexCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) || - ((0x41/* A */ <= c) && (c <= 0x46/* F */)) || - ((0x61/* a */ <= c) && (c <= 0x66/* f */)); -} - -function isOctCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */)); -} - -function isDecCode(c) { - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)); -} - -function resolveYamlInteger(data) { - if (data === null) return false; - - var max = data.length, - index = 0, - hasDigits = false, - ch; - - if (!max) return false; - - ch = data[index]; - - // sign - if (ch === '-' || ch === '+') { - ch = data[++index]; - } - - if (ch === '0') { - // 0 - if (index + 1 === max) return true; - ch = data[++index]; - - // base 2, base 8, base 16 - - if (ch === 'b') { - // base 2 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (ch !== '0' && ch !== '1') return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - - - if (ch === 'x') { - // base 16 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isHexCode(data.charCodeAt(index))) return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - - - if (ch === 'o') { - // base 8 - index++; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isOctCode(data.charCodeAt(index))) return false; - hasDigits = true; - } - return hasDigits && ch !== '_'; - } - } - - // base 10 (except 0) - - // value should not start with `_`; - if (ch === '_') return false; - - for (; index < max; index++) { - ch = data[index]; - if (ch === '_') continue; - if (!isDecCode(data.charCodeAt(index))) { - return false; - } - hasDigits = true; - } - - // Should have digits and should not end with `_` - if (!hasDigits || ch === '_') return false; - - return true; -} - -function constructYamlInteger(data) { - var value = data, sign = 1, ch; - - if (value.indexOf('_') !== -1) { - value = value.replace(/_/g, ''); - } - - ch = value[0]; - - if (ch === '-' || ch === '+') { - if (ch === '-') sign = -1; - value = value.slice(1); - ch = value[0]; - } - - if (value === '0') return 0; - - if (ch === '0') { - if (value[1] === 'b') return sign * parseInt(value.slice(2), 2); - if (value[1] === 'x') return sign * parseInt(value.slice(2), 16); - if (value[1] === 'o') return sign * parseInt(value.slice(2), 8); - } - - return sign * parseInt(value, 10); -} - -function isInteger(object) { - return (Object.prototype.toString.call(object)) === '[object Number]' && - (object % 1 === 0 && !common$4.isNegativeZero(object)); -} - -var int = new type$1('tag:yaml.org,2002:int', { - kind: 'scalar', - resolve: resolveYamlInteger, - construct: constructYamlInteger, - predicate: isInteger, - represent: { - binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); }, - octal: function (obj) { return obj >= 0 ? '0o' + obj.toString(8) : '-0o' + obj.toString(8).slice(1); }, - decimal: function (obj) { return obj.toString(10); }, - /* eslint-disable max-len */ - hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); } - }, - defaultStyle: 'decimal', - styleAliases: { - binary: [ 2, 'bin' ], - octal: [ 8, 'oct' ], - decimal: [ 10, 'dec' ], - hexadecimal: [ 16, 'hex' ] - } -}); - -var YAML_FLOAT_PATTERN = new RegExp( - // 2.5e4, 2.5 and integers - '^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' + - // .2e4, .2 - // special case, seems not from spec - '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' + - // .inf - '|[-+]?\\.(?:inf|Inf|INF)' + - // .nan - '|\\.(?:nan|NaN|NAN))$'); - -function resolveYamlFloat(data) { - if (data === null) return false; - - if (!YAML_FLOAT_PATTERN.test(data) || - // Quick hack to not allow integers end with `_` - // Probably should update regexp & check speed - data[data.length - 1] === '_') { - return false; - } - - return true; -} - -function constructYamlFloat(data) { - var value, sign; - - value = data.replace(/_/g, '').toLowerCase(); - sign = value[0] === '-' ? -1 : 1; - - if ('+-'.indexOf(value[0]) >= 0) { - value = value.slice(1); - } - - if (value === '.inf') { - return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY; - - } else if (value === '.nan') { - return NaN; - } - return sign * parseFloat(value, 10); -} - - -var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/; - -function representYamlFloat(object, style) { - var res; - - if (isNaN(object)) { - switch (style) { - case 'lowercase': return '.nan'; - case 'uppercase': return '.NAN'; - case 'camelcase': return '.NaN'; - } - } else if (Number.POSITIVE_INFINITY === object) { - switch (style) { - case 'lowercase': return '.inf'; - case 'uppercase': return '.INF'; - case 'camelcase': return '.Inf'; - } - } else if (Number.NEGATIVE_INFINITY === object) { - switch (style) { - case 'lowercase': return '-.inf'; - case 'uppercase': return '-.INF'; - case 'camelcase': return '-.Inf'; - } - } else if (common$4.isNegativeZero(object)) { - return '-0.0'; - } - - res = object.toString(10); - - // JS stringifier can build scientific format without dots: 5e-100, - // while YAML requres dot: 5.e-100. Fix it with simple hack - - return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res; -} - -function isFloat(object) { - return (Object.prototype.toString.call(object) === '[object Number]') && - (object % 1 !== 0 || common$4.isNegativeZero(object)); -} - -var float = new type$1('tag:yaml.org,2002:float', { - kind: 'scalar', - resolve: resolveYamlFloat, - construct: constructYamlFloat, - predicate: isFloat, - represent: representYamlFloat, - defaultStyle: 'lowercase' -}); - -var json = failsafe.extend({ - implicit: [ - _null, - bool, - int, - float - ] -}); - -var core = json; - -var YAML_DATE_REGEXP = new RegExp( - '^([0-9][0-9][0-9][0-9])' + // [1] year - '-([0-9][0-9])' + // [2] month - '-([0-9][0-9])$'); // [3] day - -var YAML_TIMESTAMP_REGEXP = new RegExp( - '^([0-9][0-9][0-9][0-9])' + // [1] year - '-([0-9][0-9]?)' + // [2] month - '-([0-9][0-9]?)' + // [3] day - '(?:[Tt]|[ \\t]+)' + // ... - '([0-9][0-9]?)' + // [4] hour - ':([0-9][0-9])' + // [5] minute - ':([0-9][0-9])' + // [6] second - '(?:\\.([0-9]*))?' + // [7] fraction - '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour - '(?::([0-9][0-9]))?))?$'); // [11] tz_minute - -function resolveYamlTimestamp(data) { - if (data === null) return false; - if (YAML_DATE_REGEXP.exec(data) !== null) return true; - if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true; - return false; -} - -function constructYamlTimestamp(data) { - var match, year, month, day, hour, minute, second, fraction = 0, - delta = null, tz_hour, tz_minute, date; - - match = YAML_DATE_REGEXP.exec(data); - if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data); - - if (match === null) throw new Error('Date resolve error'); - - // match: [1] year [2] month [3] day - - year = +(match[1]); - month = +(match[2]) - 1; // JS month starts with 0 - day = +(match[3]); - - if (!match[4]) { // no hour - return new Date(Date.UTC(year, month, day)); - } - - // match: [4] hour [5] minute [6] second [7] fraction - - hour = +(match[4]); - minute = +(match[5]); - second = +(match[6]); - - if (match[7]) { - fraction = match[7].slice(0, 3); - while (fraction.length < 3) { // milli-seconds - fraction += '0'; - } - fraction = +fraction; - } - - // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute - - if (match[9]) { - tz_hour = +(match[10]); - tz_minute = +(match[11] || 0); - delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds - if (match[9] === '-') delta = -delta; - } - - date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction)); - - if (delta) date.setTime(date.getTime() - delta); - - return date; -} - -function representYamlTimestamp(object /*, style*/) { - return object.toISOString(); -} - -var timestamp = new type$1('tag:yaml.org,2002:timestamp', { - kind: 'scalar', - resolve: resolveYamlTimestamp, - construct: constructYamlTimestamp, - instanceOf: Date, - represent: representYamlTimestamp -}); - -function resolveYamlMerge(data) { - return data === '<<' || data === null; -} - -var merge$1 = new type$1('tag:yaml.org,2002:merge', { - kind: 'scalar', - resolve: resolveYamlMerge -}); - -/*eslint-disable no-bitwise*/ - - - - - -// [ 64, 65, 66 ] -> [ padding, CR, LF ] -var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r'; - - -function resolveYamlBinary(data) { - if (data === null) return false; - - var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP; - - // Convert one by one. - for (idx = 0; idx < max; idx++) { - code = map.indexOf(data.charAt(idx)); - - // Skip CR/LF - if (code > 64) continue; - - // Fail on illegal characters - if (code < 0) return false; - - bitlen += 6; - } - - // If there are any bits left, source was corrupted - return (bitlen % 8) === 0; -} - -function constructYamlBinary(data) { - var idx, tailbits, - input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan - max = input.length, - map = BASE64_MAP, - bits = 0, - result = []; - - // Collect by 6*4 bits (3 bytes) - - for (idx = 0; idx < max; idx++) { - if ((idx % 4 === 0) && idx) { - result.push((bits >> 16) & 0xFF); - result.push((bits >> 8) & 0xFF); - result.push(bits & 0xFF); - } - - bits = (bits << 6) | map.indexOf(input.charAt(idx)); - } - - // Dump tail - - tailbits = (max % 4) * 6; - - if (tailbits === 0) { - result.push((bits >> 16) & 0xFF); - result.push((bits >> 8) & 0xFF); - result.push(bits & 0xFF); - } else if (tailbits === 18) { - result.push((bits >> 10) & 0xFF); - result.push((bits >> 2) & 0xFF); - } else if (tailbits === 12) { - result.push((bits >> 4) & 0xFF); - } - - return new Uint8Array(result); -} - -function representYamlBinary(object /*, style*/) { - var result = '', bits = 0, idx, tail, - max = object.length, - map = BASE64_MAP; - - // Convert every three bytes to 4 ASCII characters. - - for (idx = 0; idx < max; idx++) { - if ((idx % 3 === 0) && idx) { - result += map[(bits >> 18) & 0x3F]; - result += map[(bits >> 12) & 0x3F]; - result += map[(bits >> 6) & 0x3F]; - result += map[bits & 0x3F]; - } - - bits = (bits << 8) + object[idx]; - } - - // Dump tail - - tail = max % 3; - - if (tail === 0) { - result += map[(bits >> 18) & 0x3F]; - result += map[(bits >> 12) & 0x3F]; - result += map[(bits >> 6) & 0x3F]; - result += map[bits & 0x3F]; - } else if (tail === 2) { - result += map[(bits >> 10) & 0x3F]; - result += map[(bits >> 4) & 0x3F]; - result += map[(bits << 2) & 0x3F]; - result += map[64]; - } else if (tail === 1) { - result += map[(bits >> 2) & 0x3F]; - result += map[(bits << 4) & 0x3F]; - result += map[64]; - result += map[64]; - } - - return result; -} - -function isBinary(obj) { - return Object.prototype.toString.call(obj) === '[object Uint8Array]'; -} - -var binary = new type$1('tag:yaml.org,2002:binary', { - kind: 'scalar', - resolve: resolveYamlBinary, - construct: constructYamlBinary, - predicate: isBinary, - represent: representYamlBinary -}); - -var _hasOwnProperty$3 = Object.prototype.hasOwnProperty; -var _toString$2 = Object.prototype.toString; - -function resolveYamlOmap(data) { - if (data === null) return true; - - var objectKeys = [], index, length, pair, pairKey, pairHasKey, - object = data; - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - pairHasKey = false; - - if (_toString$2.call(pair) !== '[object Object]') return false; - - for (pairKey in pair) { - if (_hasOwnProperty$3.call(pair, pairKey)) { - if (!pairHasKey) pairHasKey = true; - else return false; - } - } - - if (!pairHasKey) return false; - - if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey); - else return false; - } - - return true; -} - -function constructYamlOmap(data) { - return data !== null ? data : []; -} - -var omap = new type$1('tag:yaml.org,2002:omap', { - kind: 'sequence', - resolve: resolveYamlOmap, - construct: constructYamlOmap -}); - -var _toString$1 = Object.prototype.toString; - -function resolveYamlPairs(data) { - if (data === null) return true; - - var index, length, pair, keys, result, - object = data; - - result = new Array(object.length); - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - - if (_toString$1.call(pair) !== '[object Object]') return false; - - keys = Object.keys(pair); - - if (keys.length !== 1) return false; - - result[index] = [ keys[0], pair[keys[0]] ]; - } - - return true; -} - -function constructYamlPairs(data) { - if (data === null) return []; - - var index, length, pair, keys, result, - object = data; - - result = new Array(object.length); - - for (index = 0, length = object.length; index < length; index += 1) { - pair = object[index]; - - keys = Object.keys(pair); - - result[index] = [ keys[0], pair[keys[0]] ]; - } - - return result; -} - -var pairs = new type$1('tag:yaml.org,2002:pairs', { - kind: 'sequence', - resolve: resolveYamlPairs, - construct: constructYamlPairs -}); - -var _hasOwnProperty$2 = Object.prototype.hasOwnProperty; - -function resolveYamlSet(data) { - if (data === null) return true; - - var key, object = data; - - for (key in object) { - if (_hasOwnProperty$2.call(object, key)) { - if (object[key] !== null) return false; - } - } - - return true; -} - -function constructYamlSet(data) { - return data !== null ? data : {}; -} - -var set = new type$1('tag:yaml.org,2002:set', { - kind: 'mapping', - resolve: resolveYamlSet, - construct: constructYamlSet -}); - -var _default$1 = core.extend({ - implicit: [ - timestamp, - merge$1 - ], - explicit: [ - binary, - omap, - pairs, - set - ] -}); - -/*eslint-disable max-len,no-use-before-define*/ - - - - - - - -var _hasOwnProperty$1 = Object.prototype.hasOwnProperty; - - -var CONTEXT_FLOW_IN = 1; -var CONTEXT_FLOW_OUT = 2; -var CONTEXT_BLOCK_IN = 3; -var CONTEXT_BLOCK_OUT = 4; - - -var CHOMPING_CLIP = 1; -var CHOMPING_STRIP = 2; -var CHOMPING_KEEP = 3; - - -var PATTERN_NON_PRINTABLE = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x84\x86-\x9F\uFFFE\uFFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/; -var PATTERN_NON_ASCII_LINE_BREAKS = /[\x85\u2028\u2029]/; -var PATTERN_FLOW_INDICATORS = /[,\[\]\{\}]/; -var PATTERN_TAG_HANDLE = /^(?:!|!!|![a-z\-]+!)$/i; -var PATTERN_TAG_URI = /^(?:!|[^,\[\]\{\}])(?:%[0-9a-f]{2}|[0-9a-z\-#;\/\?:@&=\+\$,_\.!~\*'\(\)\[\]])*$/i; - - -function _class(obj) { return Object.prototype.toString.call(obj); } - -function is_EOL(c) { - return (c === 0x0A/* LF */) || (c === 0x0D/* CR */); -} - -function is_WHITE_SPACE(c) { - return (c === 0x09/* Tab */) || (c === 0x20/* Space */); -} - -function is_WS_OR_EOL(c) { - return (c === 0x09/* Tab */) || - (c === 0x20/* Space */) || - (c === 0x0A/* LF */) || - (c === 0x0D/* CR */); -} - -function is_FLOW_INDICATOR(c) { - return c === 0x2C/* , */ || - c === 0x5B/* [ */ || - c === 0x5D/* ] */ || - c === 0x7B/* { */ || - c === 0x7D/* } */; -} - -function fromHexCode(c) { - var lc; - - if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { - return c - 0x30; - } - - /*eslint-disable no-bitwise*/ - lc = c | 0x20; - - if ((0x61/* a */ <= lc) && (lc <= 0x66/* f */)) { - return lc - 0x61 + 10; - } - - return -1; -} - -function escapedHexLen(c) { - if (c === 0x78/* x */) { return 2; } - if (c === 0x75/* u */) { return 4; } - if (c === 0x55/* U */) { return 8; } - return 0; -} - -function fromDecimalCode(c) { - if ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) { - return c - 0x30; - } - - return -1; -} - -function simpleEscapeSequence(c) { - /* eslint-disable indent */ - return (c === 0x30/* 0 */) ? '\x00' : - (c === 0x61/* a */) ? '\x07' : - (c === 0x62/* b */) ? '\x08' : - (c === 0x74/* t */) ? '\x09' : - (c === 0x09/* Tab */) ? '\x09' : - (c === 0x6E/* n */) ? '\x0A' : - (c === 0x76/* v */) ? '\x0B' : - (c === 0x66/* f */) ? '\x0C' : - (c === 0x72/* r */) ? '\x0D' : - (c === 0x65/* e */) ? '\x1B' : - (c === 0x20/* Space */) ? ' ' : - (c === 0x22/* " */) ? '\x22' : - (c === 0x2F/* / */) ? '/' : - (c === 0x5C/* \ */) ? '\x5C' : - (c === 0x4E/* N */) ? '\x85' : - (c === 0x5F/* _ */) ? '\xA0' : - (c === 0x4C/* L */) ? '\u2028' : - (c === 0x50/* P */) ? '\u2029' : ''; -} - -function charFromCodepoint(c) { - if (c <= 0xFFFF) { - return String.fromCharCode(c); - } - // Encode UTF-16 surrogate pair - // https://en.wikipedia.org/wiki/UTF-16#Code_points_U.2B010000_to_U.2B10FFFF - return String.fromCharCode( - ((c - 0x010000) >> 10) + 0xD800, - ((c - 0x010000) & 0x03FF) + 0xDC00 - ); -} - -var simpleEscapeCheck = new Array(256); // integer, for fast access -var simpleEscapeMap = new Array(256); -for (var i = 0; i < 256; i++) { - simpleEscapeCheck[i] = simpleEscapeSequence(i) ? 1 : 0; - simpleEscapeMap[i] = simpleEscapeSequence(i); -} - - -function State$1(input, options) { - this.input = input; - - this.filename = options['filename'] || null; - this.schema = options['schema'] || _default$1; - this.onWarning = options['onWarning'] || null; - // (Hidden) Remove? makes the loader to expect YAML 1.1 documents - // if such documents have no explicit %YAML directive - this.legacy = options['legacy'] || false; - - this.json = options['json'] || false; - this.listener = options['listener'] || null; - - this.implicitTypes = this.schema.compiledImplicit; - this.typeMap = this.schema.compiledTypeMap; - - this.length = input.length; - this.position = 0; - this.line = 0; - this.lineStart = 0; - this.lineIndent = 0; - - // position of first leading tab in the current line, - // used to make sure there are no tabs in the indentation - this.firstTabInLine = -1; - - this.documents = []; - - /* - this.version; - this.checkLineBreaks; - this.tagMap; - this.anchorMap; - this.tag; - this.anchor; - this.kind; - this.result;*/ - -} - - -function generateError(state, message) { - var mark = { - name: state.filename, - buffer: state.input.slice(0, -1), // omit trailing \0 - position: state.position, - line: state.line, - column: state.position - state.lineStart - }; - - mark.snippet = snippet(mark); - - return new exception(message, mark); -} - -function throwError$1(state, message) { - throw generateError(state, message); -} - -function throwWarning(state, message) { - if (state.onWarning) { - state.onWarning.call(null, generateError(state, message)); - } -} - - -var directiveHandlers = { - - YAML: function handleYamlDirective(state, name, args) { - - var match, major, minor; - - if (state.version !== null) { - throwError$1(state, 'duplication of %YAML directive'); - } - - if (args.length !== 1) { - throwError$1(state, 'YAML directive accepts exactly one argument'); - } - - match = /^([0-9]+)\.([0-9]+)$/.exec(args[0]); - - if (match === null) { - throwError$1(state, 'ill-formed argument of the YAML directive'); - } - - major = parseInt(match[1], 10); - minor = parseInt(match[2], 10); - - if (major !== 1) { - throwError$1(state, 'unacceptable YAML version of the document'); - } - - state.version = args[0]; - state.checkLineBreaks = (minor < 2); - - if (minor !== 1 && minor !== 2) { - throwWarning(state, 'unsupported YAML version of the document'); - } - }, - - TAG: function handleTagDirective(state, name, args) { - - var handle, prefix; - - if (args.length !== 2) { - throwError$1(state, 'TAG directive accepts exactly two arguments'); - } - - handle = args[0]; - prefix = args[1]; - - if (!PATTERN_TAG_HANDLE.test(handle)) { - throwError$1(state, 'ill-formed tag handle (first argument) of the TAG directive'); - } - - if (_hasOwnProperty$1.call(state.tagMap, handle)) { - throwError$1(state, 'there is a previously declared suffix for "' + handle + '" tag handle'); - } - - if (!PATTERN_TAG_URI.test(prefix)) { - throwError$1(state, 'ill-formed tag prefix (second argument) of the TAG directive'); - } - - try { - prefix = decodeURIComponent(prefix); - } catch (err) { - throwError$1(state, 'tag prefix is malformed: ' + prefix); - } - - state.tagMap[handle] = prefix; - } -}; - - -function captureSegment(state, start, end, checkJson) { - var _position, _length, _character, _result; - - if (start < end) { - _result = state.input.slice(start, end); - - if (checkJson) { - for (_position = 0, _length = _result.length; _position < _length; _position += 1) { - _character = _result.charCodeAt(_position); - if (!(_character === 0x09 || - (0x20 <= _character && _character <= 0x10FFFF))) { - throwError$1(state, 'expected valid JSON character'); - } - } - } else if (PATTERN_NON_PRINTABLE.test(_result)) { - throwError$1(state, 'the stream contains non-printable characters'); - } - - state.result += _result; - } -} - -function mergeMappings(state, destination, source, overridableKeys) { - var sourceKeys, key, index, quantity; - - if (!common$4.isObject(source)) { - throwError$1(state, 'cannot merge mappings; the provided source object is unacceptable'); - } - - sourceKeys = Object.keys(source); - - for (index = 0, quantity = sourceKeys.length; index < quantity; index += 1) { - key = sourceKeys[index]; - - if (!_hasOwnProperty$1.call(destination, key)) { - destination[key] = source[key]; - overridableKeys[key] = true; - } - } -} - -function storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, - startLine, startLineStart, startPos) { - - var index, quantity; - - // The output is a plain object here, so keys can only be strings. - // We need to convert keyNode to a string, but doing so can hang the process - // (deeply nested arrays that explode exponentially using aliases). - if (Array.isArray(keyNode)) { - keyNode = Array.prototype.slice.call(keyNode); - - for (index = 0, quantity = keyNode.length; index < quantity; index += 1) { - if (Array.isArray(keyNode[index])) { - throwError$1(state, 'nested arrays are not supported inside keys'); - } - - if (typeof keyNode === 'object' && _class(keyNode[index]) === '[object Object]') { - keyNode[index] = '[object Object]'; - } - } - } - - // Avoid code execution in load() via toString property - // (still use its own toString for arrays, timestamps, - // and whatever user schema extensions happen to have @@toStringTag) - if (typeof keyNode === 'object' && _class(keyNode) === '[object Object]') { - keyNode = '[object Object]'; - } - - - keyNode = String(keyNode); - - if (_result === null) { - _result = {}; - } - - if (keyTag === 'tag:yaml.org,2002:merge') { - if (Array.isArray(valueNode)) { - for (index = 0, quantity = valueNode.length; index < quantity; index += 1) { - mergeMappings(state, _result, valueNode[index], overridableKeys); - } - } else { - mergeMappings(state, _result, valueNode, overridableKeys); - } - } else { - if (!state.json && - !_hasOwnProperty$1.call(overridableKeys, keyNode) && - _hasOwnProperty$1.call(_result, keyNode)) { - state.line = startLine || state.line; - state.lineStart = startLineStart || state.lineStart; - state.position = startPos || state.position; - throwError$1(state, 'duplicated mapping key'); - } - - // used for this specific key only because Object.defineProperty is slow - if (keyNode === '__proto__') { - Object.defineProperty(_result, keyNode, { - configurable: true, - enumerable: true, - writable: true, - value: valueNode - }); - } else { - _result[keyNode] = valueNode; - } - delete overridableKeys[keyNode]; - } - - return _result; -} - -function readLineBreak(state) { - var ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x0A/* LF */) { - state.position++; - } else if (ch === 0x0D/* CR */) { - state.position++; - if (state.input.charCodeAt(state.position) === 0x0A/* LF */) { - state.position++; - } - } else { - throwError$1(state, 'a line break is expected'); - } - - state.line += 1; - state.lineStart = state.position; - state.firstTabInLine = -1; -} - -function skipSeparationSpace(state, allowComments, checkIndent) { - var lineBreaks = 0, - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - while (is_WHITE_SPACE(ch)) { - if (ch === 0x09/* Tab */ && state.firstTabInLine === -1) { - state.firstTabInLine = state.position; - } - ch = state.input.charCodeAt(++state.position); - } - - if (allowComments && ch === 0x23/* # */) { - do { - ch = state.input.charCodeAt(++state.position); - } while (ch !== 0x0A/* LF */ && ch !== 0x0D/* CR */ && ch !== 0); - } - - if (is_EOL(ch)) { - readLineBreak(state); - - ch = state.input.charCodeAt(state.position); - lineBreaks++; - state.lineIndent = 0; - - while (ch === 0x20/* Space */) { - state.lineIndent++; - ch = state.input.charCodeAt(++state.position); - } - } else { - break; - } - } - - if (checkIndent !== -1 && lineBreaks !== 0 && state.lineIndent < checkIndent) { - throwWarning(state, 'deficient indentation'); - } - - return lineBreaks; -} - -function testDocumentSeparator(state) { - var _position = state.position, - ch; - - ch = state.input.charCodeAt(_position); - - // Condition state.position === state.lineStart is tested - // in parent on each call, for efficiency. No needs to test here again. - if ((ch === 0x2D/* - */ || ch === 0x2E/* . */) && - ch === state.input.charCodeAt(_position + 1) && - ch === state.input.charCodeAt(_position + 2)) { - - _position += 3; - - ch = state.input.charCodeAt(_position); - - if (ch === 0 || is_WS_OR_EOL(ch)) { - return true; - } - } - - return false; -} - -function writeFoldedLines(state, count) { - if (count === 1) { - state.result += ' '; - } else if (count > 1) { - state.result += common$4.repeat('\n', count - 1); - } -} - - -function readPlainScalar(state, nodeIndent, withinFlowCollection) { - var preceding, - following, - captureStart, - captureEnd, - hasPendingContent, - _line, - _lineStart, - _lineIndent, - _kind = state.kind, - _result = state.result, - ch; - - ch = state.input.charCodeAt(state.position); - - if (is_WS_OR_EOL(ch) || - is_FLOW_INDICATOR(ch) || - ch === 0x23/* # */ || - ch === 0x26/* & */ || - ch === 0x2A/* * */ || - ch === 0x21/* ! */ || - ch === 0x7C/* | */ || - ch === 0x3E/* > */ || - ch === 0x27/* ' */ || - ch === 0x22/* " */ || - ch === 0x25/* % */ || - ch === 0x40/* @ */ || - ch === 0x60/* ` */) { - return false; - } - - if (ch === 0x3F/* ? */ || ch === 0x2D/* - */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following) || - withinFlowCollection && is_FLOW_INDICATOR(following)) { - return false; - } - } - - state.kind = 'scalar'; - state.result = ''; - captureStart = captureEnd = state.position; - hasPendingContent = false; - - while (ch !== 0) { - if (ch === 0x3A/* : */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following) || - withinFlowCollection && is_FLOW_INDICATOR(following)) { - break; - } - - } else if (ch === 0x23/* # */) { - preceding = state.input.charCodeAt(state.position - 1); - - if (is_WS_OR_EOL(preceding)) { - break; - } - - } else if ((state.position === state.lineStart && testDocumentSeparator(state)) || - withinFlowCollection && is_FLOW_INDICATOR(ch)) { - break; - - } else if (is_EOL(ch)) { - _line = state.line; - _lineStart = state.lineStart; - _lineIndent = state.lineIndent; - skipSeparationSpace(state, false, -1); - - if (state.lineIndent >= nodeIndent) { - hasPendingContent = true; - ch = state.input.charCodeAt(state.position); - continue; - } else { - state.position = captureEnd; - state.line = _line; - state.lineStart = _lineStart; - state.lineIndent = _lineIndent; - break; - } - } - - if (hasPendingContent) { - captureSegment(state, captureStart, captureEnd, false); - writeFoldedLines(state, state.line - _line); - captureStart = captureEnd = state.position; - hasPendingContent = false; - } - - if (!is_WHITE_SPACE(ch)) { - captureEnd = state.position + 1; - } - - ch = state.input.charCodeAt(++state.position); - } - - captureSegment(state, captureStart, captureEnd, false); - - if (state.result) { - return true; - } - - state.kind = _kind; - state.result = _result; - return false; -} - -function readSingleQuotedScalar(state, nodeIndent) { - var ch, - captureStart, captureEnd; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x27/* ' */) { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - state.position++; - captureStart = captureEnd = state.position; - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - if (ch === 0x27/* ' */) { - captureSegment(state, captureStart, state.position, true); - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x27/* ' */) { - captureStart = state.position; - state.position++; - captureEnd = state.position; - } else { - return true; - } - - } else if (is_EOL(ch)) { - captureSegment(state, captureStart, captureEnd, true); - writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); - captureStart = captureEnd = state.position; - - } else if (state.position === state.lineStart && testDocumentSeparator(state)) { - throwError$1(state, 'unexpected end of the document within a single quoted scalar'); - - } else { - state.position++; - captureEnd = state.position; - } - } - - throwError$1(state, 'unexpected end of the stream within a single quoted scalar'); -} - -function readDoubleQuotedScalar(state, nodeIndent) { - var captureStart, - captureEnd, - hexLength, - hexResult, - tmp, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x22/* " */) { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - state.position++; - captureStart = captureEnd = state.position; - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - if (ch === 0x22/* " */) { - captureSegment(state, captureStart, state.position, true); - state.position++; - return true; - - } else if (ch === 0x5C/* \ */) { - captureSegment(state, captureStart, state.position, true); - ch = state.input.charCodeAt(++state.position); - - if (is_EOL(ch)) { - skipSeparationSpace(state, false, nodeIndent); - - // TODO: rework to inline fn with no type cast? - } else if (ch < 256 && simpleEscapeCheck[ch]) { - state.result += simpleEscapeMap[ch]; - state.position++; - - } else if ((tmp = escapedHexLen(ch)) > 0) { - hexLength = tmp; - hexResult = 0; - - for (; hexLength > 0; hexLength--) { - ch = state.input.charCodeAt(++state.position); - - if ((tmp = fromHexCode(ch)) >= 0) { - hexResult = (hexResult << 4) + tmp; - - } else { - throwError$1(state, 'expected hexadecimal character'); - } - } - - state.result += charFromCodepoint(hexResult); - - state.position++; - - } else { - throwError$1(state, 'unknown escape sequence'); - } - - captureStart = captureEnd = state.position; - - } else if (is_EOL(ch)) { - captureSegment(state, captureStart, captureEnd, true); - writeFoldedLines(state, skipSeparationSpace(state, false, nodeIndent)); - captureStart = captureEnd = state.position; - - } else if (state.position === state.lineStart && testDocumentSeparator(state)) { - throwError$1(state, 'unexpected end of the document within a double quoted scalar'); - - } else { - state.position++; - captureEnd = state.position; - } - } - - throwError$1(state, 'unexpected end of the stream within a double quoted scalar'); -} - -function readFlowCollection(state, nodeIndent) { - var readNext = true, - _line, - _lineStart, - _pos, - _tag = state.tag, - _result, - _anchor = state.anchor, - following, - terminator, - isPair, - isExplicitPair, - isMapping, - overridableKeys = Object.create(null), - keyNode, - keyTag, - valueNode, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x5B/* [ */) { - terminator = 0x5D;/* ] */ - isMapping = false; - _result = []; - } else if (ch === 0x7B/* { */) { - terminator = 0x7D;/* } */ - isMapping = true; - _result = {}; - } else { - return false; - } - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(++state.position); - - while (ch !== 0) { - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if (ch === terminator) { - state.position++; - state.tag = _tag; - state.anchor = _anchor; - state.kind = isMapping ? 'mapping' : 'sequence'; - state.result = _result; - return true; - } else if (!readNext) { - throwError$1(state, 'missed comma between flow collection entries'); - } else if (ch === 0x2C/* , */) { - // "flow collection entries can never be completely empty", as per YAML 1.2, section 7.4 - throwError$1(state, "expected the node content, but found ','"); - } - - keyTag = keyNode = valueNode = null; - isPair = isExplicitPair = false; - - if (ch === 0x3F/* ? */) { - following = state.input.charCodeAt(state.position + 1); - - if (is_WS_OR_EOL(following)) { - isPair = isExplicitPair = true; - state.position++; - skipSeparationSpace(state, true, nodeIndent); - } - } - - _line = state.line; // Save the current line. - _lineStart = state.lineStart; - _pos = state.position; - composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); - keyTag = state.tag; - keyNode = state.result; - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if ((isExplicitPair || state.line === _line) && ch === 0x3A/* : */) { - isPair = true; - ch = state.input.charCodeAt(++state.position); - skipSeparationSpace(state, true, nodeIndent); - composeNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true); - valueNode = state.result; - } - - if (isMapping) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos); - } else if (isPair) { - _result.push(storeMappingPair(state, null, overridableKeys, keyTag, keyNode, valueNode, _line, _lineStart, _pos)); - } else { - _result.push(keyNode); - } - - skipSeparationSpace(state, true, nodeIndent); - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x2C/* , */) { - readNext = true; - ch = state.input.charCodeAt(++state.position); - } else { - readNext = false; - } - } - - throwError$1(state, 'unexpected end of the stream within a flow collection'); -} - -function readBlockScalar(state, nodeIndent) { - var captureStart, - folding, - chomping = CHOMPING_CLIP, - didReadContent = false, - detectedIndent = false, - textIndent = nodeIndent, - emptyLines = 0, - atMoreIndented = false, - tmp, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch === 0x7C/* | */) { - folding = false; - } else if (ch === 0x3E/* > */) { - folding = true; - } else { - return false; - } - - state.kind = 'scalar'; - state.result = ''; - - while (ch !== 0) { - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x2B/* + */ || ch === 0x2D/* - */) { - if (CHOMPING_CLIP === chomping) { - chomping = (ch === 0x2B/* + */) ? CHOMPING_KEEP : CHOMPING_STRIP; - } else { - throwError$1(state, 'repeat of a chomping mode identifier'); - } - - } else if ((tmp = fromDecimalCode(ch)) >= 0) { - if (tmp === 0) { - throwError$1(state, 'bad explicit indentation width of a block scalar; it cannot be less than one'); - } else if (!detectedIndent) { - textIndent = nodeIndent + tmp - 1; - detectedIndent = true; - } else { - throwError$1(state, 'repeat of an indentation width identifier'); - } - - } else { - break; - } - } - - if (is_WHITE_SPACE(ch)) { - do { ch = state.input.charCodeAt(++state.position); } - while (is_WHITE_SPACE(ch)); - - if (ch === 0x23/* # */) { - do { ch = state.input.charCodeAt(++state.position); } - while (!is_EOL(ch) && (ch !== 0)); - } - } - - while (ch !== 0) { - readLineBreak(state); - state.lineIndent = 0; - - ch = state.input.charCodeAt(state.position); - - while ((!detectedIndent || state.lineIndent < textIndent) && - (ch === 0x20/* Space */)) { - state.lineIndent++; - ch = state.input.charCodeAt(++state.position); - } - - if (!detectedIndent && state.lineIndent > textIndent) { - textIndent = state.lineIndent; - } - - if (is_EOL(ch)) { - emptyLines++; - continue; - } - - // End of the scalar. - if (state.lineIndent < textIndent) { - - // Perform the chomping. - if (chomping === CHOMPING_KEEP) { - state.result += common$4.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - } else if (chomping === CHOMPING_CLIP) { - if (didReadContent) { // i.e. only if the scalar is not empty. - state.result += '\n'; - } - } - - // Break this `while` cycle and go to the funciton's epilogue. - break; - } - - // Folded style: use fancy rules to handle line breaks. - if (folding) { - - // Lines starting with white space characters (more-indented lines) are not folded. - if (is_WHITE_SPACE(ch)) { - atMoreIndented = true; - // except for the first content line (cf. Example 8.1) - state.result += common$4.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - - // End of more-indented block. - } else if (atMoreIndented) { - atMoreIndented = false; - state.result += common$4.repeat('\n', emptyLines + 1); - - // Just one line break - perceive as the same line. - } else if (emptyLines === 0) { - if (didReadContent) { // i.e. only if we have already read some scalar content. - state.result += ' '; - } - - // Several line breaks - perceive as different lines. - } else { - state.result += common$4.repeat('\n', emptyLines); - } - - // Literal style: just add exact number of line breaks between content lines. - } else { - // Keep all line breaks except the header line break. - state.result += common$4.repeat('\n', didReadContent ? 1 + emptyLines : emptyLines); - } - - didReadContent = true; - detectedIndent = true; - emptyLines = 0; - captureStart = state.position; - - while (!is_EOL(ch) && (ch !== 0)) { - ch = state.input.charCodeAt(++state.position); - } - - captureSegment(state, captureStart, state.position, false); - } - - return true; -} - -function readBlockSequence(state, nodeIndent) { - var _line, - _tag = state.tag, - _anchor = state.anchor, - _result = [], - following, - detected = false, - ch; - - // there is a leading tab before this token, so it can't be a block sequence/mapping; - // it can still be flow sequence/mapping or a scalar - if (state.firstTabInLine !== -1) return false; - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - if (state.firstTabInLine !== -1) { - state.position = state.firstTabInLine; - throwError$1(state, 'tab characters must not be used in indentation'); - } - - if (ch !== 0x2D/* - */) { - break; - } - - following = state.input.charCodeAt(state.position + 1); - - if (!is_WS_OR_EOL(following)) { - break; - } - - detected = true; - state.position++; - - if (skipSeparationSpace(state, true, -1)) { - if (state.lineIndent <= nodeIndent) { - _result.push(null); - ch = state.input.charCodeAt(state.position); - continue; - } - } - - _line = state.line; - composeNode(state, nodeIndent, CONTEXT_BLOCK_IN, false, true); - _result.push(state.result); - skipSeparationSpace(state, true, -1); - - ch = state.input.charCodeAt(state.position); - - if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { - throwError$1(state, 'bad indentation of a sequence entry'); - } else if (state.lineIndent < nodeIndent) { - break; - } - } - - if (detected) { - state.tag = _tag; - state.anchor = _anchor; - state.kind = 'sequence'; - state.result = _result; - return true; - } - return false; -} - -function readBlockMapping(state, nodeIndent, flowIndent) { - var following, - allowCompact, - _line, - _keyLine, - _keyLineStart, - _keyPos, - _tag = state.tag, - _anchor = state.anchor, - _result = {}, - overridableKeys = Object.create(null), - keyTag = null, - keyNode = null, - valueNode = null, - atExplicitKey = false, - detected = false, - ch; - - // there is a leading tab before this token, so it can't be a block sequence/mapping; - // it can still be flow sequence/mapping or a scalar - if (state.firstTabInLine !== -1) return false; - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = _result; - } - - ch = state.input.charCodeAt(state.position); - - while (ch !== 0) { - if (!atExplicitKey && state.firstTabInLine !== -1) { - state.position = state.firstTabInLine; - throwError$1(state, 'tab characters must not be used in indentation'); - } - - following = state.input.charCodeAt(state.position + 1); - _line = state.line; // Save the current line. - - // - // Explicit notation case. There are two separate blocks: - // first for the key (denoted by "?") and second for the value (denoted by ":") - // - if ((ch === 0x3F/* ? */ || ch === 0x3A/* : */) && is_WS_OR_EOL(following)) { - - if (ch === 0x3F/* ? */) { - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = true; - allowCompact = true; - - } else if (atExplicitKey) { - // i.e. 0x3A/* : */ === character after the explicit key. - atExplicitKey = false; - allowCompact = true; - - } else { - throwError$1(state, 'incomplete explicit mapping pair; a key node is missed; or followed by a non-tabulated empty line'); - } - - state.position += 1; - ch = following; - - // - // Implicit notation case. Flow-style node as the key first, then ":", and the value. - // - } else { - _keyLine = state.line; - _keyLineStart = state.lineStart; - _keyPos = state.position; - - if (!composeNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true)) { - // Neither implicit nor explicit notation. - // Reading is done. Go to the epilogue. - break; - } - - if (state.line === _line) { - ch = state.input.charCodeAt(state.position); - - while (is_WHITE_SPACE(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (ch === 0x3A/* : */) { - ch = state.input.charCodeAt(++state.position); - - if (!is_WS_OR_EOL(ch)) { - throwError$1(state, 'a whitespace character is expected after the key-value separator within a block mapping'); - } - - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - detected = true; - atExplicitKey = false; - allowCompact = false; - keyTag = state.tag; - keyNode = state.result; - - } else if (detected) { - throwError$1(state, 'can not read an implicit mapping pair; a colon is missed'); - - } else { - state.tag = _tag; - state.anchor = _anchor; - return true; // Keep the result of `composeNode`. - } - - } else if (detected) { - throwError$1(state, 'can not read a block mapping entry; a multiline key may not be an implicit key'); - - } else { - state.tag = _tag; - state.anchor = _anchor; - return true; // Keep the result of `composeNode`. - } - } - - // - // Common reading code for both explicit and implicit notations. - // - if (state.line === _line || state.lineIndent > nodeIndent) { - if (atExplicitKey) { - _keyLine = state.line; - _keyLineStart = state.lineStart; - _keyPos = state.position; - } - - if (composeNode(state, nodeIndent, CONTEXT_BLOCK_OUT, true, allowCompact)) { - if (atExplicitKey) { - keyNode = state.result; - } else { - valueNode = state.result; - } - } - - if (!atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, valueNode, _keyLine, _keyLineStart, _keyPos); - keyTag = keyNode = valueNode = null; - } - - skipSeparationSpace(state, true, -1); - ch = state.input.charCodeAt(state.position); - } - - if ((state.line === _line || state.lineIndent > nodeIndent) && (ch !== 0)) { - throwError$1(state, 'bad indentation of a mapping entry'); - } else if (state.lineIndent < nodeIndent) { - break; - } - } - - // - // Epilogue. - // - - // Special case: last mapping's node contains only the key in explicit notation. - if (atExplicitKey) { - storeMappingPair(state, _result, overridableKeys, keyTag, keyNode, null, _keyLine, _keyLineStart, _keyPos); - } - - // Expose the resulting mapping. - if (detected) { - state.tag = _tag; - state.anchor = _anchor; - state.kind = 'mapping'; - state.result = _result; - } - - return detected; -} - -function readTagProperty(state) { - var _position, - isVerbatim = false, - isNamed = false, - tagHandle, - tagName, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x21/* ! */) return false; - - if (state.tag !== null) { - throwError$1(state, 'duplication of a tag property'); - } - - ch = state.input.charCodeAt(++state.position); - - if (ch === 0x3C/* < */) { - isVerbatim = true; - ch = state.input.charCodeAt(++state.position); - - } else if (ch === 0x21/* ! */) { - isNamed = true; - tagHandle = '!!'; - ch = state.input.charCodeAt(++state.position); - - } else { - tagHandle = '!'; - } - - _position = state.position; - - if (isVerbatim) { - do { ch = state.input.charCodeAt(++state.position); } - while (ch !== 0 && ch !== 0x3E/* > */); - - if (state.position < state.length) { - tagName = state.input.slice(_position, state.position); - ch = state.input.charCodeAt(++state.position); - } else { - throwError$1(state, 'unexpected end of the stream within a verbatim tag'); - } - } else { - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - - if (ch === 0x21/* ! */) { - if (!isNamed) { - tagHandle = state.input.slice(_position - 1, state.position + 1); - - if (!PATTERN_TAG_HANDLE.test(tagHandle)) { - throwError$1(state, 'named tag handle cannot contain such characters'); - } - - isNamed = true; - _position = state.position + 1; - } else { - throwError$1(state, 'tag suffix cannot contain exclamation marks'); - } - } - - ch = state.input.charCodeAt(++state.position); - } - - tagName = state.input.slice(_position, state.position); - - if (PATTERN_FLOW_INDICATORS.test(tagName)) { - throwError$1(state, 'tag suffix cannot contain flow indicator characters'); - } - } - - if (tagName && !PATTERN_TAG_URI.test(tagName)) { - throwError$1(state, 'tag name cannot contain such characters: ' + tagName); - } - - try { - tagName = decodeURIComponent(tagName); - } catch (err) { - throwError$1(state, 'tag name is malformed: ' + tagName); - } - - if (isVerbatim) { - state.tag = tagName; - - } else if (_hasOwnProperty$1.call(state.tagMap, tagHandle)) { - state.tag = state.tagMap[tagHandle] + tagName; - - } else if (tagHandle === '!') { - state.tag = '!' + tagName; - - } else if (tagHandle === '!!') { - state.tag = 'tag:yaml.org,2002:' + tagName; - - } else { - throwError$1(state, 'undeclared tag handle "' + tagHandle + '"'); - } - - return true; -} - -function readAnchorProperty(state) { - var _position, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x26/* & */) return false; - - if (state.anchor !== null) { - throwError$1(state, 'duplication of an anchor property'); - } - - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (state.position === _position) { - throwError$1(state, 'name of an anchor node must contain at least one character'); - } - - state.anchor = state.input.slice(_position, state.position); - return true; -} - -function readAlias(state) { - var _position, alias, - ch; - - ch = state.input.charCodeAt(state.position); - - if (ch !== 0x2A/* * */) return false; - - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch) && !is_FLOW_INDICATOR(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (state.position === _position) { - throwError$1(state, 'name of an alias node must contain at least one character'); - } - - alias = state.input.slice(_position, state.position); - - if (!_hasOwnProperty$1.call(state.anchorMap, alias)) { - throwError$1(state, 'unidentified alias "' + alias + '"'); - } - - state.result = state.anchorMap[alias]; - skipSeparationSpace(state, true, -1); - return true; -} - -function composeNode(state, parentIndent, nodeContext, allowToSeek, allowCompact) { - var allowBlockStyles, - allowBlockScalars, - allowBlockCollections, - indentStatus = 1, // 1: this>parent, 0: this=parent, -1: this parentIndent) { - indentStatus = 1; - } else if (state.lineIndent === parentIndent) { - indentStatus = 0; - } else if (state.lineIndent < parentIndent) { - indentStatus = -1; - } - } - } - - if (indentStatus === 1) { - while (readTagProperty(state) || readAnchorProperty(state)) { - if (skipSeparationSpace(state, true, -1)) { - atNewLine = true; - allowBlockCollections = allowBlockStyles; - - if (state.lineIndent > parentIndent) { - indentStatus = 1; - } else if (state.lineIndent === parentIndent) { - indentStatus = 0; - } else if (state.lineIndent < parentIndent) { - indentStatus = -1; - } - } else { - allowBlockCollections = false; - } - } - } - - if (allowBlockCollections) { - allowBlockCollections = atNewLine || allowCompact; - } - - if (indentStatus === 1 || CONTEXT_BLOCK_OUT === nodeContext) { - if (CONTEXT_FLOW_IN === nodeContext || CONTEXT_FLOW_OUT === nodeContext) { - flowIndent = parentIndent; - } else { - flowIndent = parentIndent + 1; - } - - blockIndent = state.position - state.lineStart; - - if (indentStatus === 1) { - if (allowBlockCollections && - (readBlockSequence(state, blockIndent) || - readBlockMapping(state, blockIndent, flowIndent)) || - readFlowCollection(state, flowIndent)) { - hasContent = true; - } else { - if ((allowBlockScalars && readBlockScalar(state, flowIndent)) || - readSingleQuotedScalar(state, flowIndent) || - readDoubleQuotedScalar(state, flowIndent)) { - hasContent = true; - - } else if (readAlias(state)) { - hasContent = true; - - if (state.tag !== null || state.anchor !== null) { - throwError$1(state, 'alias node should not have any properties'); - } - - } else if (readPlainScalar(state, flowIndent, CONTEXT_FLOW_IN === nodeContext)) { - hasContent = true; - - if (state.tag === null) { - state.tag = '?'; - } - } - - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - } - } else if (indentStatus === 0) { - // Special case: block sequences are allowed to have same indentation level as the parent. - // http://www.yaml.org/spec/1.2/spec.html#id2799784 - hasContent = allowBlockCollections && readBlockSequence(state, blockIndent); - } - } - - if (state.tag === null) { - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - - } else if (state.tag === '?') { - // Implicit resolving is not allowed for non-scalar types, and '?' - // non-specific tag is only automatically assigned to plain scalars. - // - // We only need to check kind conformity in case user explicitly assigns '?' - // tag, for example like this: "! [0]" - // - if (state.result !== null && state.kind !== 'scalar') { - throwError$1(state, 'unacceptable node kind for ! tag; it should be "scalar", not "' + state.kind + '"'); - } - - for (typeIndex = 0, typeQuantity = state.implicitTypes.length; typeIndex < typeQuantity; typeIndex += 1) { - type = state.implicitTypes[typeIndex]; - - if (type.resolve(state.result)) { // `state.result` updated in resolver if matched - state.result = type.construct(state.result); - state.tag = type.tag; - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - break; - } - } - } else if (state.tag !== '!') { - if (_hasOwnProperty$1.call(state.typeMap[state.kind || 'fallback'], state.tag)) { - type = state.typeMap[state.kind || 'fallback'][state.tag]; - } else { - // looking for multi type - type = null; - typeList = state.typeMap.multi[state.kind || 'fallback']; - - for (typeIndex = 0, typeQuantity = typeList.length; typeIndex < typeQuantity; typeIndex += 1) { - if (state.tag.slice(0, typeList[typeIndex].tag.length) === typeList[typeIndex].tag) { - type = typeList[typeIndex]; - break; - } - } - } - - if (!type) { - throwError$1(state, 'unknown tag !<' + state.tag + '>'); - } - - if (state.result !== null && type.kind !== state.kind) { - throwError$1(state, 'unacceptable node kind for !<' + state.tag + '> tag; it should be "' + type.kind + '", not "' + state.kind + '"'); - } - - if (!type.resolve(state.result, state.tag)) { // `state.result` updated in resolver if matched - throwError$1(state, 'cannot resolve a node with !<' + state.tag + '> explicit tag'); - } else { - state.result = type.construct(state.result, state.tag); - if (state.anchor !== null) { - state.anchorMap[state.anchor] = state.result; - } - } - } - - if (state.listener !== null) { - state.listener('close', state); - } - return state.tag !== null || state.anchor !== null || hasContent; -} - -function readDocument(state) { - var documentStart = state.position, - _position, - directiveName, - directiveArgs, - hasDirectives = false, - ch; - - state.version = null; - state.checkLineBreaks = state.legacy; - state.tagMap = Object.create(null); - state.anchorMap = Object.create(null); - - while ((ch = state.input.charCodeAt(state.position)) !== 0) { - skipSeparationSpace(state, true, -1); - - ch = state.input.charCodeAt(state.position); - - if (state.lineIndent > 0 || ch !== 0x25/* % */) { - break; - } - - hasDirectives = true; - ch = state.input.charCodeAt(++state.position); - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - directiveName = state.input.slice(_position, state.position); - directiveArgs = []; - - if (directiveName.length < 1) { - throwError$1(state, 'directive name must not be less than one character in length'); - } - - while (ch !== 0) { - while (is_WHITE_SPACE(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - if (ch === 0x23/* # */) { - do { ch = state.input.charCodeAt(++state.position); } - while (ch !== 0 && !is_EOL(ch)); - break; - } - - if (is_EOL(ch)) break; - - _position = state.position; - - while (ch !== 0 && !is_WS_OR_EOL(ch)) { - ch = state.input.charCodeAt(++state.position); - } - - directiveArgs.push(state.input.slice(_position, state.position)); - } - - if (ch !== 0) readLineBreak(state); - - if (_hasOwnProperty$1.call(directiveHandlers, directiveName)) { - directiveHandlers[directiveName](state, directiveName, directiveArgs); - } else { - throwWarning(state, 'unknown document directive "' + directiveName + '"'); - } - } - - skipSeparationSpace(state, true, -1); - - if (state.lineIndent === 0 && - state.input.charCodeAt(state.position) === 0x2D/* - */ && - state.input.charCodeAt(state.position + 1) === 0x2D/* - */ && - state.input.charCodeAt(state.position + 2) === 0x2D/* - */) { - state.position += 3; - skipSeparationSpace(state, true, -1); - - } else if (hasDirectives) { - throwError$1(state, 'directives end mark is expected'); - } - - composeNode(state, state.lineIndent - 1, CONTEXT_BLOCK_OUT, false, true); - skipSeparationSpace(state, true, -1); - - if (state.checkLineBreaks && - PATTERN_NON_ASCII_LINE_BREAKS.test(state.input.slice(documentStart, state.position))) { - throwWarning(state, 'non-ASCII line breaks are interpreted as content'); - } - - state.documents.push(state.result); - - if (state.position === state.lineStart && testDocumentSeparator(state)) { - - if (state.input.charCodeAt(state.position) === 0x2E/* . */) { - state.position += 3; - skipSeparationSpace(state, true, -1); - } - return; - } - - if (state.position < (state.length - 1)) { - throwError$1(state, 'end of the stream or a document separator is expected'); - } else { - return; - } -} - - -function loadDocuments(input, options) { - input = String(input); - options = options || {}; - - if (input.length !== 0) { - - // Add tailing `\n` if not exists - if (input.charCodeAt(input.length - 1) !== 0x0A/* LF */ && - input.charCodeAt(input.length - 1) !== 0x0D/* CR */) { - input += '\n'; - } - - // Strip BOM - if (input.charCodeAt(0) === 0xFEFF) { - input = input.slice(1); - } - } - - var state = new State$1(input, options); - - var nullpos = input.indexOf('\0'); - - if (nullpos !== -1) { - state.position = nullpos; - throwError$1(state, 'null byte is not allowed in input'); - } - - // Use 0 as string terminator. That significantly simplifies bounds check. - state.input += '\0'; - - while (state.input.charCodeAt(state.position) === 0x20/* Space */) { - state.lineIndent += 1; - state.position += 1; - } - - while (state.position < (state.length - 1)) { - readDocument(state); - } - - return state.documents; -} - - -function loadAll$1(input, iterator, options) { - if (iterator !== null && typeof iterator === 'object' && typeof options === 'undefined') { - options = iterator; - iterator = null; - } - - var documents = loadDocuments(input, options); - - if (typeof iterator !== 'function') { - return documents; - } - - for (var index = 0, length = documents.length; index < length; index += 1) { - iterator(documents[index]); - } -} - - -function load$1(input, options) { - var documents = loadDocuments(input, options); - - if (documents.length === 0) { - /*eslint-disable no-undefined*/ - return undefined; - } else if (documents.length === 1) { - return documents[0]; - } - throw new exception('expected a single document in the stream, but found more'); -} - - -var loadAll_1 = loadAll$1; -var load_1 = load$1; - -var loader = { - loadAll: loadAll_1, - load: load_1 -}; - -/*eslint-disable no-use-before-define*/ - - - - - -var _toString = Object.prototype.toString; -var _hasOwnProperty = Object.prototype.hasOwnProperty; - -var CHAR_BOM = 0xFEFF; -var CHAR_TAB = 0x09; /* Tab */ -var CHAR_LINE_FEED = 0x0A; /* LF */ -var CHAR_CARRIAGE_RETURN = 0x0D; /* CR */ -var CHAR_SPACE = 0x20; /* Space */ -var CHAR_EXCLAMATION = 0x21; /* ! */ -var CHAR_DOUBLE_QUOTE = 0x22; /* " */ -var CHAR_SHARP = 0x23; /* # */ -var CHAR_PERCENT = 0x25; /* % */ -var CHAR_AMPERSAND = 0x26; /* & */ -var CHAR_SINGLE_QUOTE = 0x27; /* ' */ -var CHAR_ASTERISK = 0x2A; /* * */ -var CHAR_COMMA = 0x2C; /* , */ -var CHAR_MINUS = 0x2D; /* - */ -var CHAR_COLON = 0x3A; /* : */ -var CHAR_EQUALS = 0x3D; /* = */ -var CHAR_GREATER_THAN = 0x3E; /* > */ -var CHAR_QUESTION = 0x3F; /* ? */ -var CHAR_COMMERCIAL_AT = 0x40; /* @ */ -var CHAR_LEFT_SQUARE_BRACKET = 0x5B; /* [ */ -var CHAR_RIGHT_SQUARE_BRACKET = 0x5D; /* ] */ -var CHAR_GRAVE_ACCENT = 0x60; /* ` */ -var CHAR_LEFT_CURLY_BRACKET = 0x7B; /* { */ -var CHAR_VERTICAL_LINE = 0x7C; /* | */ -var CHAR_RIGHT_CURLY_BRACKET = 0x7D; /* } */ - -var ESCAPE_SEQUENCES = {}; - -ESCAPE_SEQUENCES[0x00] = '\\0'; -ESCAPE_SEQUENCES[0x07] = '\\a'; -ESCAPE_SEQUENCES[0x08] = '\\b'; -ESCAPE_SEQUENCES[0x09] = '\\t'; -ESCAPE_SEQUENCES[0x0A] = '\\n'; -ESCAPE_SEQUENCES[0x0B] = '\\v'; -ESCAPE_SEQUENCES[0x0C] = '\\f'; -ESCAPE_SEQUENCES[0x0D] = '\\r'; -ESCAPE_SEQUENCES[0x1B] = '\\e'; -ESCAPE_SEQUENCES[0x22] = '\\"'; -ESCAPE_SEQUENCES[0x5C] = '\\\\'; -ESCAPE_SEQUENCES[0x85] = '\\N'; -ESCAPE_SEQUENCES[0xA0] = '\\_'; -ESCAPE_SEQUENCES[0x2028] = '\\L'; -ESCAPE_SEQUENCES[0x2029] = '\\P'; - -var DEPRECATED_BOOLEANS_SYNTAX = [ - 'y', 'Y', 'yes', 'Yes', 'YES', 'on', 'On', 'ON', - 'n', 'N', 'no', 'No', 'NO', 'off', 'Off', 'OFF' -]; - -var DEPRECATED_BASE60_SYNTAX = /^[-+]?[0-9_]+(?::[0-9_]+)+(?:\.[0-9_]*)?$/; - -function compileStyleMap(schema, map) { - var result, keys, index, length, tag, style, type; - - if (map === null) return {}; - - result = {}; - keys = Object.keys(map); - - for (index = 0, length = keys.length; index < length; index += 1) { - tag = keys[index]; - style = String(map[tag]); - - if (tag.slice(0, 2) === '!!') { - tag = 'tag:yaml.org,2002:' + tag.slice(2); - } - type = schema.compiledTypeMap['fallback'][tag]; - - if (type && _hasOwnProperty.call(type.styleAliases, style)) { - style = type.styleAliases[style]; - } - - result[tag] = style; - } - - return result; -} - -function encodeHex(character) { - var string, handle, length; - - string = character.toString(16).toUpperCase(); - - if (character <= 0xFF) { - handle = 'x'; - length = 2; - } else if (character <= 0xFFFF) { - handle = 'u'; - length = 4; - } else if (character <= 0xFFFFFFFF) { - handle = 'U'; - length = 8; - } else { - throw new exception('code point within a string may not be greater than 0xFFFFFFFF'); - } - - return '\\' + handle + common$4.repeat('0', length - string.length) + string; -} - - -var QUOTING_TYPE_SINGLE = 1, - QUOTING_TYPE_DOUBLE = 2; - -function State(options) { - this.schema = options['schema'] || _default$1; - this.indent = Math.max(1, (options['indent'] || 2)); - this.noArrayIndent = options['noArrayIndent'] || false; - this.skipInvalid = options['skipInvalid'] || false; - this.flowLevel = (common$4.isNothing(options['flowLevel']) ? -1 : options['flowLevel']); - this.styleMap = compileStyleMap(this.schema, options['styles'] || null); - this.sortKeys = options['sortKeys'] || false; - this.lineWidth = options['lineWidth'] || 80; - this.noRefs = options['noRefs'] || false; - this.noCompatMode = options['noCompatMode'] || false; - this.condenseFlow = options['condenseFlow'] || false; - this.quotingType = options['quotingType'] === '"' ? QUOTING_TYPE_DOUBLE : QUOTING_TYPE_SINGLE; - this.forceQuotes = options['forceQuotes'] || false; - this.replacer = typeof options['replacer'] === 'function' ? options['replacer'] : null; - - this.implicitTypes = this.schema.compiledImplicit; - this.explicitTypes = this.schema.compiledExplicit; - - this.tag = null; - this.result = ''; - - this.duplicates = []; - this.usedDuplicates = null; -} - -// Indents every line in a string. Empty lines (\n only) are not indented. -function indentString(string, spaces) { - var ind = common$4.repeat(' ', spaces), - position = 0, - next = -1, - result = '', - line, - length = string.length; - - while (position < length) { - next = string.indexOf('\n', position); - if (next === -1) { - line = string.slice(position); - position = length; - } else { - line = string.slice(position, next + 1); - position = next + 1; - } - - if (line.length && line !== '\n') result += ind; - - result += line; - } - - return result; -} - -function generateNextLine(state, level) { - return '\n' + common$4.repeat(' ', state.indent * level); -} - -function testImplicitResolving(state, str) { - var index, length, type; - - for (index = 0, length = state.implicitTypes.length; index < length; index += 1) { - type = state.implicitTypes[index]; - - if (type.resolve(str)) { - return true; - } - } - - return false; -} - -// [33] s-white ::= s-space | s-tab -function isWhitespace(c) { - return c === CHAR_SPACE || c === CHAR_TAB; -} - -// Returns true if the character can be printed without escaping. -// From YAML 1.2: "any allowed characters known to be non-printable -// should also be escaped. [However,] This isn’t mandatory" -// Derived from nb-char - \t - #x85 - #xA0 - #x2028 - #x2029. -function isPrintable(c) { - return (0x00020 <= c && c <= 0x00007E) - || ((0x000A1 <= c && c <= 0x00D7FF) && c !== 0x2028 && c !== 0x2029) - || ((0x0E000 <= c && c <= 0x00FFFD) && c !== CHAR_BOM) - || (0x10000 <= c && c <= 0x10FFFF); -} - -// [34] ns-char ::= nb-char - s-white -// [27] nb-char ::= c-printable - b-char - c-byte-order-mark -// [26] b-char ::= b-line-feed | b-carriage-return -// Including s-white (for some reason, examples doesn't match specs in this aspect) -// ns-char ::= c-printable - b-line-feed - b-carriage-return - c-byte-order-mark -function isNsCharOrWhitespace(c) { - return isPrintable(c) - && c !== CHAR_BOM - // - b-char - && c !== CHAR_CARRIAGE_RETURN - && c !== CHAR_LINE_FEED; -} - -// [127] ns-plain-safe(c) ::= c = flow-out ⇒ ns-plain-safe-out -// c = flow-in ⇒ ns-plain-safe-in -// c = block-key ⇒ ns-plain-safe-out -// c = flow-key ⇒ ns-plain-safe-in -// [128] ns-plain-safe-out ::= ns-char -// [129] ns-plain-safe-in ::= ns-char - c-flow-indicator -// [130] ns-plain-char(c) ::= ( ns-plain-safe(c) - “:” - “#” ) -// | ( /* An ns-char preceding */ “#” ) -// | ( “:” /* Followed by an ns-plain-safe(c) */ ) -function isPlainSafe(c, prev, inblock) { - var cIsNsCharOrWhitespace = isNsCharOrWhitespace(c); - var cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c); - return ( - // ns-plain-safe - inblock ? // c = flow-in - cIsNsCharOrWhitespace - : cIsNsCharOrWhitespace - // - c-flow-indicator - && c !== CHAR_COMMA - && c !== CHAR_LEFT_SQUARE_BRACKET - && c !== CHAR_RIGHT_SQUARE_BRACKET - && c !== CHAR_LEFT_CURLY_BRACKET - && c !== CHAR_RIGHT_CURLY_BRACKET - ) - // ns-plain-char - && c !== CHAR_SHARP // false on '#' - && !(prev === CHAR_COLON && !cIsNsChar) // false on ': ' - || (isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP) // change to true on '[^ ]#' - || (prev === CHAR_COLON && cIsNsChar); // change to true on ':[^ ]' -} - -// Simplified test for values allowed as the first character in plain style. -function isPlainSafeFirst(c) { - // Uses a subset of ns-char - c-indicator - // where ns-char = nb-char - s-white. - // No support of ( ( “?” | “:” | “-” ) /* Followed by an ns-plain-safe(c)) */ ) part - return isPrintable(c) && c !== CHAR_BOM - && !isWhitespace(c) // - s-white - // - (c-indicator ::= - // “-” | “?” | “:” | “,” | “[” | “]” | “{” | “}” - && c !== CHAR_MINUS - && c !== CHAR_QUESTION - && c !== CHAR_COLON - && c !== CHAR_COMMA - && c !== CHAR_LEFT_SQUARE_BRACKET - && c !== CHAR_RIGHT_SQUARE_BRACKET - && c !== CHAR_LEFT_CURLY_BRACKET - && c !== CHAR_RIGHT_CURLY_BRACKET - // | “#” | “&” | “*” | “!” | “|” | “=” | “>” | “'” | “"” - && c !== CHAR_SHARP - && c !== CHAR_AMPERSAND - && c !== CHAR_ASTERISK - && c !== CHAR_EXCLAMATION - && c !== CHAR_VERTICAL_LINE - && c !== CHAR_EQUALS - && c !== CHAR_GREATER_THAN - && c !== CHAR_SINGLE_QUOTE - && c !== CHAR_DOUBLE_QUOTE - // | “%” | “@” | “`”) - && c !== CHAR_PERCENT - && c !== CHAR_COMMERCIAL_AT - && c !== CHAR_GRAVE_ACCENT; -} - -// Simplified test for values allowed as the last character in plain style. -function isPlainSafeLast(c) { - // just not whitespace or colon, it will be checked to be plain character later - return !isWhitespace(c) && c !== CHAR_COLON; -} - -// Same as 'string'.codePointAt(pos), but works in older browsers. -function codePointAt(string, pos) { - var first = string.charCodeAt(pos), second; - if (first >= 0xD800 && first <= 0xDBFF && pos + 1 < string.length) { - second = string.charCodeAt(pos + 1); - if (second >= 0xDC00 && second <= 0xDFFF) { - // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae - return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; - } - } - return first; -} - -// Determines whether block indentation indicator is required. -function needIndentIndicator(string) { - var leadingSpaceRe = /^\n* /; - return leadingSpaceRe.test(string); -} - -var STYLE_PLAIN = 1, - STYLE_SINGLE = 2, - STYLE_LITERAL = 3, - STYLE_FOLDED = 4, - STYLE_DOUBLE = 5; - -// Determines which scalar styles are possible and returns the preferred style. -// lineWidth = -1 => no limit. -// Pre-conditions: str.length > 0. -// Post-conditions: -// STYLE_PLAIN or STYLE_SINGLE => no \n are in the string. -// STYLE_LITERAL => no lines are suitable for folding (or lineWidth is -1). -// STYLE_FOLDED => a line > lineWidth and can be folded (and lineWidth != -1). -function chooseScalarStyle(string, singleLineOnly, indentPerLevel, lineWidth, - testAmbiguousType, quotingType, forceQuotes, inblock) { - - var i; - var char = 0; - var prevChar = null; - var hasLineBreak = false; - var hasFoldableLine = false; // only checked if shouldTrackWidth - var shouldTrackWidth = lineWidth !== -1; - var previousLineBreak = -1; // count the first line correctly - var plain = isPlainSafeFirst(codePointAt(string, 0)) - && isPlainSafeLast(codePointAt(string, string.length - 1)); - - if (singleLineOnly || forceQuotes) { - // Case: no block styles. - // Check for disallowed characters to rule out plain and single. - for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - if (!isPrintable(char)) { - return STYLE_DOUBLE; - } - plain = plain && isPlainSafe(char, prevChar, inblock); - prevChar = char; - } - } else { - // Case: block styles permitted. - for (i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - if (char === CHAR_LINE_FEED) { - hasLineBreak = true; - // Check if any line can be folded. - if (shouldTrackWidth) { - hasFoldableLine = hasFoldableLine || - // Foldable line = too long, and not more-indented. - (i - previousLineBreak - 1 > lineWidth && - string[previousLineBreak + 1] !== ' '); - previousLineBreak = i; - } - } else if (!isPrintable(char)) { - return STYLE_DOUBLE; - } - plain = plain && isPlainSafe(char, prevChar, inblock); - prevChar = char; - } - // in case the end is missing a \n - hasFoldableLine = hasFoldableLine || (shouldTrackWidth && - (i - previousLineBreak - 1 > lineWidth && - string[previousLineBreak + 1] !== ' ')); - } - // Although every style can represent \n without escaping, prefer block styles - // for multiline, since they're more readable and they don't add empty lines. - // Also prefer folding a super-long line. - if (!hasLineBreak && !hasFoldableLine) { - // Strings interpretable as another type have to be quoted; - // e.g. the string 'true' vs. the boolean true. - if (plain && !forceQuotes && !testAmbiguousType(string)) { - return STYLE_PLAIN; - } - return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; - } - // Edge case: block indentation indicator can only have one digit. - if (indentPerLevel > 9 && needIndentIndicator(string)) { - return STYLE_DOUBLE; - } - // At this point we know block styles are valid. - // Prefer literal style unless we want to fold. - if (!forceQuotes) { - return hasFoldableLine ? STYLE_FOLDED : STYLE_LITERAL; - } - return quotingType === QUOTING_TYPE_DOUBLE ? STYLE_DOUBLE : STYLE_SINGLE; -} - -// Note: line breaking/folding is implemented for only the folded style. -// NB. We drop the last trailing newline (if any) of a returned block scalar -// since the dumper adds its own newline. This always works: -// • No ending newline => unaffected; already using strip "-" chomping. -// • Ending newline => removed then restored. -// Importantly, this keeps the "+" chomp indicator from gaining an extra line. -function writeScalar(state, string, level, iskey, inblock) { - state.dump = (function () { - if (string.length === 0) { - return state.quotingType === QUOTING_TYPE_DOUBLE ? '""' : "''"; - } - if (!state.noCompatMode) { - if (DEPRECATED_BOOLEANS_SYNTAX.indexOf(string) !== -1 || DEPRECATED_BASE60_SYNTAX.test(string)) { - return state.quotingType === QUOTING_TYPE_DOUBLE ? ('"' + string + '"') : ("'" + string + "'"); - } - } - - var indent = state.indent * Math.max(1, level); // no 0-indent scalars - // As indentation gets deeper, let the width decrease monotonically - // to the lower bound min(state.lineWidth, 40). - // Note that this implies - // state.lineWidth ≤ 40 + state.indent: width is fixed at the lower bound. - // state.lineWidth > 40 + state.indent: width decreases until the lower bound. - // This behaves better than a constant minimum width which disallows narrower options, - // or an indent threshold which causes the width to suddenly increase. - var lineWidth = state.lineWidth === -1 - ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent); - - // Without knowing if keys are implicit/explicit, assume implicit for safety. - var singleLineOnly = iskey - // No block styles in flow mode. - || (state.flowLevel > -1 && level >= state.flowLevel); - function testAmbiguity(string) { - return testImplicitResolving(state, string); - } - - switch (chooseScalarStyle(string, singleLineOnly, state.indent, lineWidth, - testAmbiguity, state.quotingType, state.forceQuotes && !iskey, inblock)) { - - case STYLE_PLAIN: - return string; - case STYLE_SINGLE: - return "'" + string.replace(/'/g, "''") + "'"; - case STYLE_LITERAL: - return '|' + blockHeader(string, state.indent) - + dropEndingNewline(indentString(string, indent)); - case STYLE_FOLDED: - return '>' + blockHeader(string, state.indent) - + dropEndingNewline(indentString(foldString(string, lineWidth), indent)); - case STYLE_DOUBLE: - return '"' + escapeString(string) + '"'; - default: - throw new exception('impossible error: invalid scalar style'); - } - }()); -} - -// Pre-conditions: string is valid for a block scalar, 1 <= indentPerLevel <= 9. -function blockHeader(string, indentPerLevel) { - var indentIndicator = needIndentIndicator(string) ? String(indentPerLevel) : ''; - - // note the special case: the string '\n' counts as a "trailing" empty line. - var clip = string[string.length - 1] === '\n'; - var keep = clip && (string[string.length - 2] === '\n' || string === '\n'); - var chomp = keep ? '+' : (clip ? '' : '-'); - - return indentIndicator + chomp + '\n'; -} - -// (See the note for writeScalar.) -function dropEndingNewline(string) { - return string[string.length - 1] === '\n' ? string.slice(0, -1) : string; -} - -// Note: a long line without a suitable break point will exceed the width limit. -// Pre-conditions: every char in str isPrintable, str.length > 0, width > 0. -function foldString(string, width) { - // In folded style, $k$ consecutive newlines output as $k+1$ newlines— - // unless they're before or after a more-indented line, or at the very - // beginning or end, in which case $k$ maps to $k$. - // Therefore, parse each chunk as newline(s) followed by a content line. - var lineRe = /(\n+)([^\n]*)/g; - - // first line (possibly an empty line) - var result = (function () { - var nextLF = string.indexOf('\n'); - nextLF = nextLF !== -1 ? nextLF : string.length; - lineRe.lastIndex = nextLF; - return foldLine(string.slice(0, nextLF), width); - }()); - // If we haven't reached the first content line yet, don't add an extra \n. - var prevMoreIndented = string[0] === '\n' || string[0] === ' '; - var moreIndented; - - // rest of the lines - var match; - while ((match = lineRe.exec(string))) { - var prefix = match[1], line = match[2]; - moreIndented = (line[0] === ' '); - result += prefix - + (!prevMoreIndented && !moreIndented && line !== '' - ? '\n' : '') - + foldLine(line, width); - prevMoreIndented = moreIndented; - } - - return result; -} - -// Greedy line breaking. -// Picks the longest line under the limit each time, -// otherwise settles for the shortest line over the limit. -// NB. More-indented lines *cannot* be folded, as that would add an extra \n. -function foldLine(line, width) { - if (line === '' || line[0] === ' ') return line; - - // Since a more-indented line adds a \n, breaks can't be followed by a space. - var breakRe = / [^ ]/g; // note: the match index will always be <= length-2. - var match; - // start is an inclusive index. end, curr, and next are exclusive. - var start = 0, end, curr = 0, next = 0; - var result = ''; - - // Invariants: 0 <= start <= length-1. - // 0 <= curr <= next <= max(0, length-2). curr - start <= width. - // Inside the loop: - // A match implies length >= 2, so curr and next are <= length-2. - while ((match = breakRe.exec(line))) { - next = match.index; - // maintain invariant: curr - start <= width - if (next - start > width) { - end = (curr > start) ? curr : next; // derive end <= length-2 - result += '\n' + line.slice(start, end); - // skip the space that was output as \n - start = end + 1; // derive start <= length-1 - } - curr = next; - } - - // By the invariants, start <= length-1, so there is something left over. - // It is either the whole string or a part starting from non-whitespace. - result += '\n'; - // Insert a break if the remainder is too long and there is a break available. - if (line.length - start > width && curr > start) { - result += line.slice(start, curr) + '\n' + line.slice(curr + 1); - } else { - result += line.slice(start); - } - - return result.slice(1); // drop extra \n joiner -} - -// Escapes a double-quoted string. -function escapeString(string) { - var result = ''; - var char = 0; - var escapeSeq; - - for (var i = 0; i < string.length; char >= 0x10000 ? i += 2 : i++) { - char = codePointAt(string, i); - escapeSeq = ESCAPE_SEQUENCES[char]; - - if (!escapeSeq && isPrintable(char)) { - result += string[i]; - if (char >= 0x10000) result += string[i + 1]; - } else { - result += escapeSeq || encodeHex(char); - } - } - - return result; -} - -function writeFlowSequence(state, level, object) { - var _result = '', - _tag = state.tag, - index, - length, - value; - - for (index = 0, length = object.length; index < length; index += 1) { - value = object[index]; - - if (state.replacer) { - value = state.replacer.call(object, String(index), value); - } - - // Write only valid elements, put null instead of invalid elements. - if (writeNode(state, level, value, false, false) || - (typeof value === 'undefined' && - writeNode(state, level, null, false, false))) { - - if (_result !== '') _result += ',' + (!state.condenseFlow ? ' ' : ''); - _result += state.dump; - } - } - - state.tag = _tag; - state.dump = '[' + _result + ']'; -} - -function writeBlockSequence(state, level, object, compact) { - var _result = '', - _tag = state.tag, - index, - length, - value; - - for (index = 0, length = object.length; index < length; index += 1) { - value = object[index]; - - if (state.replacer) { - value = state.replacer.call(object, String(index), value); - } - - // Write only valid elements, put null instead of invalid elements. - if (writeNode(state, level + 1, value, true, true, false, true) || - (typeof value === 'undefined' && - writeNode(state, level + 1, null, true, true, false, true))) { - - if (!compact || _result !== '') { - _result += generateNextLine(state, level); - } - - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - _result += '-'; - } else { - _result += '- '; - } - - _result += state.dump; - } - } - - state.tag = _tag; - state.dump = _result || '[]'; // Empty sequence if no valid values. -} - -function writeFlowMapping(state, level, object) { - var _result = '', - _tag = state.tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue, - pairBuffer; - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - - pairBuffer = ''; - if (_result !== '') pairBuffer += ', '; - - if (state.condenseFlow) pairBuffer += '"'; - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - if (state.replacer) { - objectValue = state.replacer.call(object, objectKey, objectValue); - } - - if (!writeNode(state, level, objectKey, false, false)) { - continue; // Skip this pair because of invalid key; - } - - if (state.dump.length > 1024) pairBuffer += '? '; - - pairBuffer += state.dump + (state.condenseFlow ? '"' : '') + ':' + (state.condenseFlow ? '' : ' '); - - if (!writeNode(state, level, objectValue, false, false)) { - continue; // Skip this pair because of invalid value. - } - - pairBuffer += state.dump; - - // Both key and value are valid. - _result += pairBuffer; - } - - state.tag = _tag; - state.dump = '{' + _result + '}'; -} - -function writeBlockMapping(state, level, object, compact) { - var _result = '', - _tag = state.tag, - objectKeyList = Object.keys(object), - index, - length, - objectKey, - objectValue, - explicitPair, - pairBuffer; - - // Allow sorting keys so that the output file is deterministic - if (state.sortKeys === true) { - // Default sorting - objectKeyList.sort(); - } else if (typeof state.sortKeys === 'function') { - // Custom sort function - objectKeyList.sort(state.sortKeys); - } else if (state.sortKeys) { - // Something is wrong - throw new exception('sortKeys must be a boolean or a function'); - } - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - pairBuffer = ''; - - if (!compact || _result !== '') { - pairBuffer += generateNextLine(state, level); - } - - objectKey = objectKeyList[index]; - objectValue = object[objectKey]; - - if (state.replacer) { - objectValue = state.replacer.call(object, objectKey, objectValue); - } - - if (!writeNode(state, level + 1, objectKey, true, true, true)) { - continue; // Skip this pair because of invalid key. - } - - explicitPair = (state.tag !== null && state.tag !== '?') || - (state.dump && state.dump.length > 1024); - - if (explicitPair) { - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - pairBuffer += '?'; - } else { - pairBuffer += '? '; - } - } - - pairBuffer += state.dump; - - if (explicitPair) { - pairBuffer += generateNextLine(state, level); - } - - if (!writeNode(state, level + 1, objectValue, true, explicitPair)) { - continue; // Skip this pair because of invalid value. - } - - if (state.dump && CHAR_LINE_FEED === state.dump.charCodeAt(0)) { - pairBuffer += ':'; - } else { - pairBuffer += ': '; - } - - pairBuffer += state.dump; - - // Both key and value are valid. - _result += pairBuffer; - } - - state.tag = _tag; - state.dump = _result || '{}'; // Empty mapping if no valid pairs. -} - -function detectType(state, object, explicit) { - var _result, typeList, index, length, type, style; - - typeList = explicit ? state.explicitTypes : state.implicitTypes; - - for (index = 0, length = typeList.length; index < length; index += 1) { - type = typeList[index]; - - if ((type.instanceOf || type.predicate) && - (!type.instanceOf || ((typeof object === 'object') && (object instanceof type.instanceOf))) && - (!type.predicate || type.predicate(object))) { - - if (explicit) { - if (type.multi && type.representName) { - state.tag = type.representName(object); - } else { - state.tag = type.tag; - } - } else { - state.tag = '?'; - } - - if (type.represent) { - style = state.styleMap[type.tag] || type.defaultStyle; - - if (_toString.call(type.represent) === '[object Function]') { - _result = type.represent(object, style); - } else if (_hasOwnProperty.call(type.represent, style)) { - _result = type.represent[style](object, style); - } else { - throw new exception('!<' + type.tag + '> tag resolver accepts not "' + style + '" style'); - } - - state.dump = _result; - } - - return true; - } - } - - return false; -} - -// Serializes `object` and writes it to global `result`. -// Returns true on success, or false on invalid object. -// -function writeNode(state, level, object, block, compact, iskey, isblockseq) { - state.tag = null; - state.dump = object; - - if (!detectType(state, object, false)) { - detectType(state, object, true); - } - - var type = _toString.call(state.dump); - var inblock = block; - var tagStr; - - if (block) { - block = (state.flowLevel < 0 || state.flowLevel > level); - } - - var objectOrArray = type === '[object Object]' || type === '[object Array]', - duplicateIndex, - duplicate; - - if (objectOrArray) { - duplicateIndex = state.duplicates.indexOf(object); - duplicate = duplicateIndex !== -1; - } - - if ((state.tag !== null && state.tag !== '?') || duplicate || (state.indent !== 2 && level > 0)) { - compact = false; - } - - if (duplicate && state.usedDuplicates[duplicateIndex]) { - state.dump = '*ref_' + duplicateIndex; - } else { - if (objectOrArray && duplicate && !state.usedDuplicates[duplicateIndex]) { - state.usedDuplicates[duplicateIndex] = true; - } - if (type === '[object Object]') { - if (block && (Object.keys(state.dump).length !== 0)) { - writeBlockMapping(state, level, state.dump, compact); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + state.dump; - } - } else { - writeFlowMapping(state, level, state.dump); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; - } - } - } else if (type === '[object Array]') { - if (block && (state.dump.length !== 0)) { - if (state.noArrayIndent && !isblockseq && level > 0) { - writeBlockSequence(state, level - 1, state.dump, compact); - } else { - writeBlockSequence(state, level, state.dump, compact); - } - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + state.dump; - } - } else { - writeFlowSequence(state, level, state.dump); - if (duplicate) { - state.dump = '&ref_' + duplicateIndex + ' ' + state.dump; - } - } - } else if (type === '[object String]') { - if (state.tag !== '?') { - writeScalar(state, state.dump, level, iskey, inblock); - } - } else if (type === '[object Undefined]') { - return false; - } else { - if (state.skipInvalid) return false; - throw new exception('unacceptable kind of an object to dump ' + type); - } - - if (state.tag !== null && state.tag !== '?') { - // Need to encode all characters except those allowed by the spec: - // - // [35] ns-dec-digit ::= [#x30-#x39] /* 0-9 */ - // [36] ns-hex-digit ::= ns-dec-digit - // | [#x41-#x46] /* A-F */ | [#x61-#x66] /* a-f */ - // [37] ns-ascii-letter ::= [#x41-#x5A] /* A-Z */ | [#x61-#x7A] /* a-z */ - // [38] ns-word-char ::= ns-dec-digit | ns-ascii-letter | “-” - // [39] ns-uri-char ::= “%” ns-hex-digit ns-hex-digit | ns-word-char | “#” - // | “;” | “/” | “?” | “:” | “@” | “&” | “=” | “+” | “$” | “,” - // | “_” | “.” | “!” | “~” | “*” | “'” | “(” | “)” | “[” | “]” - // - // Also need to encode '!' because it has special meaning (end of tag prefix). - // - tagStr = encodeURI( - state.tag[0] === '!' ? state.tag.slice(1) : state.tag - ).replace(/!/g, '%21'); - - if (state.tag[0] === '!') { - tagStr = '!' + tagStr; - } else if (tagStr.slice(0, 18) === 'tag:yaml.org,2002:') { - tagStr = '!!' + tagStr.slice(18); - } else { - tagStr = '!<' + tagStr + '>'; - } - - state.dump = tagStr + ' ' + state.dump; - } - } - - return true; -} - -function getDuplicateReferences(object, state) { - var objects = [], - duplicatesIndexes = [], - index, - length; - - inspectNode(object, objects, duplicatesIndexes); - - for (index = 0, length = duplicatesIndexes.length; index < length; index += 1) { - state.duplicates.push(objects[duplicatesIndexes[index]]); - } - state.usedDuplicates = new Array(length); -} - -function inspectNode(object, objects, duplicatesIndexes) { - var objectKeyList, - index, - length; - - if (object !== null && typeof object === 'object') { - index = objects.indexOf(object); - if (index !== -1) { - if (duplicatesIndexes.indexOf(index) === -1) { - duplicatesIndexes.push(index); - } - } else { - objects.push(object); - - if (Array.isArray(object)) { - for (index = 0, length = object.length; index < length; index += 1) { - inspectNode(object[index], objects, duplicatesIndexes); - } - } else { - objectKeyList = Object.keys(object); - - for (index = 0, length = objectKeyList.length; index < length; index += 1) { - inspectNode(object[objectKeyList[index]], objects, duplicatesIndexes); - } - } - } - } -} - -function dump$1(input, options) { - options = options || {}; - - var state = new State(options); - - if (!state.noRefs) getDuplicateReferences(input, state); - - var value = input; - - if (state.replacer) { - value = state.replacer.call({ '': value }, '', value); - } - - if (writeNode(state, 0, value, true, true)) return state.dump + '\n'; - - return ''; -} - -var dump_1 = dump$1; - -var dumper = { - dump: dump_1 -}; - -function renamed(from, to) { - return function () { - throw new Error('Function yaml.' + from + ' is removed in js-yaml 4. ' + - 'Use yaml.' + to + ' instead, which is now safe by default.'); - }; -} - - -var Type = type$1; -var Schema = schema$1; -var FAILSAFE_SCHEMA = failsafe; -var JSON_SCHEMA = json; -var CORE_SCHEMA = core; -var DEFAULT_SCHEMA = _default$1; -var load = loader.load; -var loadAll = loader.loadAll; -var dump = dumper.dump; -var YAMLException = exception; - -// Re-export all types in case user wants to create custom schema -var types$1 = { - binary: binary, - float: float, - map: map$3, - null: _null, - pairs: pairs, - set: set, - timestamp: timestamp, - bool: bool, - int: int, - merge: merge$1, - omap: omap, - seq: seq, - str: str -}; - -// Removed functions from JS-YAML 3.0.x -var safeLoad = renamed('safeLoad', 'load'); -var safeLoadAll = renamed('safeLoadAll', 'loadAll'); -var safeDump = renamed('safeDump', 'dump'); - -var jsYaml = { - Type: Type, - Schema: Schema, - FAILSAFE_SCHEMA: FAILSAFE_SCHEMA, - JSON_SCHEMA: JSON_SCHEMA, - CORE_SCHEMA: CORE_SCHEMA, - DEFAULT_SCHEMA: DEFAULT_SCHEMA, - load: load, - loadAll: loadAll, - dump: dump, - YAMLException: YAMLException, - types: types$1, - safeLoad: safeLoad, - safeLoadAll: safeLoadAll, - safeDump: safeDump -}; - -var isArrayish$2 = function isArrayish(obj) { - if (!obj) { - return false; - } - - return obj instanceof Array || Array.isArray(obj) || - (obj.length >= 0 && obj.splice instanceof Function); -}; - -var util$2 = require$$0$4; -var isArrayish$1 = isArrayish$2; - -var errorEx$1 = function errorEx(name, properties) { - if (!name || name.constructor !== String) { - properties = name || {}; - name = Error.name; - } - - var errorExError = function ErrorEXError(message) { - if (!this) { - return new ErrorEXError(message); - } - - message = message instanceof Error - ? message.message - : (message || this.message); - - Error.call(this, message); - Error.captureStackTrace(this, errorExError); - - this.name = name; - - Object.defineProperty(this, 'message', { - configurable: true, - enumerable: false, - get: function () { - var newMessage = message.split(/\r?\n/g); - - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } - - var modifier = properties[key]; - - if ('message' in modifier) { - newMessage = modifier.message(this[key], newMessage) || newMessage; - if (!isArrayish$1(newMessage)) { - newMessage = [newMessage]; - } - } - } - - return newMessage.join('\n'); - }, - set: function (v) { - message = v; - } - }); - - var overwrittenStack = null; - - var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack'); - var stackGetter = stackDescriptor.get; - var stackValue = stackDescriptor.value; - delete stackDescriptor.value; - delete stackDescriptor.writable; - - stackDescriptor.set = function (newstack) { - overwrittenStack = newstack; - }; - - stackDescriptor.get = function () { - var stack = (overwrittenStack || ((stackGetter) - ? stackGetter.call(this) - : stackValue)).split(/\r?\n+/g); - - // starting in Node 7, the stack builder caches the message. - // just replace it. - if (!overwrittenStack) { - stack[0] = this.name + ': ' + this.message; - } - - var lineCount = 1; - for (var key in properties) { - if (!properties.hasOwnProperty(key)) { - continue; - } - - var modifier = properties[key]; - - if ('line' in modifier) { - var line = modifier.line(this[key]); - if (line) { - stack.splice(lineCount++, 0, ' ' + line); - } - } - - if ('stack' in modifier) { - modifier.stack(this[key], stack); - } - } - - return stack.join('\n'); - }; - - Object.defineProperty(this, 'stack', stackDescriptor); - }; - - if (Object.setPrototypeOf) { - Object.setPrototypeOf(errorExError.prototype, Error.prototype); - Object.setPrototypeOf(errorExError, Error); - } else { - util$2.inherits(errorExError, Error); - } - - return errorExError; -}; - -errorEx$1.append = function (str, def) { - return { - message: function (v, message) { - v = v || def; - - if (v) { - message[0] += ' ' + str.replace('%s', v.toString()); - } - - return message; - } - }; -}; - -errorEx$1.line = function (str, def) { - return { - line: function (v) { - v = v || def; - - if (v) { - return str.replace('%s', v.toString()); - } - - return null; - } - }; -}; - -var errorEx_1 = errorEx$1; - -const hexify = char => { - const h = char.charCodeAt(0).toString(16).toUpperCase(); - return '0x' + (h.length % 2 ? '0' : '') + h -}; - -const parseError = (e, txt, context) => { - if (!txt) { - return { - message: e.message + ' while parsing empty string', - position: 0, - } - } - const badToken = e.message.match(/^Unexpected token (.) .*position\s+(\d+)/i); - const errIdx = badToken ? +badToken[2] - : e.message.match(/^Unexpected end of JSON.*/i) ? txt.length - 1 - : null; - - const msg = badToken ? e.message.replace(/^Unexpected token ./, `Unexpected token ${ - JSON.stringify(badToken[1]) - } (${hexify(badToken[1])})`) - : e.message; - - if (errIdx !== null && errIdx !== undefined) { - const start = errIdx <= context ? 0 - : errIdx - context; - - const end = errIdx + context >= txt.length ? txt.length - : errIdx + context; - - const slice = (start === 0 ? '' : '...') + - txt.slice(start, end) + - (end === txt.length ? '' : '...'); - - const near = txt === slice ? '' : 'near '; - - return { - message: msg + ` while parsing ${near}${JSON.stringify(slice)}`, - position: errIdx, - } - } else { - return { - message: msg + ` while parsing '${txt.slice(0, context * 2)}'`, - position: 0, - } - } -}; - -class JSONParseError extends SyntaxError { - constructor (er, txt, context, caller) { - context = context || 20; - const metadata = parseError(er, txt, context); - super(metadata.message); - Object.assign(this, metadata); - this.code = 'EJSONPARSE'; - this.systemError = er; - Error.captureStackTrace(this, caller || this.constructor); - } - get name () { return this.constructor.name } - set name (n) {} - get [Symbol.toStringTag] () { return this.constructor.name } -} - -const kIndent = Symbol.for('indent'); -const kNewline = Symbol.for('newline'); -// only respect indentation if we got a line break, otherwise squash it -// things other than objects and arrays aren't indented, so ignore those -// Important: in both of these regexps, the $1 capture group is the newline -// or undefined, and the $2 capture group is the indent, or undefined. -const formatRE = /^\s*[{\[]((?:\r?\n)+)([\s\t]*)/; -const emptyRE = /^(?:\{\}|\[\])((?:\r?\n)+)?$/; - -const parseJson$1 = (txt, reviver, context) => { - const parseText = stripBOM(txt); - context = context || 20; - try { - // get the indentation so that we can save it back nicely - // if the file starts with {" then we have an indent of '', ie, none - // otherwise, pick the indentation of the next line after the first \n - // If the pattern doesn't match, then it means no indentation. - // JSON.stringify ignores symbols, so this is reasonably safe. - // if the string is '{}' or '[]', then use the default 2-space indent. - const [, newline = '\n', indent = ' '] = parseText.match(emptyRE) || - parseText.match(formatRE) || - [, '', '']; - - const result = JSON.parse(parseText, reviver); - if (result && typeof result === 'object') { - result[kNewline] = newline; - result[kIndent] = indent; - } - return result - } catch (e) { - if (typeof txt !== 'string' && !Buffer.isBuffer(txt)) { - const isEmptyArray = Array.isArray(txt) && txt.length === 0; - throw Object.assign(new TypeError( - `Cannot parse ${isEmptyArray ? 'an empty array' : String(txt)}` - ), { - code: 'EJSONPARSE', - systemError: e, - }) - } - - throw new JSONParseError(e, parseText, context, parseJson$1) - } -}; - -// Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) -// because the buffer-to-string conversion in `fs.readFileSync()` -// translates it to FEFF, the UTF-16 BOM. -const stripBOM = txt => String(txt).replace(/^\uFEFF/, ''); - -var jsonParseEvenBetterErrors = parseJson$1; -parseJson$1.JSONParseError = JSONParseError; - -parseJson$1.noExceptions = (txt, reviver) => { - try { - return JSON.parse(stripBOM(txt), reviver) - } catch (e) {} -}; - -var LF = '\n'; -var CR = '\r'; -var LinesAndColumns$1 = (function () { - function LinesAndColumns(string) { - this.string = string; - var offsets = [0]; - for (var offset = 0; offset < string.length;) { - switch (string[offset]) { - case LF: - offset += LF.length; - offsets.push(offset); - break; - case CR: - offset += CR.length; - if (string[offset] === LF) { - offset += LF.length; - } - offsets.push(offset); - break; - default: - offset++; - break; - } - } - this.offsets = offsets; - } - LinesAndColumns.prototype.locationForIndex = function (index) { - if (index < 0 || index > this.string.length) { - return null; - } - var line = 0; - var offsets = this.offsets; - while (offsets[line + 1] <= index) { - line++; - } - var column = index - offsets[line]; - return { line: line, column: column }; - }; - LinesAndColumns.prototype.indexForLocation = function (location) { - var line = location.line, column = location.column; - if (line < 0 || line >= this.offsets.length) { - return null; - } - if (column < 0 || column > this.lengthOfLine(line)) { - return null; - } - return this.offsets[line] + column; - }; - LinesAndColumns.prototype.lengthOfLine = function (line) { - var offset = this.offsets[line]; - var nextOffset = line === this.offsets.length - 1 ? this.string.length : this.offsets[line + 1]; - return nextOffset - offset; - }; - return LinesAndColumns; -}()); - -var dist = /*#__PURE__*/Object.freeze({ - __proto__: null, - 'default': LinesAndColumns$1 -}); - -var require$$2 = /*@__PURE__*/getAugmentedNamespace(dist); - -var lib$4 = {}; - -var lib$3 = {}; - -var jsTokens = {}; - -// Copyright 2014, 2015, 2016, 2017, 2018 Simon Lydell -// License: MIT. (See LICENSE.) - -Object.defineProperty(jsTokens, "__esModule", { - value: true -}); - -// This regex comes from regex.coffee, and is inserted here by generate-index.js -// (run `npm run build`). -jsTokens.default = /((['"])(?:(?!\2|\\).|\\(?:\r\n|[\s\S]))*(\2)?|`(?:[^`\\$]|\\[\s\S]|\$(?!\{)|\$\{(?:[^{}]|\{[^}]*\}?)*\}?)*(`)?)|(\/\/.*)|(\/\*(?:[^*]|\*(?!\/))*(\*\/)?)|(\/(?!\*)(?:\[(?:(?![\]\\]).|\\.)*\]|(?![\/\]\\]).|\\.)+\/(?:(?!\s*(?:\b|[\u0080-\uFFFF$\\'"~({]|[+\-!](?!=)|\.?\d))|[gmiyus]{1,6}\b(?![\u0080-\uFFFF$\\]|\s*(?:[+\-*%&|^<>!=?({]|\/(?![\/*])))))|(0[xX][\da-fA-F]+|0[oO][0-7]+|0[bB][01]+|(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?)|((?!\d)(?:(?!\s)[$\w\u0080-\uFFFF]|\\u[\da-fA-F]{4}|\\u\{[\da-fA-F]+\})+)|(--|\+\+|&&|\|\||=>|\.{3}|(?:[+\-\/%&|^]|\*{1,2}|<{1,2}|>{1,3}|!=?|={1,2})=?|[?~.,:;[\](){}])|(\s+)|(^$|[\s\S])/g; - -jsTokens.matchToToken = function(match) { - var token = {type: "invalid", value: match[0], closed: undefined}; - if (match[ 1]) token.type = "string" , token.closed = !!(match[3] || match[4]); - else if (match[ 5]) token.type = "comment"; - else if (match[ 6]) token.type = "comment", token.closed = !!match[7]; - else if (match[ 8]) token.type = "regex"; - else if (match[ 9]) token.type = "number"; - else if (match[10]) token.type = "name"; - else if (match[11]) token.type = "punctuator"; - else if (match[12]) token.type = "whitespace"; - return token -}; - -var lib$2 = {}; - -var identifier = {}; - -Object.defineProperty(identifier, "__esModule", { - value: true -}); -identifier.isIdentifierStart = isIdentifierStart; -identifier.isIdentifierChar = isIdentifierChar; -identifier.isIdentifierName = isIdentifierName; -let nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08c7\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d04-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e86-\u0e8a\u0e8c-\u0ea3\u0ea5\u0ea7-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf3\u1cf5\u1cf6\u1cfa\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31bf\u31f0-\u31ff\u3400-\u4dbf\u4e00-\u9ffc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7bf\ua7c2-\ua7ca\ua7f5-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab69\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc"; -let nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b55-\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d81-\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1abf\u1ac0\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua82c\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f"; -const nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]"); -const nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]"); -nonASCIIidentifierStartChars = nonASCIIidentifierChars = null; -const astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 14, 29, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 19, 35, 5, 35, 5, 39, 9, 51, 157, 310, 10, 21, 11, 7, 153, 5, 3, 0, 2, 43, 2, 1, 4, 0, 3, 22, 11, 22, 10, 30, 66, 18, 2, 1, 11, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 28, 43, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 56, 50, 14, 50, 14, 35, 349, 41, 7, 1, 79, 28, 11, 0, 9, 21, 107, 20, 28, 22, 13, 52, 76, 44, 33, 24, 27, 35, 30, 0, 3, 0, 9, 34, 4, 0, 13, 47, 15, 3, 22, 0, 2, 0, 36, 17, 2, 24, 85, 6, 2, 0, 2, 3, 2, 14, 2, 9, 8, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 19, 0, 13, 4, 159, 52, 19, 3, 21, 2, 31, 47, 21, 1, 2, 0, 185, 46, 42, 3, 37, 47, 21, 0, 60, 42, 14, 0, 72, 26, 230, 43, 117, 63, 32, 7, 3, 0, 3, 7, 2, 1, 2, 23, 16, 0, 2, 0, 95, 7, 3, 38, 17, 0, 2, 0, 29, 0, 11, 39, 8, 0, 22, 0, 12, 45, 20, 0, 35, 56, 264, 8, 2, 36, 18, 0, 50, 29, 113, 6, 2, 1, 2, 37, 22, 0, 26, 5, 2, 1, 2, 31, 15, 0, 328, 18, 190, 0, 80, 921, 103, 110, 18, 195, 2749, 1070, 4050, 582, 8634, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 689, 63, 129, 74, 6, 0, 67, 12, 65, 1, 2, 0, 29, 6135, 9, 1237, 43, 8, 8952, 286, 50, 2, 18, 3, 9, 395, 2309, 106, 6, 12, 4, 8, 8, 9, 5991, 84, 2, 70, 2, 1, 3, 0, 3, 1, 3, 3, 2, 11, 2, 0, 2, 6, 2, 64, 2, 3, 3, 7, 2, 6, 2, 27, 2, 3, 2, 4, 2, 0, 4, 6, 2, 339, 3, 24, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 30, 2, 24, 2, 7, 2357, 44, 11, 6, 17, 0, 370, 43, 1301, 196, 60, 67, 8, 0, 1205, 3, 2, 26, 2, 1, 2, 0, 3, 0, 2, 9, 2, 3, 2, 0, 2, 0, 7, 0, 5, 0, 2, 0, 2, 0, 2, 2, 2, 1, 2, 0, 3, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 1, 2, 0, 3, 3, 2, 6, 2, 3, 2, 3, 2, 0, 2, 9, 2, 16, 6, 2, 2, 4, 2, 16, 4421, 42717, 35, 4148, 12, 221, 3, 5761, 15, 7472, 3104, 541, 1507, 4938]; -const astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 574, 3, 9, 9, 370, 1, 154, 10, 176, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 6, 1, 45, 0, 13, 2, 49, 13, 9, 3, 2, 11, 83, 11, 7, 0, 161, 11, 6, 9, 7, 3, 56, 1, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 193, 17, 10, 9, 5, 0, 82, 19, 13, 9, 214, 6, 3, 8, 28, 1, 83, 16, 16, 9, 82, 12, 9, 9, 84, 14, 5, 9, 243, 14, 166, 9, 71, 5, 2, 1, 3, 3, 2, 0, 2, 1, 13, 9, 120, 6, 3, 6, 4, 0, 29, 9, 41, 6, 2, 3, 9, 0, 10, 10, 47, 15, 406, 7, 2, 7, 17, 9, 57, 21, 2, 13, 123, 5, 4, 0, 2, 1, 2, 6, 2, 0, 9, 9, 49, 4, 2, 1, 2, 4, 9, 9, 330, 3, 19306, 9, 135, 4, 60, 6, 26, 9, 1014, 0, 2, 54, 8, 3, 82, 0, 12, 1, 19628, 1, 5319, 4, 4, 5, 9, 7, 3, 6, 31, 3, 149, 2, 1418, 49, 513, 54, 5, 49, 9, 0, 15, 0, 23, 4, 2, 14, 1361, 6, 2, 16, 3, 6, 2, 1, 2, 4, 262, 6, 10, 9, 419, 13, 1495, 6, 110, 6, 6, 9, 4759, 9, 787719, 239]; - -function isInAstralSet(code, set) { - let pos = 0x10000; - - for (let i = 0, length = set.length; i < length; i += 2) { - pos += set[i]; - if (pos > code) return false; - pos += set[i + 1]; - if (pos >= code) return true; - } - - return false; -} - -function isIdentifierStart(code) { - if (code < 65) return code === 36; - if (code <= 90) return true; - if (code < 97) return code === 95; - if (code <= 122) return true; - - if (code <= 0xffff) { - return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)); - } - - return isInAstralSet(code, astralIdentifierStartCodes); -} - -function isIdentifierChar(code) { - if (code < 48) return code === 36; - if (code < 58) return true; - if (code < 65) return false; - if (code <= 90) return true; - if (code < 97) return code === 95; - if (code <= 122) return true; - - if (code <= 0xffff) { - return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)); - } - - return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes); -} - -function isIdentifierName(name) { - let isFirst = true; - - for (let i = 0; i < name.length; i++) { - let cp = name.charCodeAt(i); - - if ((cp & 0xfc00) === 0xd800 && i + 1 < name.length) { - const trail = name.charCodeAt(++i); - - if ((trail & 0xfc00) === 0xdc00) { - cp = 0x10000 + ((cp & 0x3ff) << 10) + (trail & 0x3ff); - } - } - - if (isFirst) { - isFirst = false; - - if (!isIdentifierStart(cp)) { - return false; - } - } else if (!isIdentifierChar(cp)) { - return false; - } - } - - return !isFirst; -} - -var keyword = {}; - -Object.defineProperty(keyword, "__esModule", { - value: true -}); -keyword.isReservedWord = isReservedWord; -keyword.isStrictReservedWord = isStrictReservedWord; -keyword.isStrictBindOnlyReservedWord = isStrictBindOnlyReservedWord; -keyword.isStrictBindReservedWord = isStrictBindReservedWord; -keyword.isKeyword = isKeyword; -const reservedWords = { - keyword: ["break", "case", "catch", "continue", "debugger", "default", "do", "else", "finally", "for", "function", "if", "return", "switch", "throw", "try", "var", "const", "while", "with", "new", "this", "super", "class", "extends", "export", "import", "null", "true", "false", "in", "instanceof", "typeof", "void", "delete"], - strict: ["implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"], - strictBind: ["eval", "arguments"] -}; -const keywords$1 = new Set(reservedWords.keyword); -const reservedWordsStrictSet = new Set(reservedWords.strict); -const reservedWordsStrictBindSet = new Set(reservedWords.strictBind); - -function isReservedWord(word, inModule) { - return inModule && word === "await" || word === "enum"; -} - -function isStrictReservedWord(word, inModule) { - return isReservedWord(word, inModule) || reservedWordsStrictSet.has(word); -} - -function isStrictBindOnlyReservedWord(word) { - return reservedWordsStrictBindSet.has(word); -} - -function isStrictBindReservedWord(word, inModule) { - return isStrictReservedWord(word, inModule) || isStrictBindOnlyReservedWord(word); -} - -function isKeyword(word) { - return keywords$1.has(word); -} - -(function (exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -Object.defineProperty(exports, "isIdentifierName", { - enumerable: true, - get: function () { - return _identifier.isIdentifierName; - } -}); -Object.defineProperty(exports, "isIdentifierChar", { - enumerable: true, - get: function () { - return _identifier.isIdentifierChar; - } -}); -Object.defineProperty(exports, "isIdentifierStart", { - enumerable: true, - get: function () { - return _identifier.isIdentifierStart; - } -}); -Object.defineProperty(exports, "isReservedWord", { - enumerable: true, - get: function () { - return _keyword.isReservedWord; - } -}); -Object.defineProperty(exports, "isStrictBindOnlyReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictBindOnlyReservedWord; - } -}); -Object.defineProperty(exports, "isStrictBindReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictBindReservedWord; - } -}); -Object.defineProperty(exports, "isStrictReservedWord", { - enumerable: true, - get: function () { - return _keyword.isStrictReservedWord; - } -}); -Object.defineProperty(exports, "isKeyword", { - enumerable: true, - get: function () { - return _keyword.isKeyword; - } -}); - -var _identifier = identifier; - -var _keyword = keyword; -}(lib$2)); - -var chalk = {exports: {}}; - -var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - -var escapeStringRegexp$1 = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); - } - - return str.replace(matchOperatorsRe, '\\$&'); -}; - -var ansiStyles = {exports: {}}; - -var conversions$2 = {exports: {}}; - -var colorName = { - "aliceblue": [240, 248, 255], - "antiquewhite": [250, 235, 215], - "aqua": [0, 255, 255], - "aquamarine": [127, 255, 212], - "azure": [240, 255, 255], - "beige": [245, 245, 220], - "bisque": [255, 228, 196], - "black": [0, 0, 0], - "blanchedalmond": [255, 235, 205], - "blue": [0, 0, 255], - "blueviolet": [138, 43, 226], - "brown": [165, 42, 42], - "burlywood": [222, 184, 135], - "cadetblue": [95, 158, 160], - "chartreuse": [127, 255, 0], - "chocolate": [210, 105, 30], - "coral": [255, 127, 80], - "cornflowerblue": [100, 149, 237], - "cornsilk": [255, 248, 220], - "crimson": [220, 20, 60], - "cyan": [0, 255, 255], - "darkblue": [0, 0, 139], - "darkcyan": [0, 139, 139], - "darkgoldenrod": [184, 134, 11], - "darkgray": [169, 169, 169], - "darkgreen": [0, 100, 0], - "darkgrey": [169, 169, 169], - "darkkhaki": [189, 183, 107], - "darkmagenta": [139, 0, 139], - "darkolivegreen": [85, 107, 47], - "darkorange": [255, 140, 0], - "darkorchid": [153, 50, 204], - "darkred": [139, 0, 0], - "darksalmon": [233, 150, 122], - "darkseagreen": [143, 188, 143], - "darkslateblue": [72, 61, 139], - "darkslategray": [47, 79, 79], - "darkslategrey": [47, 79, 79], - "darkturquoise": [0, 206, 209], - "darkviolet": [148, 0, 211], - "deeppink": [255, 20, 147], - "deepskyblue": [0, 191, 255], - "dimgray": [105, 105, 105], - "dimgrey": [105, 105, 105], - "dodgerblue": [30, 144, 255], - "firebrick": [178, 34, 34], - "floralwhite": [255, 250, 240], - "forestgreen": [34, 139, 34], - "fuchsia": [255, 0, 255], - "gainsboro": [220, 220, 220], - "ghostwhite": [248, 248, 255], - "gold": [255, 215, 0], - "goldenrod": [218, 165, 32], - "gray": [128, 128, 128], - "green": [0, 128, 0], - "greenyellow": [173, 255, 47], - "grey": [128, 128, 128], - "honeydew": [240, 255, 240], - "hotpink": [255, 105, 180], - "indianred": [205, 92, 92], - "indigo": [75, 0, 130], - "ivory": [255, 255, 240], - "khaki": [240, 230, 140], - "lavender": [230, 230, 250], - "lavenderblush": [255, 240, 245], - "lawngreen": [124, 252, 0], - "lemonchiffon": [255, 250, 205], - "lightblue": [173, 216, 230], - "lightcoral": [240, 128, 128], - "lightcyan": [224, 255, 255], - "lightgoldenrodyellow": [250, 250, 210], - "lightgray": [211, 211, 211], - "lightgreen": [144, 238, 144], - "lightgrey": [211, 211, 211], - "lightpink": [255, 182, 193], - "lightsalmon": [255, 160, 122], - "lightseagreen": [32, 178, 170], - "lightskyblue": [135, 206, 250], - "lightslategray": [119, 136, 153], - "lightslategrey": [119, 136, 153], - "lightsteelblue": [176, 196, 222], - "lightyellow": [255, 255, 224], - "lime": [0, 255, 0], - "limegreen": [50, 205, 50], - "linen": [250, 240, 230], - "magenta": [255, 0, 255], - "maroon": [128, 0, 0], - "mediumaquamarine": [102, 205, 170], - "mediumblue": [0, 0, 205], - "mediumorchid": [186, 85, 211], - "mediumpurple": [147, 112, 219], - "mediumseagreen": [60, 179, 113], - "mediumslateblue": [123, 104, 238], - "mediumspringgreen": [0, 250, 154], - "mediumturquoise": [72, 209, 204], - "mediumvioletred": [199, 21, 133], - "midnightblue": [25, 25, 112], - "mintcream": [245, 255, 250], - "mistyrose": [255, 228, 225], - "moccasin": [255, 228, 181], - "navajowhite": [255, 222, 173], - "navy": [0, 0, 128], - "oldlace": [253, 245, 230], - "olive": [128, 128, 0], - "olivedrab": [107, 142, 35], - "orange": [255, 165, 0], - "orangered": [255, 69, 0], - "orchid": [218, 112, 214], - "palegoldenrod": [238, 232, 170], - "palegreen": [152, 251, 152], - "paleturquoise": [175, 238, 238], - "palevioletred": [219, 112, 147], - "papayawhip": [255, 239, 213], - "peachpuff": [255, 218, 185], - "peru": [205, 133, 63], - "pink": [255, 192, 203], - "plum": [221, 160, 221], - "powderblue": [176, 224, 230], - "purple": [128, 0, 128], - "rebeccapurple": [102, 51, 153], - "red": [255, 0, 0], - "rosybrown": [188, 143, 143], - "royalblue": [65, 105, 225], - "saddlebrown": [139, 69, 19], - "salmon": [250, 128, 114], - "sandybrown": [244, 164, 96], - "seagreen": [46, 139, 87], - "seashell": [255, 245, 238], - "sienna": [160, 82, 45], - "silver": [192, 192, 192], - "skyblue": [135, 206, 235], - "slateblue": [106, 90, 205], - "slategray": [112, 128, 144], - "slategrey": [112, 128, 144], - "snow": [255, 250, 250], - "springgreen": [0, 255, 127], - "steelblue": [70, 130, 180], - "tan": [210, 180, 140], - "teal": [0, 128, 128], - "thistle": [216, 191, 216], - "tomato": [255, 99, 71], - "turquoise": [64, 224, 208], - "violet": [238, 130, 238], - "wheat": [245, 222, 179], - "white": [255, 255, 255], - "whitesmoke": [245, 245, 245], - "yellow": [255, 255, 0], - "yellowgreen": [154, 205, 50] -}; - -/* MIT license */ - -var cssKeywords = colorName; - -// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) - -var reverseKeywords = {}; -for (var key$1 in cssKeywords) { - if (cssKeywords.hasOwnProperty(key$1)) { - reverseKeywords[cssKeywords[key$1]] = key$1; - } -} - -var convert$2 = conversions$2.exports = { - rgb: {channels: 3, labels: 'rgb'}, - hsl: {channels: 3, labels: 'hsl'}, - hsv: {channels: 3, labels: 'hsv'}, - hwb: {channels: 3, labels: 'hwb'}, - cmyk: {channels: 4, labels: 'cmyk'}, - xyz: {channels: 3, labels: 'xyz'}, - lab: {channels: 3, labels: 'lab'}, - lch: {channels: 3, labels: 'lch'}, - hex: {channels: 1, labels: ['hex']}, - keyword: {channels: 1, labels: ['keyword']}, - ansi16: {channels: 1, labels: ['ansi16']}, - ansi256: {channels: 1, labels: ['ansi256']}, - hcg: {channels: 3, labels: ['h', 'c', 'g']}, - apple: {channels: 3, labels: ['r16', 'g16', 'b16']}, - gray: {channels: 1, labels: ['gray']} -}; - -// hide .channels and .labels properties -for (var model in convert$2) { - if (convert$2.hasOwnProperty(model)) { - if (!('channels' in convert$2[model])) { - throw new Error('missing channels property: ' + model); - } - - if (!('labels' in convert$2[model])) { - throw new Error('missing channel labels property: ' + model); - } - - if (convert$2[model].labels.length !== convert$2[model].channels) { - throw new Error('channel and label counts mismatch: ' + model); - } - - var channels = convert$2[model].channels; - var labels$1 = convert$2[model].labels; - delete convert$2[model].channels; - delete convert$2[model].labels; - Object.defineProperty(convert$2[model], 'channels', {value: channels}); - Object.defineProperty(convert$2[model], 'labels', {value: labels$1}); - } -} - -convert$2.rgb.hsl = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var min = Math.min(r, g, b); - var max = Math.max(r, g, b); - var delta = max - min; - var h; - var s; - var l; - - if (max === min) { - h = 0; - } else if (r === max) { - h = (g - b) / delta; - } else if (g === max) { - h = 2 + (b - r) / delta; - } else if (b === max) { - h = 4 + (r - g) / delta; - } - - h = Math.min(h * 60, 360); - - if (h < 0) { - h += 360; - } - - l = (min + max) / 2; - - if (max === min) { - s = 0; - } else if (l <= 0.5) { - s = delta / (max + min); - } else { - s = delta / (2 - max - min); - } - - return [h, s * 100, l * 100]; -}; - -convert$2.rgb.hsv = function (rgb) { - var rdif; - var gdif; - var bdif; - var h; - var s; - - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var v = Math.max(r, g, b); - var diff = v - Math.min(r, g, b); - var diffc = function (c) { - return (v - c) / 6 / diff + 1 / 2; - }; - - if (diff === 0) { - h = s = 0; - } else { - s = diff / v; - rdif = diffc(r); - gdif = diffc(g); - bdif = diffc(b); - - if (r === v) { - h = bdif - gdif; - } else if (g === v) { - h = (1 / 3) + rdif - bdif; - } else if (b === v) { - h = (2 / 3) + gdif - rdif; - } - if (h < 0) { - h += 1; - } else if (h > 1) { - h -= 1; - } - } - - return [ - h * 360, - s * 100, - v * 100 - ]; -}; - -convert$2.rgb.hwb = function (rgb) { - var r = rgb[0]; - var g = rgb[1]; - var b = rgb[2]; - var h = convert$2.rgb.hsl(rgb)[0]; - var w = 1 / 255 * Math.min(r, Math.min(g, b)); - - b = 1 - 1 / 255 * Math.max(r, Math.max(g, b)); - - return [h, w * 100, b * 100]; -}; - -convert$2.rgb.cmyk = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var c; - var m; - var y; - var k; - - k = Math.min(1 - r, 1 - g, 1 - b); - c = (1 - r - k) / (1 - k) || 0; - m = (1 - g - k) / (1 - k) || 0; - y = (1 - b - k) / (1 - k) || 0; - - return [c * 100, m * 100, y * 100, k * 100]; -}; - -/** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */ -function comparativeDistance(x, y) { - return ( - Math.pow(x[0] - y[0], 2) + - Math.pow(x[1] - y[1], 2) + - Math.pow(x[2] - y[2], 2) - ); -} - -convert$2.rgb.keyword = function (rgb) { - var reversed = reverseKeywords[rgb]; - if (reversed) { - return reversed; - } - - var currentClosestDistance = Infinity; - var currentClosestKeyword; - - for (var keyword in cssKeywords) { - if (cssKeywords.hasOwnProperty(keyword)) { - var value = cssKeywords[keyword]; - - // Compute comparative distance - var distance = comparativeDistance(rgb, value); - - // Check if its less, if so set as closest - if (distance < currentClosestDistance) { - currentClosestDistance = distance; - currentClosestKeyword = keyword; - } - } - } - - return currentClosestKeyword; -}; - -convert$2.keyword.rgb = function (keyword) { - return cssKeywords[keyword]; -}; - -convert$2.rgb.xyz = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - - // assume sRGB - r = r > 0.04045 ? Math.pow(((r + 0.055) / 1.055), 2.4) : (r / 12.92); - g = g > 0.04045 ? Math.pow(((g + 0.055) / 1.055), 2.4) : (g / 12.92); - b = b > 0.04045 ? Math.pow(((b + 0.055) / 1.055), 2.4) : (b / 12.92); - - var x = (r * 0.4124) + (g * 0.3576) + (b * 0.1805); - var y = (r * 0.2126) + (g * 0.7152) + (b * 0.0722); - var z = (r * 0.0193) + (g * 0.1192) + (b * 0.9505); - - return [x * 100, y * 100, z * 100]; -}; - -convert$2.rgb.lab = function (rgb) { - var xyz = convert$2.rgb.xyz(rgb); - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$2.hsl.rgb = function (hsl) { - var h = hsl[0] / 360; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var t1; - var t2; - var t3; - var rgb; - var val; - - if (s === 0) { - val = l * 255; - return [val, val, val]; - } - - if (l < 0.5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - - t1 = 2 * l - t2; - - rgb = [0, 0, 0]; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - if (t3 < 0) { - t3++; - } - if (t3 > 1) { - t3--; - } - - if (6 * t3 < 1) { - val = t1 + (t2 - t1) * 6 * t3; - } else if (2 * t3 < 1) { - val = t2; - } else if (3 * t3 < 2) { - val = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - val = t1; - } - - rgb[i] = val * 255; - } - - return rgb; -}; - -convert$2.hsl.hsv = function (hsl) { - var h = hsl[0]; - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var smin = s; - var lmin = Math.max(l, 0.01); - var sv; - var v; - - l *= 2; - s *= (l <= 1) ? l : 2 - l; - smin *= lmin <= 1 ? lmin : 2 - lmin; - v = (l + s) / 2; - sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s); - - return [h, sv * 100, v * 100]; -}; - -convert$2.hsv.rgb = function (hsv) { - var h = hsv[0] / 60; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var hi = Math.floor(h) % 6; - - var f = h - Math.floor(h); - var p = 255 * v * (1 - s); - var q = 255 * v * (1 - (s * f)); - var t = 255 * v * (1 - (s * (1 - f))); - v *= 255; - - switch (hi) { - case 0: - return [v, t, p]; - case 1: - return [q, v, p]; - case 2: - return [p, v, t]; - case 3: - return [p, q, v]; - case 4: - return [t, p, v]; - case 5: - return [v, p, q]; - } -}; - -convert$2.hsv.hsl = function (hsv) { - var h = hsv[0]; - var s = hsv[1] / 100; - var v = hsv[2] / 100; - var vmin = Math.max(v, 0.01); - var lmin; - var sl; - var l; - - l = (2 - s) * v; - lmin = (2 - s) * vmin; - sl = s * vmin; - sl /= (lmin <= 1) ? lmin : 2 - lmin; - sl = sl || 0; - l /= 2; - - return [h, sl * 100, l * 100]; -}; - -// http://dev.w3.org/csswg/css-color/#hwb-to-rgb -convert$2.hwb.rgb = function (hwb) { - var h = hwb[0] / 360; - var wh = hwb[1] / 100; - var bl = hwb[2] / 100; - var ratio = wh + bl; - var i; - var v; - var f; - var n; - - // wh + bl cant be > 1 - if (ratio > 1) { - wh /= ratio; - bl /= ratio; - } - - i = Math.floor(6 * h); - v = 1 - bl; - f = 6 * h - i; - - if ((i & 0x01) !== 0) { - f = 1 - f; - } - - n = wh + f * (v - wh); // linear interpolation - - var r; - var g; - var b; - switch (i) { - default: - case 6: - case 0: r = v; g = n; b = wh; break; - case 1: r = n; g = v; b = wh; break; - case 2: r = wh; g = v; b = n; break; - case 3: r = wh; g = n; b = v; break; - case 4: r = n; g = wh; b = v; break; - case 5: r = v; g = wh; b = n; break; - } - - return [r * 255, g * 255, b * 255]; -}; - -convert$2.cmyk.rgb = function (cmyk) { - var c = cmyk[0] / 100; - var m = cmyk[1] / 100; - var y = cmyk[2] / 100; - var k = cmyk[3] / 100; - var r; - var g; - var b; - - r = 1 - Math.min(1, c * (1 - k) + k); - g = 1 - Math.min(1, m * (1 - k) + k); - b = 1 - Math.min(1, y * (1 - k) + k); - - return [r * 255, g * 255, b * 255]; -}; - -convert$2.xyz.rgb = function (xyz) { - var x = xyz[0] / 100; - var y = xyz[1] / 100; - var z = xyz[2] / 100; - var r; - var g; - var b; - - r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986); - g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415); - b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570); - - // assume sRGB - r = r > 0.0031308 - ? ((1.055 * Math.pow(r, 1.0 / 2.4)) - 0.055) - : r * 12.92; - - g = g > 0.0031308 - ? ((1.055 * Math.pow(g, 1.0 / 2.4)) - 0.055) - : g * 12.92; - - b = b > 0.0031308 - ? ((1.055 * Math.pow(b, 1.0 / 2.4)) - 0.055) - : b * 12.92; - - r = Math.min(Math.max(0, r), 1); - g = Math.min(Math.max(0, g), 1); - b = Math.min(Math.max(0, b), 1); - - return [r * 255, g * 255, b * 255]; -}; - -convert$2.xyz.lab = function (xyz) { - var x = xyz[0]; - var y = xyz[1]; - var z = xyz[2]; - var l; - var a; - var b; - - x /= 95.047; - y /= 100; - z /= 108.883; - - x = x > 0.008856 ? Math.pow(x, 1 / 3) : (7.787 * x) + (16 / 116); - y = y > 0.008856 ? Math.pow(y, 1 / 3) : (7.787 * y) + (16 / 116); - z = z > 0.008856 ? Math.pow(z, 1 / 3) : (7.787 * z) + (16 / 116); - - l = (116 * y) - 16; - a = 500 * (x - y); - b = 200 * (y - z); - - return [l, a, b]; -}; - -convert$2.lab.xyz = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var x; - var y; - var z; - - y = (l + 16) / 116; - x = a / 500 + y; - z = y - b / 200; - - var y2 = Math.pow(y, 3); - var x2 = Math.pow(x, 3); - var z2 = Math.pow(z, 3); - y = y2 > 0.008856 ? y2 : (y - 16 / 116) / 7.787; - x = x2 > 0.008856 ? x2 : (x - 16 / 116) / 7.787; - z = z2 > 0.008856 ? z2 : (z - 16 / 116) / 7.787; - - x *= 95.047; - y *= 100; - z *= 108.883; - - return [x, y, z]; -}; - -convert$2.lab.lch = function (lab) { - var l = lab[0]; - var a = lab[1]; - var b = lab[2]; - var hr; - var h; - var c; - - hr = Math.atan2(b, a); - h = hr * 360 / 2 / Math.PI; - - if (h < 0) { - h += 360; - } - - c = Math.sqrt(a * a + b * b); - - return [l, c, h]; -}; - -convert$2.lch.lab = function (lch) { - var l = lch[0]; - var c = lch[1]; - var h = lch[2]; - var a; - var b; - var hr; - - hr = h / 360 * 2 * Math.PI; - a = c * Math.cos(hr); - b = c * Math.sin(hr); - - return [l, a, b]; -}; - -convert$2.rgb.ansi16 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - var value = 1 in arguments ? arguments[1] : convert$2.rgb.hsv(args)[2]; // hsv -> ansi16 optimization - - value = Math.round(value / 50); - - if (value === 0) { - return 30; - } - - var ansi = 30 - + ((Math.round(b / 255) << 2) - | (Math.round(g / 255) << 1) - | Math.round(r / 255)); - - if (value === 2) { - ansi += 60; - } - - return ansi; -}; - -convert$2.hsv.ansi16 = function (args) { - // optimization here; we already know the value and don't need to get - // it converted for us. - return convert$2.rgb.ansi16(convert$2.hsv.rgb(args), args[2]); -}; - -convert$2.rgb.ansi256 = function (args) { - var r = args[0]; - var g = args[1]; - var b = args[2]; - - // we use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (r === g && g === b) { - if (r < 8) { - return 16; - } - - if (r > 248) { - return 231; - } - - return Math.round(((r - 8) / 247) * 24) + 232; - } - - var ansi = 16 - + (36 * Math.round(r / 255 * 5)) - + (6 * Math.round(g / 255 * 5)) - + Math.round(b / 255 * 5); - - return ansi; -}; - -convert$2.ansi16.rgb = function (args) { - var color = args % 10; - - // handle greyscale - if (color === 0 || color === 7) { - if (args > 50) { - color += 3.5; - } - - color = color / 10.5 * 255; - - return [color, color, color]; - } - - var mult = (~~(args > 50) + 1) * 0.5; - var r = ((color & 1) * mult) * 255; - var g = (((color >> 1) & 1) * mult) * 255; - var b = (((color >> 2) & 1) * mult) * 255; - - return [r, g, b]; -}; - -convert$2.ansi256.rgb = function (args) { - // handle greyscale - if (args >= 232) { - var c = (args - 232) * 10 + 8; - return [c, c, c]; - } - - args -= 16; - - var rem; - var r = Math.floor(args / 36) / 5 * 255; - var g = Math.floor((rem = args % 36) / 6) / 5 * 255; - var b = (rem % 6) / 5 * 255; - - return [r, g, b]; -}; - -convert$2.rgb.hex = function (args) { - var integer = ((Math.round(args[0]) & 0xFF) << 16) - + ((Math.round(args[1]) & 0xFF) << 8) - + (Math.round(args[2]) & 0xFF); - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$2.hex.rgb = function (args) { - var match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i); - if (!match) { - return [0, 0, 0]; - } - - var colorString = match[0]; - - if (match[0].length === 3) { - colorString = colorString.split('').map(function (char) { - return char + char; - }).join(''); - } - - var integer = parseInt(colorString, 16); - var r = (integer >> 16) & 0xFF; - var g = (integer >> 8) & 0xFF; - var b = integer & 0xFF; - - return [r, g, b]; -}; - -convert$2.rgb.hcg = function (rgb) { - var r = rgb[0] / 255; - var g = rgb[1] / 255; - var b = rgb[2] / 255; - var max = Math.max(Math.max(r, g), b); - var min = Math.min(Math.min(r, g), b); - var chroma = (max - min); - var grayscale; - var hue; - - if (chroma < 1) { - grayscale = min / (1 - chroma); - } else { - grayscale = 0; - } - - if (chroma <= 0) { - hue = 0; - } else - if (max === r) { - hue = ((g - b) / chroma) % 6; - } else - if (max === g) { - hue = 2 + (b - r) / chroma; - } else { - hue = 4 + (r - g) / chroma + 4; - } - - hue /= 6; - hue %= 1; - - return [hue * 360, chroma * 100, grayscale * 100]; -}; - -convert$2.hsl.hcg = function (hsl) { - var s = hsl[1] / 100; - var l = hsl[2] / 100; - var c = 1; - var f = 0; - - if (l < 0.5) { - c = 2.0 * s * l; - } else { - c = 2.0 * s * (1.0 - l); - } - - if (c < 1.0) { - f = (l - 0.5 * c) / (1.0 - c); - } - - return [hsl[0], c * 100, f * 100]; -}; - -convert$2.hsv.hcg = function (hsv) { - var s = hsv[1] / 100; - var v = hsv[2] / 100; - - var c = s * v; - var f = 0; - - if (c < 1.0) { - f = (v - c) / (1 - c); - } - - return [hsv[0], c * 100, f * 100]; -}; - -convert$2.hcg.rgb = function (hcg) { - var h = hcg[0] / 360; - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - if (c === 0.0) { - return [g * 255, g * 255, g * 255]; - } - - var pure = [0, 0, 0]; - var hi = (h % 1) * 6; - var v = hi % 1; - var w = 1 - v; - var mg = 0; - - switch (Math.floor(hi)) { - case 0: - pure[0] = 1; pure[1] = v; pure[2] = 0; break; - case 1: - pure[0] = w; pure[1] = 1; pure[2] = 0; break; - case 2: - pure[0] = 0; pure[1] = 1; pure[2] = v; break; - case 3: - pure[0] = 0; pure[1] = w; pure[2] = 1; break; - case 4: - pure[0] = v; pure[1] = 0; pure[2] = 1; break; - default: - pure[0] = 1; pure[1] = 0; pure[2] = w; - } - - mg = (1.0 - c) * g; - - return [ - (c * pure[0] + mg) * 255, - (c * pure[1] + mg) * 255, - (c * pure[2] + mg) * 255 - ]; -}; - -convert$2.hcg.hsv = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var v = c + g * (1.0 - c); - var f = 0; - - if (v > 0.0) { - f = c / v; - } - - return [hcg[0], f * 100, v * 100]; -}; - -convert$2.hcg.hsl = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - - var l = g * (1.0 - c) + 0.5 * c; - var s = 0; - - if (l > 0.0 && l < 0.5) { - s = c / (2 * l); - } else - if (l >= 0.5 && l < 1.0) { - s = c / (2 * (1 - l)); - } - - return [hcg[0], s * 100, l * 100]; -}; - -convert$2.hcg.hwb = function (hcg) { - var c = hcg[1] / 100; - var g = hcg[2] / 100; - var v = c + g * (1.0 - c); - return [hcg[0], (v - c) * 100, (1 - v) * 100]; -}; - -convert$2.hwb.hcg = function (hwb) { - var w = hwb[1] / 100; - var b = hwb[2] / 100; - var v = 1 - b; - var c = v - w; - var g = 0; - - if (c < 1) { - g = (v - c) / (1 - c); - } - - return [hwb[0], c * 100, g * 100]; -}; - -convert$2.apple.rgb = function (apple) { - return [(apple[0] / 65535) * 255, (apple[1] / 65535) * 255, (apple[2] / 65535) * 255]; -}; - -convert$2.rgb.apple = function (rgb) { - return [(rgb[0] / 255) * 65535, (rgb[1] / 255) * 65535, (rgb[2] / 255) * 65535]; -}; - -convert$2.gray.rgb = function (args) { - return [args[0] / 100 * 255, args[0] / 100 * 255, args[0] / 100 * 255]; -}; - -convert$2.gray.hsl = convert$2.gray.hsv = function (args) { - return [0, 0, args[0]]; -}; - -convert$2.gray.hwb = function (gray) { - return [0, 100, gray[0]]; -}; - -convert$2.gray.cmyk = function (gray) { - return [0, 0, 0, gray[0]]; -}; - -convert$2.gray.lab = function (gray) { - return [gray[0], 0, 0]; -}; - -convert$2.gray.hex = function (gray) { - var val = Math.round(gray[0] / 100 * 255) & 0xFF; - var integer = (val << 16) + (val << 8) + val; - - var string = integer.toString(16).toUpperCase(); - return '000000'.substring(string.length) + string; -}; - -convert$2.rgb.gray = function (rgb) { - var val = (rgb[0] + rgb[1] + rgb[2]) / 3; - return [val / 255 * 100]; -}; - -var conversions$1 = conversions$2.exports; - -/* - this function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/ - -function buildGraph() { - var graph = {}; - // https://jsperf.com/object-keys-vs-for-in-with-closure/3 - var models = Object.keys(conversions$1); - - for (var len = models.length, i = 0; i < len; i++) { - graph[models[i]] = { - // http://jsperf.com/1-vs-infinity - // micro-opt, but this is simple. - distance: -1, - parent: null - }; - } - - return graph; -} - -// https://en.wikipedia.org/wiki/Breadth-first_search -function deriveBFS(fromModel) { - var graph = buildGraph(); - var queue = [fromModel]; // unshift -> queue -> pop - - graph[fromModel].distance = 0; - - while (queue.length) { - var current = queue.pop(); - var adjacents = Object.keys(conversions$1[current]); - - for (var len = adjacents.length, i = 0; i < len; i++) { - var adjacent = adjacents[i]; - var node = graph[adjacent]; - - if (node.distance === -1) { - node.distance = graph[current].distance + 1; - node.parent = current; - queue.unshift(adjacent); - } - } - } - - return graph; -} - -function link$1(from, to) { - return function (args) { - return to(from(args)); - }; -} - -function wrapConversion(toModel, graph) { - var path = [graph[toModel].parent, toModel]; - var fn = conversions$1[graph[toModel].parent][toModel]; - - var cur = graph[toModel].parent; - while (graph[cur].parent) { - path.unshift(graph[cur].parent); - fn = link$1(conversions$1[graph[cur].parent][cur], fn); - cur = graph[cur].parent; - } - - fn.conversion = path; - return fn; -} - -var route$1 = function (fromModel) { - var graph = deriveBFS(fromModel); - var conversion = {}; - - var models = Object.keys(graph); - for (var len = models.length, i = 0; i < len; i++) { - var toModel = models[i]; - var node = graph[toModel]; - - if (node.parent === null) { - // no possible conversion, or this node is the source model. - continue; - } - - conversion[toModel] = wrapConversion(toModel, graph); - } - - return conversion; -}; - -var conversions = conversions$2.exports; -var route = route$1; - -var convert$1 = {}; - -var models = Object.keys(conversions); - -function wrapRaw(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - return fn(args); - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -function wrapRounded(fn) { - var wrappedFn = function (args) { - if (args === undefined || args === null) { - return args; - } - - if (arguments.length > 1) { - args = Array.prototype.slice.call(arguments); - } - - var result = fn(args); - - // we're assuming the result is an array here. - // see notice in conversions.js; don't use box types - // in conversion functions. - if (typeof result === 'object') { - for (var len = result.length, i = 0; i < len; i++) { - result[i] = Math.round(result[i]); - } - } - - return result; - }; - - // preserve .conversion property if there is one - if ('conversion' in fn) { - wrappedFn.conversion = fn.conversion; - } - - return wrappedFn; -} - -models.forEach(function (fromModel) { - convert$1[fromModel] = {}; - - Object.defineProperty(convert$1[fromModel], 'channels', {value: conversions[fromModel].channels}); - Object.defineProperty(convert$1[fromModel], 'labels', {value: conversions[fromModel].labels}); - - var routes = route(fromModel); - var routeModels = Object.keys(routes); - - routeModels.forEach(function (toModel) { - var fn = routes[toModel]; - - convert$1[fromModel][toModel] = wrapRounded(fn); - convert$1[fromModel][toModel].raw = wrapRaw(fn); - }); -}); - -var colorConvert = convert$1; - -(function (module) { -const colorConvert$1 = colorConvert; - -const wrapAnsi16 = (fn, offset) => function () { - const code = fn.apply(colorConvert$1, arguments); - return `\u001B[${code + offset}m`; -}; - -const wrapAnsi256 = (fn, offset) => function () { - const code = fn.apply(colorConvert$1, arguments); - return `\u001B[${38 + offset};5;${code}m`; -}; - -const wrapAnsi16m = (fn, offset) => function () { - const rgb = fn.apply(colorConvert$1, arguments); - return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`; -}; - -function assembleStyles() { - const codes = new Map(); - const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29] - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - gray: [90, 39], - - // Bright color - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39] - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49] - } - }; - - // Fix humans - styles.color.grey = styles.color.gray; - - for (const groupName of Object.keys(styles)) { - const group = styles[groupName]; - - for (const styleName of Object.keys(group)) { - const style = group[styleName]; - - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m` - }; - - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false - }); - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false - }); - } - - const ansi2ansi = n => n; - const rgb2rgb = (r, g, b) => [r, g, b]; - - styles.color.close = '\u001B[39m'; - styles.bgColor.close = '\u001B[49m'; - - styles.color.ansi = { - ansi: wrapAnsi16(ansi2ansi, 0) - }; - styles.color.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 0) - }; - styles.color.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 0) - }; - - styles.bgColor.ansi = { - ansi: wrapAnsi16(ansi2ansi, 10) - }; - styles.bgColor.ansi256 = { - ansi256: wrapAnsi256(ansi2ansi, 10) - }; - styles.bgColor.ansi16m = { - rgb: wrapAnsi16m(rgb2rgb, 10) - }; - - for (let key of Object.keys(colorConvert$1)) { - if (typeof colorConvert$1[key] !== 'object') { - continue; - } - - const suite = colorConvert$1[key]; - - if (key === 'ansi16') { - key = 'ansi'; - } - - if ('ansi16' in suite) { - styles.color.ansi[key] = wrapAnsi16(suite.ansi16, 0); - styles.bgColor.ansi[key] = wrapAnsi16(suite.ansi16, 10); - } - - if ('ansi256' in suite) { - styles.color.ansi256[key] = wrapAnsi256(suite.ansi256, 0); - styles.bgColor.ansi256[key] = wrapAnsi256(suite.ansi256, 10); - } - - if ('rgb' in suite) { - styles.color.ansi16m[key] = wrapAnsi16m(suite.rgb, 0); - styles.bgColor.ansi16m[key] = wrapAnsi16m(suite.rgb, 10); - } - } - - return styles; -} - -// Make the export immutable -Object.defineProperty(module, 'exports', { - enumerable: true, - get: assembleStyles -}); -}(ansiStyles)); - -var hasFlag$2 = (flag, argv) => { - argv = argv || process.argv; - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const pos = argv.indexOf(prefix + flag); - const terminatorPos = argv.indexOf('--'); - return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos); -}; - -const os$1 = require$$0$2; -const hasFlag$1 = hasFlag$2; - -const env$1 = process.env; - -let forceColor; -if (hasFlag$1('no-color') || - hasFlag$1('no-colors') || - hasFlag$1('color=false')) { - forceColor = false; -} else if (hasFlag$1('color') || - hasFlag$1('colors') || - hasFlag$1('color=true') || - hasFlag$1('color=always')) { - forceColor = true; -} -if ('FORCE_COLOR' in env$1) { - forceColor = env$1.FORCE_COLOR.length === 0 || parseInt(env$1.FORCE_COLOR, 10) !== 0; -} - -function translateLevel$1(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function supportsColor$1(stream) { - if (forceColor === false) { - return 0; - } - - if (hasFlag$1('color=16m') || - hasFlag$1('color=full') || - hasFlag$1('color=truecolor')) { - return 3; - } - - if (hasFlag$1('color=256')) { - return 2; - } - - if (stream && !stream.isTTY && forceColor !== true) { - return 0; - } - - const min = forceColor ? 1 : 0; - - if (process.platform === 'win32') { - // Node.js 7.5.0 is the first version of Node.js to include a patch to - // libuv that enables 256 color output on Windows. Anything earlier and it - // won't work. However, here we target Node.js 8 at minimum as it is an LTS - // release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows - // release that supports 256 colors. Windows 10 build 14931 is the first release - // that supports 16m/TrueColor. - const osRelease = os$1.release().split('.'); - if ( - Number(process.versions.node.split('.')[0]) >= 8 && - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env$1) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env$1) || env$1.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env$1) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env$1.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env$1.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env$1) { - const version = parseInt((env$1.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env$1.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env$1.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env$1.TERM)) { - return 1; - } - - if ('COLORTERM' in env$1) { - return 1; - } - - if (env$1.TERM === 'dumb') { - return min; - } - - return min; -} - -function getSupportLevel(stream) { - const level = supportsColor$1(stream); - return translateLevel$1(level); -} - -var supportsColor_1 = { - supportsColor: getSupportLevel, - stdout: getSupportLevel(process.stdout), - stderr: getSupportLevel(process.stderr) -}; - -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; -const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; -const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; - -const ESCAPES = new Map([ - ['n', '\n'], - ['r', '\r'], - ['t', '\t'], - ['b', '\b'], - ['f', '\f'], - ['v', '\v'], - ['0', '\0'], - ['\\', '\\'], - ['e', '\u001B'], - ['a', '\u0007'] -]); - -function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { - return String.fromCharCode(parseInt(c.slice(1), 16)); - } - - return ESCAPES.get(c) || c; -} - -function parseArguments(name, args) { - const results = []; - const chunks = args.trim().split(/\s*,\s*/g); - let matches; - - for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); - } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); - } else { - throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); - } - } - - return results; -} - -function parseStyle(style) { - STYLE_REGEX.lastIndex = 0; - - const results = []; - let matches; - - while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; - - if (matches[2]) { - const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); - } else { - results.push([name]); - } - } - - return results; -} - -function buildStyle(chalk, styles) { - const enabled = {}; - - for (const layer of styles) { - for (const style of layer.styles) { - enabled[style[0]] = layer.inverse ? null : style.slice(1); - } - } - - let current = chalk; - for (const styleName of Object.keys(enabled)) { - if (Array.isArray(enabled[styleName])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } - - if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); - } else { - current = current[styleName]; - } - } - } - - return current; -} - -var templates = (chalk, tmp) => { - const styles = []; - const chunks = []; - let chunk = []; - - // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); - } else if (style) { - const str = chunk.join(''); - chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); - styles.push({inverse, styles: parseStyle(style)}); - } else if (close) { - if (styles.length === 0) { - throw new Error('Found extraneous } in Chalk template literal'); - } - - chunks.push(buildStyle(chalk, styles)(chunk.join(''))); - chunk = []; - styles.pop(); - } else { - chunk.push(chr); - } - }); - - chunks.push(chunk.join('')); - - if (styles.length > 0) { - const errMsg = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMsg); - } - - return chunks.join(''); -}; - -(function (module) { -const escapeStringRegexp = escapeStringRegexp$1; -const ansiStyles$1 = ansiStyles.exports; -const stdoutColor = supportsColor_1.stdout; - -const template = templates; - -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - -// `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; - -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); - -const styles = Object.create(null); - -function applyOptions(obj, options) { - options = options || {}; - - // Detect level if not set manually - const scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; -} - -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); - - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = Chalk; - - return chalk.template; - } - - applyOptions(this, options); -} - -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles$1.blue.open = '\u001B[94m'; -} - -for (const key of Object.keys(ansiStyles$1)) { - ansiStyles$1[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles$1[key].close), 'g'); - - styles[key] = { - get() { - const codes = ansiStyles$1[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); - } - }; -} - -styles.visible = { - get() { - return build.call(this, this._styles || [], true, 'visible'); - } -}; - -ansiStyles$1.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles$1.color.close), 'g'); -for (const model of Object.keys(ansiStyles$1.color.ansi)) { - if (skipModels.has(model)) { - continue; - } - - styles[model] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles$1.color[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles$1.color.close, - closeRe: ansiStyles$1.color.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -ansiStyles$1.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles$1.bgColor.close), 'g'); -for (const model of Object.keys(ansiStyles$1.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } - - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles[bgModel] = { - get() { - const level = this.level; - return function () { - const open = ansiStyles$1.bgColor[levelMapping[level]][model].apply(null, arguments); - const codes = { - open, - close: ansiStyles$1.bgColor.close, - closeRe: ansiStyles$1.bgColor.closeRe - }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); - }; - } - }; -} - -const proto = Object.defineProperties(() => {}, styles); - -function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - - builder._styles = _styles; - builder._empty = _empty; - - const self = this; - - Object.defineProperty(builder, 'level', { - enumerable: true, - get() { - return self.level; - }, - set(level) { - self.level = level; - } - }); - - Object.defineProperty(builder, 'enabled', { - enumerable: true, - get() { - return self.enabled; - }, - set(enabled) { - self.enabled = enabled; - } - }); - - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; - - // `__proto__` is used because we must return a function, but there is - // no way to create a function with a different prototype - builder.__proto__ = proto; // eslint-disable-line no-proto - - return builder; -} - -function applyStyle() { - // Support varags, but simply cast to string in case there's only one arg - const args = arguments; - const argsLen = args.length; - let str = String(arguments[0]); - - if (argsLen === 0) { - return ''; - } - - if (argsLen > 1) { - // Don't slice `arguments`, it prevents V8 optimizations - for (let a = 1; a < argsLen; a++) { - str += ' ' + args[a]; - } - } - - if (!this.enabled || this.level <= 0 || !str) { - return this._empty ? '' : str; - } - - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles$1.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles$1.dim.open = ''; - } - - for (const code of this._styles.slice().reverse()) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; - - // Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS - // https://github.com/chalk/chalk/pull/92 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); - } - - // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue - ansiStyles$1.dim.open = originalDim; - - return str; -} - -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { - // If chalk() was called by itself or with a string, - // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); - } - - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; - - for (let i = 1; i < strings.length; i++) { - parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); - } - - return template(chalk, parts.join('')); -} - -Object.defineProperties(Chalk.prototype, styles); - -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript -}(chalk)); - -Object.defineProperty(lib$3, "__esModule", { - value: true -}); -lib$3.shouldHighlight = shouldHighlight; -lib$3.getChalk = getChalk; -lib$3.default = highlight; - -var _jsTokens = jsTokens; - -var _helperValidatorIdentifier = lib$2; - -var _chalk = chalk.exports; - -const sometimesKeywords = new Set(["as", "async", "from", "get", "of", "set"]); - -function getDefs$1(chalk) { - return { - keyword: chalk.cyan, - capitalized: chalk.yellow, - jsxIdentifier: chalk.yellow, - punctuator: chalk.yellow, - number: chalk.magenta, - string: chalk.green, - regex: chalk.magenta, - comment: chalk.grey, - invalid: chalk.white.bgRed.bold - }; -} - -const NEWLINE$1 = /\r\n|[\n\r\u2028\u2029]/; -const BRACKET = /^[()[\]{}]$/; -let tokenize; -{ - const JSX_TAG = /^[a-z][\w-]*$/i; - - const getTokenType = function (token, offset, text) { - if (token.type === "name") { - if ((0, _helperValidatorIdentifier.isKeyword)(token.value) || (0, _helperValidatorIdentifier.isStrictReservedWord)(token.value, true) || sometimesKeywords.has(token.value)) { - return "keyword"; - } - - if (JSX_TAG.test(token.value) && (text[offset - 1] === "<" || text.substr(offset - 2, 2) == " colorize(str)).join("\n"); - } else { - highlighted += value; - } - } - - return highlighted; -} - -function shouldHighlight(options) { - return !!_chalk.supportsColor || options.forceColor; -} - -function getChalk(options) { - return options.forceColor ? new _chalk.constructor({ - enabled: true, - level: 1 - }) : _chalk; -} - -function highlight(code, options = {}) { - if (shouldHighlight(options)) { - const chalk = getChalk(options); - const defs = getDefs$1(chalk); - return highlightTokens(defs, code); - } else { - return code; - } -} - -Object.defineProperty(lib$4, "__esModule", { - value: true -}); -lib$4.codeFrameColumns = codeFrameColumns$1; -lib$4.default = _default; - -var _highlight = lib$3; - -let deprecationWarningShown = false; - -function getDefs(chalk) { - return { - gutter: chalk.grey, - marker: chalk.red.bold, - message: chalk.red.bold - }; -} - -const NEWLINE = /\r\n|[\n\r\u2028\u2029]/; - -function getMarkerLines(loc, source, opts) { - const startLoc = Object.assign({ - column: 0, - line: -1 - }, loc.start); - const endLoc = Object.assign({}, startLoc, loc.end); - const { - linesAbove = 2, - linesBelow = 3 - } = opts || {}; - const startLine = startLoc.line; - const startColumn = startLoc.column; - const endLine = endLoc.line; - const endColumn = endLoc.column; - let start = Math.max(startLine - (linesAbove + 1), 0); - let end = Math.min(source.length, endLine + linesBelow); - - if (startLine === -1) { - start = 0; - } - - if (endLine === -1) { - end = source.length; - } - - const lineDiff = endLine - startLine; - const markerLines = {}; - - if (lineDiff) { - for (let i = 0; i <= lineDiff; i++) { - const lineNumber = i + startLine; - - if (!startColumn) { - markerLines[lineNumber] = true; - } else if (i === 0) { - const sourceLength = source[lineNumber - 1].length; - markerLines[lineNumber] = [startColumn, sourceLength - startColumn + 1]; - } else if (i === lineDiff) { - markerLines[lineNumber] = [0, endColumn]; - } else { - const sourceLength = source[lineNumber - i].length; - markerLines[lineNumber] = [0, sourceLength]; - } - } - } else { - if (startColumn === endColumn) { - if (startColumn) { - markerLines[startLine] = [startColumn, 0]; - } else { - markerLines[startLine] = true; - } - } else { - markerLines[startLine] = [startColumn, endColumn - startColumn]; - } - } - - return { - start, - end, - markerLines - }; -} - -function codeFrameColumns$1(rawLines, loc, opts = {}) { - const highlighted = (opts.highlightCode || opts.forceColor) && (0, _highlight.shouldHighlight)(opts); - const chalk = (0, _highlight.getChalk)(opts); - const defs = getDefs(chalk); - - const maybeHighlight = (chalkFn, string) => { - return highlighted ? chalkFn(string) : string; - }; - - const lines = rawLines.split(NEWLINE); - const { - start, - end, - markerLines - } = getMarkerLines(loc, lines, opts); - const hasColumns = loc.start && typeof loc.start.column === "number"; - const numberMaxWidth = String(end).length; - const highlightedLines = highlighted ? (0, _highlight.default)(rawLines, opts) : rawLines; - let frame = highlightedLines.split(NEWLINE).slice(start, end).map((line, index) => { - const number = start + 1 + index; - const paddedNumber = ` ${number}`.slice(-numberMaxWidth); - const gutter = ` ${paddedNumber} |`; - const hasMarker = markerLines[number]; - const lastMarkerLine = !markerLines[number + 1]; - - if (hasMarker) { - let markerLine = ""; - - if (Array.isArray(hasMarker)) { - const markerSpacing = line.slice(0, Math.max(hasMarker[0] - 1, 0)).replace(/[^\t]/g, " "); - const numberOfMarkers = hasMarker[1] || 1; - markerLine = ["\n ", maybeHighlight(defs.gutter, gutter.replace(/\d/g, " ")), " ", markerSpacing, maybeHighlight(defs.marker, "^").repeat(numberOfMarkers)].join(""); - - if (lastMarkerLine && opts.message) { - markerLine += " " + maybeHighlight(defs.message, opts.message); - } - } - - return [maybeHighlight(defs.marker, ">"), maybeHighlight(defs.gutter, gutter), line.length > 0 ? ` ${line}` : "", markerLine].join(""); - } else { - return ` ${maybeHighlight(defs.gutter, gutter)}${line.length > 0 ? ` ${line}` : ""}`; - } - }).join("\n"); - - if (opts.message && !hasColumns) { - frame = `${" ".repeat(numberMaxWidth + 1)}${opts.message}\n${frame}`; - } - - if (highlighted) { - return chalk.reset(frame); - } else { - return frame; - } -} - -function _default(rawLines, lineNumber, colNumber, opts = {}) { - if (!deprecationWarningShown) { - deprecationWarningShown = true; - const message = "Passing lineNumber and colNumber is deprecated to @babel/code-frame. Please use `codeFrameColumns`."; - - if (process.emitWarning) { - process.emitWarning(message, "DeprecationWarning"); - } else { - const deprecationError = new Error(message); - deprecationError.name = "DeprecationWarning"; - console.warn(new Error(message)); - } - } - - colNumber = Math.max(colNumber, 0); - const location = { - start: { - column: colNumber, - line: lineNumber - } - }; - return codeFrameColumns$1(rawLines, location, opts); -} - -const errorEx = errorEx_1; -const fallback = jsonParseEvenBetterErrors; -const {default: LinesAndColumns} = require$$2; -const {codeFrameColumns} = lib$4; - -const JSONError = errorEx('JSONError', { - fileName: errorEx.append('in %s'), - codeFrame: errorEx.append('\n\n%s\n') -}); - -const parseJson = (string, reviver, filename) => { - if (typeof reviver === 'string') { - filename = reviver; - reviver = null; - } - - try { - try { - return JSON.parse(string, reviver); - } catch (error) { - fallback(string, reviver); - throw error; - } - } catch (error) { - error.message = error.message.replace(/\n/g, ''); - const indexMatch = error.message.match(/in JSON at position (\d+) while parsing/); - - const jsonError = new JSONError(error); - if (filename) { - jsonError.fileName = filename; - } - - if (indexMatch && indexMatch.length > 0) { - const lines = new LinesAndColumns(string); - const index = Number(indexMatch[1]); - const location = lines.locationForIndex(index); - - const codeFrame = codeFrameColumns( - string, - {start: {line: location.line + 1, column: location.column + 1}}, - {highlightCode: true} - ); - - jsonError.codeFrame = codeFrame; - } - - throw jsonError; - } -}; - -parseJson.JSONError = JSONError; - -var parseJson_1 = parseJson; - -var src = {exports: {}}; - -var browser = {exports: {}}; - -/** - * Helpers. - */ - -var s = 1000; -var m = s * 60; -var h = m * 60; -var d = h * 24; -var w = d * 7; -var y = d * 365.25; - -/** - * Parse or format the given `val`. - * - * Options: - * - * - `long` verbose formatting [false] - * - * @param {String|Number} val - * @param {Object} [options] - * @throws {Error} throw an error if val is not a non-empty string or a number - * @return {String|Number} - * @api public - */ - -var ms = function(val, options) { - options = options || {}; - var type = typeof val; - if (type === 'string' && val.length > 0) { - return parse$a(val); - } else if (type === 'number' && isFinite(val)) { - return options.long ? fmtLong(val) : fmtShort(val); - } - throw new Error( - 'val is not a non-empty string or a valid number. val=' + - JSON.stringify(val) - ); -}; - -/** - * Parse the given `str` and return milliseconds. - * - * @param {String} str - * @return {Number} - * @api private - */ - -function parse$a(str) { - str = String(str); - if (str.length > 100) { - return; - } - var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec( - str - ); - if (!match) { - return; - } - var n = parseFloat(match[1]); - var type = (match[2] || 'ms').toLowerCase(); - switch (type) { - case 'years': - case 'year': - case 'yrs': - case 'yr': - case 'y': - return n * y; - case 'weeks': - case 'week': - case 'w': - return n * w; - case 'days': - case 'day': - case 'd': - return n * d; - case 'hours': - case 'hour': - case 'hrs': - case 'hr': - case 'h': - return n * h; - case 'minutes': - case 'minute': - case 'mins': - case 'min': - case 'm': - return n * m; - case 'seconds': - case 'second': - case 'secs': - case 'sec': - case 's': - return n * s; - case 'milliseconds': - case 'millisecond': - case 'msecs': - case 'msec': - case 'ms': - return n; - default: - return undefined; - } -} - -/** - * Short format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtShort(ms) { - var msAbs = Math.abs(ms); - if (msAbs >= d) { - return Math.round(ms / d) + 'd'; - } - if (msAbs >= h) { - return Math.round(ms / h) + 'h'; - } - if (msAbs >= m) { - return Math.round(ms / m) + 'm'; - } - if (msAbs >= s) { - return Math.round(ms / s) + 's'; - } - return ms + 'ms'; -} - -/** - * Long format for `ms`. - * - * @param {Number} ms - * @return {String} - * @api private - */ - -function fmtLong(ms) { - var msAbs = Math.abs(ms); - if (msAbs >= d) { - return plural$1(ms, msAbs, d, 'day'); - } - if (msAbs >= h) { - return plural$1(ms, msAbs, h, 'hour'); - } - if (msAbs >= m) { - return plural$1(ms, msAbs, m, 'minute'); - } - if (msAbs >= s) { - return plural$1(ms, msAbs, s, 'second'); - } - return ms + ' ms'; -} - -/** - * Pluralization helper. - */ - -function plural$1(ms, msAbs, n, name) { - var isPlural = msAbs >= n * 1.5; - return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : ''); -} - -/** - * This is the common logic for both the Node.js and web browser - * implementations of `debug()`. - */ - -function setup(env) { - createDebug.debug = createDebug; - createDebug.default = createDebug; - createDebug.coerce = coerce; - createDebug.disable = disable; - createDebug.enable = enable; - createDebug.enabled = enabled; - createDebug.humanize = ms; - createDebug.destroy = destroy; - - Object.keys(env).forEach(key => { - createDebug[key] = env[key]; - }); - - /** - * The currently active debug mode names, and names to skip. - */ - - createDebug.names = []; - createDebug.skips = []; - - /** - * Map of special "%n" handling functions, for the debug "format" argument. - * - * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". - */ - createDebug.formatters = {}; - - /** - * Selects a color for a debug namespace - * @param {String} namespace The namespace string for the for the debug instance to be colored - * @return {Number|String} An ANSI color code for the given namespace - * @api private - */ - function selectColor(namespace) { - let hash = 0; - - for (let i = 0; i < namespace.length; i++) { - hash = ((hash << 5) - hash) + namespace.charCodeAt(i); - hash |= 0; // Convert to 32bit integer - } - - return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; - } - createDebug.selectColor = selectColor; - - /** - * Create a debugger with the given `namespace`. - * - * @param {String} namespace - * @return {Function} - * @api public - */ - function createDebug(namespace) { - let prevTime; - let enableOverride = null; - let namespacesCache; - let enabledCache; - - function debug(...args) { - // Disabled? - if (!debug.enabled) { - return; - } - - const self = debug; - - // Set `diff` timestamp - const curr = Number(new Date()); - const ms = curr - (prevTime || curr); - self.diff = ms; - self.prev = prevTime; - self.curr = curr; - prevTime = curr; - - args[0] = createDebug.coerce(args[0]); - - if (typeof args[0] !== 'string') { - // Anything else let's inspect with %O - args.unshift('%O'); - } - - // Apply any `formatters` transformations - let index = 0; - args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => { - // If we encounter an escaped % then don't increase the array index - if (match === '%%') { - return '%'; - } - index++; - const formatter = createDebug.formatters[format]; - if (typeof formatter === 'function') { - const val = args[index]; - match = formatter.call(self, val); - - // Now we need to remove `args[index]` since it's inlined in the `format` - args.splice(index, 1); - index--; - } - return match; - }); - - // Apply env-specific formatting (colors, etc.) - createDebug.formatArgs.call(self, args); - - const logFn = self.log || createDebug.log; - logFn.apply(self, args); - } - - debug.namespace = namespace; - debug.useColors = createDebug.useColors(); - debug.color = createDebug.selectColor(namespace); - debug.extend = extend; - debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. - - Object.defineProperty(debug, 'enabled', { - enumerable: true, - configurable: false, - get: () => { - if (enableOverride !== null) { - return enableOverride; - } - if (namespacesCache !== createDebug.namespaces) { - namespacesCache = createDebug.namespaces; - enabledCache = createDebug.enabled(namespace); - } - - return enabledCache; - }, - set: v => { - enableOverride = v; - } - }); - - // Env-specific initialization logic for debug instances - if (typeof createDebug.init === 'function') { - createDebug.init(debug); - } - - return debug; - } - - function extend(namespace, delimiter) { - const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); - newDebug.log = this.log; - return newDebug; - } - - /** - * Enables a debug mode by namespaces. This can include modes - * separated by a colon and wildcards. - * - * @param {String} namespaces - * @api public - */ - function enable(namespaces) { - createDebug.save(namespaces); - createDebug.namespaces = namespaces; - - createDebug.names = []; - createDebug.skips = []; - - let i; - const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); - const len = split.length; - - for (i = 0; i < len; i++) { - if (!split[i]) { - // ignore empty strings - continue; - } - - namespaces = split[i].replace(/\*/g, '.*?'); - - if (namespaces[0] === '-') { - createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); - } else { - createDebug.names.push(new RegExp('^' + namespaces + '$')); - } - } - } - - /** - * Disable debug output. - * - * @return {String} namespaces - * @api public - */ - function disable() { - const namespaces = [ - ...createDebug.names.map(toNamespace), - ...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace) - ].join(','); - createDebug.enable(''); - return namespaces; - } - - /** - * Returns true if the given mode name is enabled, false otherwise. - * - * @param {String} name - * @return {Boolean} - * @api public - */ - function enabled(name) { - if (name[name.length - 1] === '*') { - return true; - } - - let i; - let len; - - for (i = 0, len = createDebug.skips.length; i < len; i++) { - if (createDebug.skips[i].test(name)) { - return false; - } - } - - for (i = 0, len = createDebug.names.length; i < len; i++) { - if (createDebug.names[i].test(name)) { - return true; - } - } - - return false; - } - - /** - * Convert regexp to namespace - * - * @param {RegExp} regxep - * @return {String} namespace - * @api private - */ - function toNamespace(regexp) { - return regexp.toString() - .substring(2, regexp.toString().length - 2) - .replace(/\.\*\?$/, '*'); - } - - /** - * Coerce `val`. - * - * @param {Mixed} val - * @return {Mixed} - * @api private - */ - function coerce(val) { - if (val instanceof Error) { - return val.stack || val.message; - } - return val; - } - - /** - * XXX DO NOT USE. This is a temporary stub function. - * XXX It WILL be removed in the next major release. - */ - function destroy() { - console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); - } - - createDebug.enable(createDebug.load()); - - return createDebug; -} - -var common$3 = setup; - -/* eslint-env browser */ - -(function (module, exports) { -/** - * This is the web browser implementation of `debug()`. - */ - -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.storage = localstorage(); -exports.destroy = (() => { - let warned = false; - - return () => { - if (!warned) { - warned = true; - console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); - } - }; -})(); - -/** - * Colors. - */ - -exports.colors = [ - '#0000CC', - '#0000FF', - '#0033CC', - '#0033FF', - '#0066CC', - '#0066FF', - '#0099CC', - '#0099FF', - '#00CC00', - '#00CC33', - '#00CC66', - '#00CC99', - '#00CCCC', - '#00CCFF', - '#3300CC', - '#3300FF', - '#3333CC', - '#3333FF', - '#3366CC', - '#3366FF', - '#3399CC', - '#3399FF', - '#33CC00', - '#33CC33', - '#33CC66', - '#33CC99', - '#33CCCC', - '#33CCFF', - '#6600CC', - '#6600FF', - '#6633CC', - '#6633FF', - '#66CC00', - '#66CC33', - '#9900CC', - '#9900FF', - '#9933CC', - '#9933FF', - '#99CC00', - '#99CC33', - '#CC0000', - '#CC0033', - '#CC0066', - '#CC0099', - '#CC00CC', - '#CC00FF', - '#CC3300', - '#CC3333', - '#CC3366', - '#CC3399', - '#CC33CC', - '#CC33FF', - '#CC6600', - '#CC6633', - '#CC9900', - '#CC9933', - '#CCCC00', - '#CCCC33', - '#FF0000', - '#FF0033', - '#FF0066', - '#FF0099', - '#FF00CC', - '#FF00FF', - '#FF3300', - '#FF3333', - '#FF3366', - '#FF3399', - '#FF33CC', - '#FF33FF', - '#FF6600', - '#FF6633', - '#FF9900', - '#FF9933', - '#FFCC00', - '#FFCC33' -]; - -/** - * Currently only WebKit-based Web Inspectors, Firefox >= v31, - * and the Firebug extension (any Firefox version) are known - * to support "%c" CSS customizations. - * - * TODO: add a `localStorage` variable to explicitly enable/disable colors - */ - -// eslint-disable-next-line complexity -function useColors() { - // NB: In an Electron preload script, document will be defined but not fully - // initialized. Since we know we're in Chrome, we'll just detect this case - // explicitly - if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { - return true; - } - - // Internet Explorer and Edge do not support colors. - if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { - return false; - } - - // Is webkit? http://stackoverflow.com/a/16459606/376773 - // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 - return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) || - // Is firebug? http://stackoverflow.com/a/398120/376773 - (typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) || - // Is firefox >= v31? - // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31) || - // Double check webkit in userAgent just in case we are in a worker - (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/)); -} - -/** - * Colorize log arguments if enabled. - * - * @api public - */ - -function formatArgs(args) { - args[0] = (this.useColors ? '%c' : '') + - this.namespace + - (this.useColors ? ' %c' : ' ') + - args[0] + - (this.useColors ? '%c ' : ' ') + - '+' + module.exports.humanize(this.diff); - - if (!this.useColors) { - return; - } - - const c = 'color: ' + this.color; - args.splice(1, 0, c, 'color: inherit'); - - // The final "%c" is somewhat tricky, because there could be other - // arguments passed either before or after the %c, so we need to - // figure out the correct index to insert the CSS into - let index = 0; - let lastC = 0; - args[0].replace(/%[a-zA-Z%]/g, match => { - if (match === '%%') { - return; - } - index++; - if (match === '%c') { - // We only are interested in the *last* %c - // (the user may have provided their own) - lastC = index; - } - }); - - args.splice(lastC, 0, c); -} - -/** - * Invokes `console.debug()` when available. - * No-op when `console.debug` is not a "function". - * If `console.debug` is not available, falls back - * to `console.log`. - * - * @api public - */ -exports.log = console.debug || console.log || (() => {}); - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ -function save(namespaces) { - try { - if (namespaces) { - exports.storage.setItem('debug', namespaces); - } else { - exports.storage.removeItem('debug'); - } - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ -function load() { - let r; - try { - r = exports.storage.getItem('debug'); - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } - - // If debug isn't set in LS, and we're in Electron, try to load $DEBUG - if (!r && typeof process !== 'undefined' && 'env' in process) { - r = process.env.DEBUG; - } - - return r; -} - -/** - * Localstorage attempts to return the localstorage. - * - * This is necessary because safari throws - * when a user disables cookies/localstorage - * and you attempt to access it. - * - * @return {LocalStorage} - * @api private - */ - -function localstorage() { - try { - // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context - // The Browser also has localStorage in the global context. - return localStorage; - } catch (error) { - // Swallow - // XXX (@Qix-) should we be logging these? - } -} - -module.exports = common$3(exports); - -const {formatters} = module.exports; - -/** - * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. - */ - -formatters.j = function (v) { - try { - return JSON.stringify(v); - } catch (error) { - return '[UnexpectedJSONParseError]: ' + error.message; - } -}; -}(browser, browser.exports)); - -var node = {exports: {}}; - -/** - * Module dependencies. - */ - -(function (module, exports) { -const tty = tty$1; -const util = require$$0$4; - -/** - * This is the Node.js implementation of `debug()`. - */ - -exports.init = init; -exports.log = log; -exports.formatArgs = formatArgs; -exports.save = save; -exports.load = load; -exports.useColors = useColors; -exports.destroy = util.deprecate( - () => {}, - 'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.' -); - -/** - * Colors. - */ - -exports.colors = [6, 2, 3, 4, 5, 1]; - -try { - // Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json) - // eslint-disable-next-line import/no-extraneous-dependencies - const supportsColor = supportsColor_1$1; - - if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) { - exports.colors = [ - 20, - 21, - 26, - 27, - 32, - 33, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 56, - 57, - 62, - 63, - 68, - 69, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 92, - 93, - 98, - 99, - 112, - 113, - 128, - 129, - 134, - 135, - 148, - 149, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 178, - 179, - 184, - 185, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 214, - 215, - 220, - 221 - ]; - } -} catch (error) { - // Swallow - we only care if `supports-color` is available; it doesn't have to be. -} - -/** - * Build up the default `inspectOpts` object from the environment variables. - * - * $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js - */ - -exports.inspectOpts = Object.keys(process.env).filter(key => { - return /^debug_/i.test(key); -}).reduce((obj, key) => { - // Camel-case - const prop = key - .substring(6) - .toLowerCase() - .replace(/_([a-z])/g, (_, k) => { - return k.toUpperCase(); - }); - - // Coerce string value into JS value - let val = process.env[key]; - if (/^(yes|on|true|enabled)$/i.test(val)) { - val = true; - } else if (/^(no|off|false|disabled)$/i.test(val)) { - val = false; - } else if (val === 'null') { - val = null; - } else { - val = Number(val); - } - - obj[prop] = val; - return obj; -}, {}); - -/** - * Is stdout a TTY? Colored output is enabled when `true`. - */ - -function useColors() { - return 'colors' in exports.inspectOpts ? - Boolean(exports.inspectOpts.colors) : - tty.isatty(process.stderr.fd); -} - -/** - * Adds ANSI color escape codes if enabled. - * - * @api public - */ - -function formatArgs(args) { - const {namespace: name, useColors} = this; - - if (useColors) { - const c = this.color; - const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c); - const prefix = ` ${colorCode};1m${name} \u001B[0m`; - - args[0] = prefix + args[0].split('\n').join('\n' + prefix); - args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m'); - } else { - args[0] = getDate() + name + ' ' + args[0]; - } -} - -function getDate() { - if (exports.inspectOpts.hideDate) { - return ''; - } - return new Date().toISOString() + ' '; -} - -/** - * Invokes `util.format()` with the specified arguments and writes to stderr. - */ - -function log(...args) { - return process.stderr.write(util.format(...args) + '\n'); -} - -/** - * Save `namespaces`. - * - * @param {String} namespaces - * @api private - */ -function save(namespaces) { - if (namespaces) { - process.env.DEBUG = namespaces; - } else { - // If you set a process.env field to null or undefined, it gets cast to the - // string 'null' or 'undefined'. Just delete instead. - delete process.env.DEBUG; - } -} - -/** - * Load `namespaces`. - * - * @return {String} returns the previously persisted debug modes - * @api private - */ - -function load() { - return process.env.DEBUG; -} - -/** - * Init logic for `debug` instances. - * - * Create a new `inspectOpts` object in case `useColors` is set - * differently for a particular `debug` instance. - */ - -function init(debug) { - debug.inspectOpts = {}; - - const keys = Object.keys(exports.inspectOpts); - for (let i = 0; i < keys.length; i++) { - debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]]; - } -} - -module.exports = common$3(exports); - -const {formatters} = module.exports; - -/** - * Map %o to `util.inspect()`, all on a single line. - */ - -formatters.o = function (v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts) - .split('\n') - .map(str => str.trim()) - .join(' '); -}; - -/** - * Map %O to `util.inspect()`, allowing multiple lines if needed. - */ - -formatters.O = function (v) { - this.inspectOpts.colors = this.useColors; - return util.inspect(v, this.inspectOpts); -}; -}(node, node.exports)); - -/** - * Detect Electron renderer / nwjs process, which is node, but we should - * treat as a browser. - */ - -if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) { - src.exports = browser.exports; -} else { - src.exports = node.exports; -} - -var createDebug = src.exports; - -var re$6 = {exports: {}}; - -// Note: this is the semver.org version of the spec that it implements -// Not necessarily the package version of this code. -const SEMVER_SPEC_VERSION = '2.0.0'; - -const MAX_LENGTH$2 = 256; -const MAX_SAFE_INTEGER$1 = Number.MAX_SAFE_INTEGER || - /* istanbul ignore next */ 9007199254740991; - -// Max safe segment length for coercion. -const MAX_SAFE_COMPONENT_LENGTH = 16; - -var constants = { - SEMVER_SPEC_VERSION, - MAX_LENGTH: MAX_LENGTH$2, - MAX_SAFE_INTEGER: MAX_SAFE_INTEGER$1, - MAX_SAFE_COMPONENT_LENGTH -}; - -const debug$f = ( - typeof process === 'object' && - process.env && - process.env.NODE_DEBUG && - /\bsemver\b/i.test(process.env.NODE_DEBUG) -) ? (...args) => console.error('SEMVER', ...args) - : () => {}; - -var debug_1 = debug$f; - -(function (module, exports) { -const { MAX_SAFE_COMPONENT_LENGTH } = constants; -const debug = debug_1; -exports = module.exports = {}; - -// The actual regexps go on exports.re -const re = exports.re = []; -const src = exports.src = []; -const t = exports.t = {}; -let R = 0; - -const createToken = (name, value, isGlobal) => { - const index = R++; - debug(index, value); - t[name] = index; - src[index] = value; - re[index] = new RegExp(value, isGlobal ? 'g' : undefined); -}; - -// The following Regular Expressions can be used for tokenizing, -// validating, and parsing SemVer version strings. - -// ## Numeric Identifier -// A single `0`, or a non-zero digit followed by zero or more digits. - -createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*'); -createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+'); - -// ## Non-numeric Identifier -// Zero or more digits, followed by a letter or hyphen, and then zero or -// more letters, digits, or hyphens. - -createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*'); - -// ## Main Version -// Three dot-separated numeric identifiers. - -createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` + - `(${src[t.NUMERICIDENTIFIER]})\\.` + - `(${src[t.NUMERICIDENTIFIER]})`); - -createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + - `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` + - `(${src[t.NUMERICIDENTIFIERLOOSE]})`); - -// ## Pre-release Version Identifier -// A numeric identifier, or a non-numeric identifier. - -createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER] -}|${src[t.NONNUMERICIDENTIFIER]})`); - -createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE] -}|${src[t.NONNUMERICIDENTIFIER]})`); - -// ## Pre-release Version -// Hyphen, followed by one or more dot-separated pre-release version -// identifiers. - -createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER] -}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`); - -createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE] -}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`); - -// ## Build Metadata Identifier -// Any combination of digits, letters, or hyphens. - -createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+'); - -// ## Build Metadata -// Plus sign, followed by one or more period-separated build metadata -// identifiers. - -createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER] -}(?:\\.${src[t.BUILDIDENTIFIER]})*))`); - -// ## Full Version String -// A main version, followed optionally by a pre-release version and -// build metadata. - -// Note that the only major, minor, patch, and pre-release sections of -// the version string are capturing groups. The build metadata is not a -// capturing group, because it should not ever be used in version -// comparison. - -createToken('FULLPLAIN', `v?${src[t.MAINVERSION] -}${src[t.PRERELEASE]}?${ - src[t.BUILD]}?`); - -createToken('FULL', `^${src[t.FULLPLAIN]}$`); - -// like full, but allows v1.2.3 and =1.2.3, which people do sometimes. -// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty -// common in the npm registry. -createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE] -}${src[t.PRERELEASELOOSE]}?${ - src[t.BUILD]}?`); - -createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`); - -createToken('GTLT', '((?:<|>)?=?)'); - -// Something like "2.*" or "1.2.x". -// Note that "x.x" is a valid xRange identifer, meaning "any version" -// Only the first item is strictly required. -createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`); -createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`); - -createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIER]})` + - `(?:${src[t.PRERELEASE]})?${ - src[t.BUILD]}?` + - `)?)?`); - -createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + - `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` + - `(?:${src[t.PRERELEASELOOSE]})?${ - src[t.BUILD]}?` + - `)?)?`); - -createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`); -createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`); - -// Coercion. -// Extract anything that could conceivably be a part of a valid semver -createToken('COERCE', `${'(^|[^\\d])' + - '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` + - `(?:$|[^\\d])`); -createToken('COERCERTL', src[t.COERCE], true); - -// Tilde ranges. -// Meaning is "reasonably at or greater than" -createToken('LONETILDE', '(?:~>?)'); - -createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true); -exports.tildeTrimReplace = '$1~'; - -createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`); -createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`); - -// Caret ranges. -// Meaning is "at least and backwards compatible with" -createToken('LONECARET', '(?:\\^)'); - -createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true); -exports.caretTrimReplace = '$1^'; - -createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`); -createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`); - -// A simple gt/lt/eq thing, or just "" to indicate "any version" -createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`); -createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`); - -// An expression to strip any whitespace between the gtlt and the thing -// it modifies, so that `> 1.2.3` ==> `>1.2.3` -createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT] -}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true); -exports.comparatorTrimReplace = '$1$2$3'; - -// Something like `1.2.3 - 1.2.4` -// Note that these all use the loose form, because they'll be -// checked against either the strict or loose comparator form -// later. -createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` + - `\\s+-\\s+` + - `(${src[t.XRANGEPLAIN]})` + - `\\s*$`); - -createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` + - `\\s+-\\s+` + - `(${src[t.XRANGEPLAINLOOSE]})` + - `\\s*$`); - -// Star ranges basically just allow anything at all. -createToken('STAR', '(<|>)?=?\\s*\\*'); -// >=0.0.0 is like a star -createToken('GTE0', '^\\s*>=\\s*0\.0\.0\\s*$'); -createToken('GTE0PRE', '^\\s*>=\\s*0\.0\.0-0\\s*$'); -}(re$6, re$6.exports)); - -// parse out just the options we care about so we always get a consistent -// obj with keys in a consistent order. -const opts = ['includePrerelease', 'loose', 'rtl']; -const parseOptions$4 = options => - !options ? {} - : typeof options !== 'object' ? { loose: true } - : opts.filter(k => options[k]).reduce((options, k) => { - options[k] = true; - return options - }, {}); -var parseOptions_1 = parseOptions$4; - -const numeric$1 = /^[0-9]+$/; -const compareIdentifiers$1 = (a, b) => { - const anum = numeric$1.test(a); - const bnum = numeric$1.test(b); - - if (anum && bnum) { - a = +a; - b = +b; - } - - return a === b ? 0 - : (anum && !bnum) ? -1 - : (bnum && !anum) ? 1 - : a < b ? -1 - : 1 -}; - -const rcompareIdentifiers = (a, b) => compareIdentifiers$1(b, a); - -var identifiers = { - compareIdentifiers: compareIdentifiers$1, - rcompareIdentifiers -}; - -const debug$e = debug_1; -const { MAX_LENGTH: MAX_LENGTH$1, MAX_SAFE_INTEGER } = constants; -const { re: re$5, t: t$4 } = re$6.exports; - -const parseOptions$3 = parseOptions_1; -const { compareIdentifiers } = identifiers; -class SemVer$e { - constructor (version, options) { - options = parseOptions$3(options); - - if (version instanceof SemVer$e) { - if (version.loose === !!options.loose && - version.includePrerelease === !!options.includePrerelease) { - return version - } else { - version = version.version; - } - } else if (typeof version !== 'string') { - throw new TypeError(`Invalid Version: ${version}`) - } - - if (version.length > MAX_LENGTH$1) { - throw new TypeError( - `version is longer than ${MAX_LENGTH$1} characters` - ) - } - - debug$e('SemVer', version, options); - this.options = options; - this.loose = !!options.loose; - // this isn't actually relevant for versions, but keep it so that we - // don't run into trouble passing this.options around. - this.includePrerelease = !!options.includePrerelease; - - const m = version.trim().match(options.loose ? re$5[t$4.LOOSE] : re$5[t$4.FULL]); - - if (!m) { - throw new TypeError(`Invalid Version: ${version}`) - } - - this.raw = version; - - // these are actually numbers - this.major = +m[1]; - this.minor = +m[2]; - this.patch = +m[3]; - - if (this.major > MAX_SAFE_INTEGER || this.major < 0) { - throw new TypeError('Invalid major version') - } - - if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) { - throw new TypeError('Invalid minor version') - } - - if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) { - throw new TypeError('Invalid patch version') - } - - // numberify any prerelease numeric ids - if (!m[4]) { - this.prerelease = []; - } else { - this.prerelease = m[4].split('.').map((id) => { - if (/^[0-9]+$/.test(id)) { - const num = +id; - if (num >= 0 && num < MAX_SAFE_INTEGER) { - return num - } - } - return id - }); - } - - this.build = m[5] ? m[5].split('.') : []; - this.format(); - } - - format () { - this.version = `${this.major}.${this.minor}.${this.patch}`; - if (this.prerelease.length) { - this.version += `-${this.prerelease.join('.')}`; - } - return this.version - } - - toString () { - return this.version - } - - compare (other) { - debug$e('SemVer.compare', this.version, this.options, other); - if (!(other instanceof SemVer$e)) { - if (typeof other === 'string' && other === this.version) { - return 0 - } - other = new SemVer$e(other, this.options); - } - - if (other.version === this.version) { - return 0 - } - - return this.compareMain(other) || this.comparePre(other) - } - - compareMain (other) { - if (!(other instanceof SemVer$e)) { - other = new SemVer$e(other, this.options); - } - - return ( - compareIdentifiers(this.major, other.major) || - compareIdentifiers(this.minor, other.minor) || - compareIdentifiers(this.patch, other.patch) - ) - } - - comparePre (other) { - if (!(other instanceof SemVer$e)) { - other = new SemVer$e(other, this.options); - } - - // NOT having a prerelease is > having one - if (this.prerelease.length && !other.prerelease.length) { - return -1 - } else if (!this.prerelease.length && other.prerelease.length) { - return 1 - } else if (!this.prerelease.length && !other.prerelease.length) { - return 0 - } - - let i = 0; - do { - const a = this.prerelease[i]; - const b = other.prerelease[i]; - debug$e('prerelease compare', i, a, b); - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) - } - } while (++i) - } - - compareBuild (other) { - if (!(other instanceof SemVer$e)) { - other = new SemVer$e(other, this.options); - } - - let i = 0; - do { - const a = this.build[i]; - const b = other.build[i]; - debug$e('prerelease compare', i, a, b); - if (a === undefined && b === undefined) { - return 0 - } else if (b === undefined) { - return 1 - } else if (a === undefined) { - return -1 - } else if (a === b) { - continue - } else { - return compareIdentifiers(a, b) - } - } while (++i) - } - - // preminor will bump the version up to the next minor release, and immediately - // down to pre-release. premajor and prepatch work the same way. - inc (release, identifier) { - switch (release) { - case 'premajor': - this.prerelease.length = 0; - this.patch = 0; - this.minor = 0; - this.major++; - this.inc('pre', identifier); - break - case 'preminor': - this.prerelease.length = 0; - this.patch = 0; - this.minor++; - this.inc('pre', identifier); - break - case 'prepatch': - // If this is already a prerelease, it will bump to the next version - // drop any prereleases that might already exist, since they are not - // relevant at this point. - this.prerelease.length = 0; - this.inc('patch', identifier); - this.inc('pre', identifier); - break - // If the input is a non-prerelease version, this acts the same as - // prepatch. - case 'prerelease': - if (this.prerelease.length === 0) { - this.inc('patch', identifier); - } - this.inc('pre', identifier); - break - - case 'major': - // If this is a pre-major version, bump up to the same major version. - // Otherwise increment major. - // 1.0.0-5 bumps to 1.0.0 - // 1.1.0 bumps to 2.0.0 - if ( - this.minor !== 0 || - this.patch !== 0 || - this.prerelease.length === 0 - ) { - this.major++; - } - this.minor = 0; - this.patch = 0; - this.prerelease = []; - break - case 'minor': - // If this is a pre-minor version, bump up to the same minor version. - // Otherwise increment minor. - // 1.2.0-5 bumps to 1.2.0 - // 1.2.1 bumps to 1.3.0 - if (this.patch !== 0 || this.prerelease.length === 0) { - this.minor++; - } - this.patch = 0; - this.prerelease = []; - break - case 'patch': - // If this is not a pre-release version, it will increment the patch. - // If it is a pre-release it will bump up to the same patch version. - // 1.2.0-5 patches to 1.2.0 - // 1.2.0 patches to 1.2.1 - if (this.prerelease.length === 0) { - this.patch++; - } - this.prerelease = []; - break - // This probably shouldn't be used publicly. - // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. - case 'pre': - if (this.prerelease.length === 0) { - this.prerelease = [0]; - } else { - let i = this.prerelease.length; - while (--i >= 0) { - if (typeof this.prerelease[i] === 'number') { - this.prerelease[i]++; - i = -2; - } - } - if (i === -1) { - // didn't increment anything - this.prerelease.push(0); - } - } - if (identifier) { - // 1.2.0-beta.1 bumps to 1.2.0-beta.2, - // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 - if (this.prerelease[0] === identifier) { - if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0]; - } - } else { - this.prerelease = [identifier, 0]; - } - } - break - - default: - throw new Error(`invalid increment argument: ${release}`) - } - this.format(); - this.raw = this.version; - return this - } -} - -var semver$2 = SemVer$e; - -const {MAX_LENGTH} = constants; -const { re: re$4, t: t$3 } = re$6.exports; -const SemVer$d = semver$2; - -const parseOptions$2 = parseOptions_1; -const parse$9 = (version, options) => { - options = parseOptions$2(options); - - if (version instanceof SemVer$d) { - return version - } - - if (typeof version !== 'string') { - return null - } - - if (version.length > MAX_LENGTH) { - return null - } - - const r = options.loose ? re$4[t$3.LOOSE] : re$4[t$3.FULL]; - if (!r.test(version)) { - return null - } - - try { - return new SemVer$d(version, options) - } catch (er) { - return null - } -}; - -var parse_1 = parse$9; - -const parse$8 = parse_1; -const valid$1 = (version, options) => { - const v = parse$8(version, options); - return v ? v.version : null -}; -var valid_1 = valid$1; - -const parse$7 = parse_1; -const clean = (version, options) => { - const s = parse$7(version.trim().replace(/^[=v]+/, ''), options); - return s ? s.version : null -}; -var clean_1 = clean; - -const SemVer$c = semver$2; - -const inc = (version, release, options, identifier) => { - if (typeof (options) === 'string') { - identifier = options; - options = undefined; - } - - try { - return new SemVer$c(version, options).inc(release, identifier).version - } catch (er) { - return null - } -}; -var inc_1 = inc; - -const SemVer$b = semver$2; -const compare$b = (a, b, loose) => - new SemVer$b(a, loose).compare(new SemVer$b(b, loose)); - -var compare_1 = compare$b; - -const compare$a = compare_1; -const eq$2 = (a, b, loose) => compare$a(a, b, loose) === 0; -var eq_1 = eq$2; - -const parse$6 = parse_1; -const eq$1 = eq_1; - -const diff = (version1, version2) => { - if (eq$1(version1, version2)) { - return null - } else { - const v1 = parse$6(version1); - const v2 = parse$6(version2); - const hasPre = v1.prerelease.length || v2.prerelease.length; - const prefix = hasPre ? 'pre' : ''; - const defaultResult = hasPre ? 'prerelease' : ''; - for (const key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } - } - } - return defaultResult // may be undefined - } -}; -var diff_1 = diff; - -const SemVer$a = semver$2; -const major = (a, loose) => new SemVer$a(a, loose).major; -var major_1 = major; - -const SemVer$9 = semver$2; -const minor = (a, loose) => new SemVer$9(a, loose).minor; -var minor_1 = minor; - -const SemVer$8 = semver$2; -const patch = (a, loose) => new SemVer$8(a, loose).patch; -var patch_1 = patch; - -const parse$5 = parse_1; -const prerelease = (version, options) => { - const parsed = parse$5(version, options); - return (parsed && parsed.prerelease.length) ? parsed.prerelease : null -}; -var prerelease_1 = prerelease; - -const compare$9 = compare_1; -const rcompare = (a, b, loose) => compare$9(b, a, loose); -var rcompare_1 = rcompare; - -const compare$8 = compare_1; -const compareLoose = (a, b) => compare$8(a, b, true); -var compareLoose_1 = compareLoose; - -const SemVer$7 = semver$2; -const compareBuild$2 = (a, b, loose) => { - const versionA = new SemVer$7(a, loose); - const versionB = new SemVer$7(b, loose); - return versionA.compare(versionB) || versionA.compareBuild(versionB) -}; -var compareBuild_1 = compareBuild$2; - -const compareBuild$1 = compareBuild_1; -const sort$1 = (list, loose) => list.sort((a, b) => compareBuild$1(a, b, loose)); -var sort_1 = sort$1; - -const compareBuild = compareBuild_1; -const rsort = (list, loose) => list.sort((a, b) => compareBuild(b, a, loose)); -var rsort_1 = rsort; - -const compare$7 = compare_1; -const gt$3 = (a, b, loose) => compare$7(a, b, loose) > 0; -var gt_1 = gt$3; - -const compare$6 = compare_1; -const lt$2 = (a, b, loose) => compare$6(a, b, loose) < 0; -var lt_1 = lt$2; - -const compare$5 = compare_1; -const neq$1 = (a, b, loose) => compare$5(a, b, loose) !== 0; -var neq_1 = neq$1; - -const compare$4 = compare_1; -const gte$3 = (a, b, loose) => compare$4(a, b, loose) >= 0; -var gte_1 = gte$3; - -const compare$3 = compare_1; -const lte$3 = (a, b, loose) => compare$3(a, b, loose) <= 0; -var lte_1 = lte$3; - -const eq = eq_1; -const neq = neq_1; -const gt$2 = gt_1; -const gte$2 = gte_1; -const lt$1 = lt_1; -const lte$2 = lte_1; - -const cmp$1 = (a, op, b, loose) => { - switch (op) { - case '===': - if (typeof a === 'object') - a = a.version; - if (typeof b === 'object') - b = b.version; - return a === b - - case '!==': - if (typeof a === 'object') - a = a.version; - if (typeof b === 'object') - b = b.version; - return a !== b - - case '': - case '=': - case '==': - return eq(a, b, loose) - - case '!=': - return neq(a, b, loose) - - case '>': - return gt$2(a, b, loose) - - case '>=': - return gte$2(a, b, loose) - - case '<': - return lt$1(a, b, loose) - - case '<=': - return lte$2(a, b, loose) - - default: - throw new TypeError(`Invalid operator: ${op}`) - } -}; -var cmp_1 = cmp$1; - -const SemVer$6 = semver$2; -const parse$4 = parse_1; -const {re: re$3, t: t$2} = re$6.exports; - -const coerce$2 = (version, options) => { - if (version instanceof SemVer$6) { - return version - } - - if (typeof version === 'number') { - version = String(version); - } - - if (typeof version !== 'string') { - return null - } - - options = options || {}; - - let match = null; - if (!options.rtl) { - match = version.match(re$3[t$2.COERCE]); - } else { - // Find the right-most coercible string that does not share - // a terminus with a more left-ward coercible string. - // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4' - // - // Walk through the string checking with a /g regexp - // Manually set the index so as to pick up overlapping matches. - // Stop when we get a match that ends at the string end, since no - // coercible string can be more right-ward without the same terminus. - let next; - while ((next = re$3[t$2.COERCERTL].exec(version)) && - (!match || match.index + match[0].length !== version.length) - ) { - if (!match || - next.index + next[0].length !== match.index + match[0].length) { - match = next; - } - re$3[t$2.COERCERTL].lastIndex = next.index + next[1].length + next[2].length; - } - // leave it in a clean state - re$3[t$2.COERCERTL].lastIndex = -1; - } - - if (match === null) - return null - - return parse$4(`${match[2]}.${match[3] || '0'}.${match[4] || '0'}`, options) -}; -var coerce_1 = coerce$2; - -var iterator = function (Yallist) { - Yallist.prototype[Symbol.iterator] = function* () { - for (let walker = this.head; walker; walker = walker.next) { - yield walker.value; - } - }; -}; - -var yallist = Yallist$1; - -Yallist$1.Node = Node; -Yallist$1.create = Yallist$1; - -function Yallist$1 (list) { - var self = this; - if (!(self instanceof Yallist$1)) { - self = new Yallist$1(); - } - - self.tail = null; - self.head = null; - self.length = 0; - - if (list && typeof list.forEach === 'function') { - list.forEach(function (item) { - self.push(item); - }); - } else if (arguments.length > 0) { - for (var i = 0, l = arguments.length; i < l; i++) { - self.push(arguments[i]); - } - } - - return self -} - -Yallist$1.prototype.removeNode = function (node) { - if (node.list !== this) { - throw new Error('removing node which does not belong to this list') - } - - var next = node.next; - var prev = node.prev; - - if (next) { - next.prev = prev; - } - - if (prev) { - prev.next = next; - } - - if (node === this.head) { - this.head = next; - } - if (node === this.tail) { - this.tail = prev; - } - - node.list.length--; - node.next = null; - node.prev = null; - node.list = null; - - return next -}; - -Yallist$1.prototype.unshiftNode = function (node) { - if (node === this.head) { - return - } - - if (node.list) { - node.list.removeNode(node); - } - - var head = this.head; - node.list = this; - node.next = head; - if (head) { - head.prev = node; - } - - this.head = node; - if (!this.tail) { - this.tail = node; - } - this.length++; -}; - -Yallist$1.prototype.pushNode = function (node) { - if (node === this.tail) { - return - } - - if (node.list) { - node.list.removeNode(node); - } - - var tail = this.tail; - node.list = this; - node.prev = tail; - if (tail) { - tail.next = node; - } - - this.tail = node; - if (!this.head) { - this.head = node; - } - this.length++; -}; - -Yallist$1.prototype.push = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - push$2(this, arguments[i]); - } - return this.length -}; - -Yallist$1.prototype.unshift = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - unshift(this, arguments[i]); - } - return this.length -}; - -Yallist$1.prototype.pop = function () { - if (!this.tail) { - return undefined - } - - var res = this.tail.value; - this.tail = this.tail.prev; - if (this.tail) { - this.tail.next = null; - } else { - this.head = null; - } - this.length--; - return res -}; - -Yallist$1.prototype.shift = function () { - if (!this.head) { - return undefined - } - - var res = this.head.value; - this.head = this.head.next; - if (this.head) { - this.head.prev = null; - } else { - this.tail = null; - } - this.length--; - return res -}; - -Yallist$1.prototype.forEach = function (fn, thisp) { - thisp = thisp || this; - for (var walker = this.head, i = 0; walker !== null; i++) { - fn.call(thisp, walker.value, i, this); - walker = walker.next; - } -}; - -Yallist$1.prototype.forEachReverse = function (fn, thisp) { - thisp = thisp || this; - for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { - fn.call(thisp, walker.value, i, this); - walker = walker.prev; - } -}; - -Yallist$1.prototype.get = function (n) { - for (var i = 0, walker = this.head; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.next; - } - if (i === n && walker !== null) { - return walker.value - } -}; - -Yallist$1.prototype.getReverse = function (n) { - for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.prev; - } - if (i === n && walker !== null) { - return walker.value - } -}; - -Yallist$1.prototype.map = function (fn, thisp) { - thisp = thisp || this; - var res = new Yallist$1(); - for (var walker = this.head; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)); - walker = walker.next; - } - return res -}; - -Yallist$1.prototype.mapReverse = function (fn, thisp) { - thisp = thisp || this; - var res = new Yallist$1(); - for (var walker = this.tail; walker !== null;) { - res.push(fn.call(thisp, walker.value, this)); - walker = walker.prev; - } - return res -}; - -Yallist$1.prototype.reduce = function (fn, initial) { - var acc; - var walker = this.head; - if (arguments.length > 1) { - acc = initial; - } else if (this.head) { - walker = this.head.next; - acc = this.head.value; - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = 0; walker !== null; i++) { - acc = fn(acc, walker.value, i); - walker = walker.next; - } - - return acc -}; - -Yallist$1.prototype.reduceReverse = function (fn, initial) { - var acc; - var walker = this.tail; - if (arguments.length > 1) { - acc = initial; - } else if (this.tail) { - walker = this.tail.prev; - acc = this.tail.value; - } else { - throw new TypeError('Reduce of empty list with no initial value') - } - - for (var i = this.length - 1; walker !== null; i--) { - acc = fn(acc, walker.value, i); - walker = walker.prev; - } - - return acc -}; - -Yallist$1.prototype.toArray = function () { - var arr = new Array(this.length); - for (var i = 0, walker = this.head; walker !== null; i++) { - arr[i] = walker.value; - walker = walker.next; - } - return arr -}; - -Yallist$1.prototype.toArrayReverse = function () { - var arr = new Array(this.length); - for (var i = 0, walker = this.tail; walker !== null; i++) { - arr[i] = walker.value; - walker = walker.prev; - } - return arr -}; - -Yallist$1.prototype.slice = function (from, to) { - to = to || this.length; - if (to < 0) { - to += this.length; - } - from = from || 0; - if (from < 0) { - from += this.length; - } - var ret = new Yallist$1(); - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0; - } - if (to > this.length) { - to = this.length; - } - for (var i = 0, walker = this.head; walker !== null && i < from; i++) { - walker = walker.next; - } - for (; walker !== null && i < to; i++, walker = walker.next) { - ret.push(walker.value); - } - return ret -}; - -Yallist$1.prototype.sliceReverse = function (from, to) { - to = to || this.length; - if (to < 0) { - to += this.length; - } - from = from || 0; - if (from < 0) { - from += this.length; - } - var ret = new Yallist$1(); - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0; - } - if (to > this.length) { - to = this.length; - } - for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { - walker = walker.prev; - } - for (; walker !== null && i > from; i--, walker = walker.prev) { - ret.push(walker.value); - } - return ret -}; - -Yallist$1.prototype.splice = function (start, deleteCount, ...nodes) { - if (start > this.length) { - start = this.length - 1; - } - if (start < 0) { - start = this.length + start; - } - - for (var i = 0, walker = this.head; walker !== null && i < start; i++) { - walker = walker.next; - } - - var ret = []; - for (var i = 0; walker && i < deleteCount; i++) { - ret.push(walker.value); - walker = this.removeNode(walker); - } - if (walker === null) { - walker = this.tail; - } - - if (walker !== this.head && walker !== this.tail) { - walker = walker.prev; - } - - for (var i = 0; i < nodes.length; i++) { - walker = insert(this, walker, nodes[i]); - } - return ret; -}; - -Yallist$1.prototype.reverse = function () { - var head = this.head; - var tail = this.tail; - for (var walker = head; walker !== null; walker = walker.prev) { - var p = walker.prev; - walker.prev = walker.next; - walker.next = p; - } - this.head = tail; - this.tail = head; - return this -}; - -function insert (self, node, value) { - var inserted = node === self.head ? - new Node(value, null, node, self) : - new Node(value, node, node.next, self); - - if (inserted.next === null) { - self.tail = inserted; - } - if (inserted.prev === null) { - self.head = inserted; - } - - self.length++; - - return inserted -} - -function push$2 (self, item) { - self.tail = new Node(item, self.tail, null, self); - if (!self.head) { - self.head = self.tail; - } - self.length++; -} - -function unshift (self, item) { - self.head = new Node(item, null, self.head, self); - if (!self.tail) { - self.tail = self.head; - } - self.length++; -} - -function Node (value, prev, next, list) { - if (!(this instanceof Node)) { - return new Node(value, prev, next, list) - } - - this.list = list; - this.value = value; - - if (prev) { - prev.next = this; - this.prev = prev; - } else { - this.prev = null; - } - - if (next) { - next.prev = this; - this.next = next; - } else { - this.next = null; - } -} - -try { - // add if support for Symbol.iterator is present - iterator(Yallist$1); -} catch (er) {} - -// A linked list to keep track of recently-used-ness -const Yallist = yallist; - -const MAX = Symbol('max'); -const LENGTH = Symbol('length'); -const LENGTH_CALCULATOR = Symbol('lengthCalculator'); -const ALLOW_STALE = Symbol('allowStale'); -const MAX_AGE = Symbol('maxAge'); -const DISPOSE = Symbol('dispose'); -const NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet'); -const LRU_LIST = Symbol('lruList'); -const CACHE = Symbol('cache'); -const UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet'); - -const naiveLength = () => 1; - -// lruList is a yallist where the head is the youngest -// item, and the tail is the oldest. the list contains the Hit -// objects as the entries. -// Each Hit object has a reference to its Yallist.Node. This -// never changes. -// -// cache is a Map (or PseudoMap) that matches the keys to -// the Yallist.Node object. -class LRUCache { - constructor (options) { - if (typeof options === 'number') - options = { max: options }; - - if (!options) - options = {}; - - if (options.max && (typeof options.max !== 'number' || options.max < 0)) - throw new TypeError('max must be a non-negative number') - // Kind of weird to have a default max of Infinity, but oh well. - this[MAX] = options.max || Infinity; - - const lc = options.length || naiveLength; - this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc; - this[ALLOW_STALE] = options.stale || false; - if (options.maxAge && typeof options.maxAge !== 'number') - throw new TypeError('maxAge must be a number') - this[MAX_AGE] = options.maxAge || 0; - this[DISPOSE] = options.dispose; - this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false; - this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false; - this.reset(); - } - - // resize the cache when the max changes. - set max (mL) { - if (typeof mL !== 'number' || mL < 0) - throw new TypeError('max must be a non-negative number') - - this[MAX] = mL || Infinity; - trim(this); - } - get max () { - return this[MAX] - } - - set allowStale (allowStale) { - this[ALLOW_STALE] = !!allowStale; - } - get allowStale () { - return this[ALLOW_STALE] - } - - set maxAge (mA) { - if (typeof mA !== 'number') - throw new TypeError('maxAge must be a non-negative number') - - this[MAX_AGE] = mA; - trim(this); - } - get maxAge () { - return this[MAX_AGE] - } - - // resize the cache when the lengthCalculator changes. - set lengthCalculator (lC) { - if (typeof lC !== 'function') - lC = naiveLength; - - if (lC !== this[LENGTH_CALCULATOR]) { - this[LENGTH_CALCULATOR] = lC; - this[LENGTH] = 0; - this[LRU_LIST].forEach(hit => { - hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key); - this[LENGTH] += hit.length; - }); - } - trim(this); - } - get lengthCalculator () { return this[LENGTH_CALCULATOR] } - - get length () { return this[LENGTH] } - get itemCount () { return this[LRU_LIST].length } - - rforEach (fn, thisp) { - thisp = thisp || this; - for (let walker = this[LRU_LIST].tail; walker !== null;) { - const prev = walker.prev; - forEachStep(this, fn, walker, thisp); - walker = prev; - } - } - - forEach (fn, thisp) { - thisp = thisp || this; - for (let walker = this[LRU_LIST].head; walker !== null;) { - const next = walker.next; - forEachStep(this, fn, walker, thisp); - walker = next; - } - } - - keys () { - return this[LRU_LIST].toArray().map(k => k.key) - } - - values () { - return this[LRU_LIST].toArray().map(k => k.value) - } - - reset () { - if (this[DISPOSE] && - this[LRU_LIST] && - this[LRU_LIST].length) { - this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value)); - } - - this[CACHE] = new Map(); // hash of items by key - this[LRU_LIST] = new Yallist(); // list of items in order of use recency - this[LENGTH] = 0; // length of items in the list - } - - dump () { - return this[LRU_LIST].map(hit => - isStale(this, hit) ? false : { - k: hit.key, - v: hit.value, - e: hit.now + (hit.maxAge || 0) - }).toArray().filter(h => h) - } - - dumpLru () { - return this[LRU_LIST] - } - - set (key, value, maxAge) { - maxAge = maxAge || this[MAX_AGE]; - - if (maxAge && typeof maxAge !== 'number') - throw new TypeError('maxAge must be a number') - - const now = maxAge ? Date.now() : 0; - const len = this[LENGTH_CALCULATOR](value, key); - - if (this[CACHE].has(key)) { - if (len > this[MAX]) { - del(this, this[CACHE].get(key)); - return false - } - - const node = this[CACHE].get(key); - const item = node.value; - - // dispose of the old one before overwriting - // split out into 2 ifs for better coverage tracking - if (this[DISPOSE]) { - if (!this[NO_DISPOSE_ON_SET]) - this[DISPOSE](key, item.value); - } - - item.now = now; - item.maxAge = maxAge; - item.value = value; - this[LENGTH] += len - item.length; - item.length = len; - this.get(key); - trim(this); - return true - } - - const hit = new Entry(key, value, len, now, maxAge); - - // oversized objects fall out of cache automatically. - if (hit.length > this[MAX]) { - if (this[DISPOSE]) - this[DISPOSE](key, value); - - return false - } - - this[LENGTH] += hit.length; - this[LRU_LIST].unshift(hit); - this[CACHE].set(key, this[LRU_LIST].head); - trim(this); - return true - } - - has (key) { - if (!this[CACHE].has(key)) return false - const hit = this[CACHE].get(key).value; - return !isStale(this, hit) - } - - get (key) { - return get(this, key, true) - } - - peek (key) { - return get(this, key, false) - } - - pop () { - const node = this[LRU_LIST].tail; - if (!node) - return null - - del(this, node); - return node.value - } - - del (key) { - del(this, this[CACHE].get(key)); - } - - load (arr) { - // reset the cache - this.reset(); - - const now = Date.now(); - // A previous serialized cache has the most recent items first - for (let l = arr.length - 1; l >= 0; l--) { - const hit = arr[l]; - const expiresAt = hit.e || 0; - if (expiresAt === 0) - // the item was created without expiration in a non aged cache - this.set(hit.k, hit.v); - else { - const maxAge = expiresAt - now; - // dont add already expired items - if (maxAge > 0) { - this.set(hit.k, hit.v, maxAge); - } - } - } - } - - prune () { - this[CACHE].forEach((value, key) => get(this, key, false)); - } -} - -const get = (self, key, doUse) => { - const node = self[CACHE].get(key); - if (node) { - const hit = node.value; - if (isStale(self, hit)) { - del(self, node); - if (!self[ALLOW_STALE]) - return undefined - } else { - if (doUse) { - if (self[UPDATE_AGE_ON_GET]) - node.value.now = Date.now(); - self[LRU_LIST].unshiftNode(node); - } - } - return hit.value - } -}; - -const isStale = (self, hit) => { - if (!hit || (!hit.maxAge && !self[MAX_AGE])) - return false - - const diff = Date.now() - hit.now; - return hit.maxAge ? diff > hit.maxAge - : self[MAX_AGE] && (diff > self[MAX_AGE]) -}; - -const trim = self => { - if (self[LENGTH] > self[MAX]) { - for (let walker = self[LRU_LIST].tail; - self[LENGTH] > self[MAX] && walker !== null;) { - // We know that we're about to delete this one, and also - // what the next least recently used key will be, so just - // go ahead and set it now. - const prev = walker.prev; - del(self, walker); - walker = prev; - } - } -}; - -const del = (self, node) => { - if (node) { - const hit = node.value; - if (self[DISPOSE]) - self[DISPOSE](hit.key, hit.value); - - self[LENGTH] -= hit.length; - self[CACHE].delete(hit.key); - self[LRU_LIST].removeNode(node); - } -}; - -class Entry { - constructor (key, value, length, now, maxAge) { - this.key = key; - this.value = value; - this.length = length; - this.now = now; - this.maxAge = maxAge || 0; - } -} - -const forEachStep = (self, fn, node, thisp) => { - let hit = node.value; - if (isStale(self, hit)) { - del(self, node); - if (!self[ALLOW_STALE]) - hit = undefined; - } - if (hit) - fn.call(thisp, hit.value, hit.key, self); -}; - -var lruCache = LRUCache; - -// hoisted class for cyclic dependency -class Range$a { - constructor (range, options) { - options = parseOptions$1(options); - - if (range instanceof Range$a) { - if ( - range.loose === !!options.loose && - range.includePrerelease === !!options.includePrerelease - ) { - return range - } else { - return new Range$a(range.raw, options) - } - } - - if (range instanceof Comparator$3) { - // just put it in the set and return - this.raw = range.value; - this.set = [[range]]; - this.format(); - return this - } - - this.options = options; - this.loose = !!options.loose; - this.includePrerelease = !!options.includePrerelease; - - // First, split based on boolean or || - this.raw = range; - this.set = range - .split(/\s*\|\|\s*/) - // map the range to a 2d array of comparators - .map(range => this.parseRange(range.trim())) - // throw out any comparator lists that are empty - // this generally means that it was not a valid range, which is allowed - // in loose mode, but will still throw if the WHOLE range is invalid. - .filter(c => c.length); - - if (!this.set.length) { - throw new TypeError(`Invalid SemVer Range: ${range}`) - } - - // if we have any that are not the null set, throw out null sets. - if (this.set.length > 1) { - // keep the first one, in case they're all null sets - const first = this.set[0]; - this.set = this.set.filter(c => !isNullSet(c[0])); - if (this.set.length === 0) - this.set = [first]; - else if (this.set.length > 1) { - // if we have any that are *, then the range is just * - for (const c of this.set) { - if (c.length === 1 && isAny(c[0])) { - this.set = [c]; - break - } - } - } - } - - this.format(); - } - - format () { - this.range = this.set - .map((comps) => { - return comps.join(' ').trim() - }) - .join('||') - .trim(); - return this.range - } - - toString () { - return this.range - } - - parseRange (range) { - range = range.trim(); - - // memoize range parsing for performance. - // this is a very hot path, and fully deterministic. - const memoOpts = Object.keys(this.options).join(','); - const memoKey = `parseRange:${memoOpts}:${range}`; - const cached = cache.get(memoKey); - if (cached) - return cached - - const loose = this.options.loose; - // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` - const hr = loose ? re$2[t$1.HYPHENRANGELOOSE] : re$2[t$1.HYPHENRANGE]; - range = range.replace(hr, hyphenReplace(this.options.includePrerelease)); - debug$d('hyphen replace', range); - // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` - range = range.replace(re$2[t$1.COMPARATORTRIM], comparatorTrimReplace); - debug$d('comparator trim', range, re$2[t$1.COMPARATORTRIM]); - - // `~ 1.2.3` => `~1.2.3` - range = range.replace(re$2[t$1.TILDETRIM], tildeTrimReplace); - - // `^ 1.2.3` => `^1.2.3` - range = range.replace(re$2[t$1.CARETTRIM], caretTrimReplace); - - // normalize spaces - range = range.split(/\s+/).join(' '); - - // At this point, the range is completely trimmed and - // ready to be split into comparators. - - const compRe = loose ? re$2[t$1.COMPARATORLOOSE] : re$2[t$1.COMPARATOR]; - const rangeList = range - .split(' ') - .map(comp => parseComparator(comp, this.options)) - .join(' ') - .split(/\s+/) - // >=0.0.0 is equivalent to * - .map(comp => replaceGTE0(comp, this.options)) - // in loose mode, throw out any that are not valid comparators - .filter(this.options.loose ? comp => !!comp.match(compRe) : () => true) - .map(comp => new Comparator$3(comp, this.options)); - - // if any comparators are the null set, then replace with JUST null set - // if more than one comparator, remove any * comparators - // also, don't include the same comparator more than once - rangeList.length; - const rangeMap = new Map(); - for (const comp of rangeList) { - if (isNullSet(comp)) - return [comp] - rangeMap.set(comp.value, comp); - } - if (rangeMap.size > 1 && rangeMap.has('')) - rangeMap.delete(''); - - const result = [...rangeMap.values()]; - cache.set(memoKey, result); - return result - } - - intersects (range, options) { - if (!(range instanceof Range$a)) { - throw new TypeError('a Range is required') - } - - return this.set.some((thisComparators) => { - return ( - isSatisfiable(thisComparators, options) && - range.set.some((rangeComparators) => { - return ( - isSatisfiable(rangeComparators, options) && - thisComparators.every((thisComparator) => { - return rangeComparators.every((rangeComparator) => { - return thisComparator.intersects(rangeComparator, options) - }) - }) - ) - }) - ) - }) - } - - // if ANY of the sets match ALL of its comparators, then pass - test (version) { - if (!version) { - return false - } - - if (typeof version === 'string') { - try { - version = new SemVer$5(version, this.options); - } catch (er) { - return false - } - } - - for (let i = 0; i < this.set.length; i++) { - if (testSet(this.set[i], version, this.options)) { - return true - } - } - return false - } -} -var range$1 = Range$a; - -const LRU = lruCache; -const cache = new LRU({ max: 1000 }); - -const parseOptions$1 = parseOptions_1; -const Comparator$3 = comparator$1; -const debug$d = debug_1; -const SemVer$5 = semver$2; -const { - re: re$2, - t: t$1, - comparatorTrimReplace, - tildeTrimReplace, - caretTrimReplace -} = re$6.exports; - -const isNullSet = c => c.value === '<0.0.0-0'; -const isAny = c => c.value === ''; - -// take a set of comparators and determine whether there -// exists a version which can satisfy it -const isSatisfiable = (comparators, options) => { - let result = true; - const remainingComparators = comparators.slice(); - let testComparator = remainingComparators.pop(); - - while (result && remainingComparators.length) { - result = remainingComparators.every((otherComparator) => { - return testComparator.intersects(otherComparator, options) - }); - - testComparator = remainingComparators.pop(); - } - - return result -}; - -// comprised of xranges, tildes, stars, and gtlt's at this point. -// already replaced the hyphen ranges -// turn into a set of JUST comparators. -const parseComparator = (comp, options) => { - debug$d('comp', comp, options); - comp = replaceCarets(comp, options); - debug$d('caret', comp); - comp = replaceTildes(comp, options); - debug$d('tildes', comp); - comp = replaceXRanges(comp, options); - debug$d('xrange', comp); - comp = replaceStars(comp, options); - debug$d('stars', comp); - return comp -}; - -const isX = id => !id || id.toLowerCase() === 'x' || id === '*'; - -// ~, ~> --> * (any, kinda silly) -// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0-0 -// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0-0 -// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0-0 -// ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 -// ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 -const replaceTildes = (comp, options) => - comp.trim().split(/\s+/).map((comp) => { - return replaceTilde(comp, options) - }).join(' '); - -const replaceTilde = (comp, options) => { - const r = options.loose ? re$2[t$1.TILDELOOSE] : re$2[t$1.TILDE]; - return comp.replace(r, (_, M, m, p, pr) => { - debug$d('tilde', comp, _, M, m, p, pr); - let ret; - - if (isX(M)) { - ret = ''; - } else if (isX(m)) { - ret = `>=${M}.0.0 <${+M + 1}.0.0-0`; - } else if (isX(p)) { - // ~1.2 == >=1.2.0 <1.3.0-0 - ret = `>=${M}.${m}.0 <${M}.${+m + 1}.0-0`; - } else if (pr) { - debug$d('replaceTilde pr', pr); - ret = `>=${M}.${m}.${p}-${pr - } <${M}.${+m + 1}.0-0`; - } else { - // ~1.2.3 == >=1.2.3 <1.3.0-0 - ret = `>=${M}.${m}.${p - } <${M}.${+m + 1}.0-0`; - } - - debug$d('tilde return', ret); - return ret - }) -}; - -// ^ --> * (any, kinda silly) -// ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0-0 -// ^2.0, ^2.0.x --> >=2.0.0 <3.0.0-0 -// ^1.2, ^1.2.x --> >=1.2.0 <2.0.0-0 -// ^1.2.3 --> >=1.2.3 <2.0.0-0 -// ^1.2.0 --> >=1.2.0 <2.0.0-0 -const replaceCarets = (comp, options) => - comp.trim().split(/\s+/).map((comp) => { - return replaceCaret(comp, options) - }).join(' '); - -const replaceCaret = (comp, options) => { - debug$d('caret', comp, options); - const r = options.loose ? re$2[t$1.CARETLOOSE] : re$2[t$1.CARET]; - const z = options.includePrerelease ? '-0' : ''; - return comp.replace(r, (_, M, m, p, pr) => { - debug$d('caret', comp, _, M, m, p, pr); - let ret; - - if (isX(M)) { - ret = ''; - } else if (isX(m)) { - ret = `>=${M}.0.0${z} <${+M + 1}.0.0-0`; - } else if (isX(p)) { - if (M === '0') { - ret = `>=${M}.${m}.0${z} <${M}.${+m + 1}.0-0`; - } else { - ret = `>=${M}.${m}.0${z} <${+M + 1}.0.0-0`; - } - } else if (pr) { - debug$d('replaceCaret pr', pr); - if (M === '0') { - if (m === '0') { - ret = `>=${M}.${m}.${p}-${pr - } <${M}.${m}.${+p + 1}-0`; - } else { - ret = `>=${M}.${m}.${p}-${pr - } <${M}.${+m + 1}.0-0`; - } - } else { - ret = `>=${M}.${m}.${p}-${pr - } <${+M + 1}.0.0-0`; - } - } else { - debug$d('no pr'); - if (M === '0') { - if (m === '0') { - ret = `>=${M}.${m}.${p - }${z} <${M}.${m}.${+p + 1}-0`; - } else { - ret = `>=${M}.${m}.${p - }${z} <${M}.${+m + 1}.0-0`; - } - } else { - ret = `>=${M}.${m}.${p - } <${+M + 1}.0.0-0`; - } - } - - debug$d('caret return', ret); - return ret - }) -}; - -const replaceXRanges = (comp, options) => { - debug$d('replaceXRanges', comp, options); - return comp.split(/\s+/).map((comp) => { - return replaceXRange(comp, options) - }).join(' ') -}; - -const replaceXRange = (comp, options) => { - comp = comp.trim(); - const r = options.loose ? re$2[t$1.XRANGELOOSE] : re$2[t$1.XRANGE]; - return comp.replace(r, (ret, gtlt, M, m, p, pr) => { - debug$d('xRange', comp, ret, gtlt, M, m, p, pr); - const xM = isX(M); - const xm = xM || isX(m); - const xp = xm || isX(p); - const anyX = xp; - - if (gtlt === '=' && anyX) { - gtlt = ''; - } - - // if we're including prereleases in the match, then we need - // to fix this to -0, the lowest possible prerelease value - pr = options.includePrerelease ? '-0' : ''; - - if (xM) { - if (gtlt === '>' || gtlt === '<') { - // nothing is allowed - ret = '<0.0.0-0'; - } else { - // nothing is forbidden - ret = '*'; - } - } else if (gtlt && anyX) { - // we know patch is an x, because we have any x at all. - // replace X with 0 - if (xm) { - m = 0; - } - p = 0; - - if (gtlt === '>') { - // >1 => >=2.0.0 - // >1.2 => >=1.3.0 - gtlt = '>='; - if (xm) { - M = +M + 1; - m = 0; - p = 0; - } else { - m = +m + 1; - p = 0; - } - } else if (gtlt === '<=') { - // <=0.7.x is actually <0.8.0, since any 0.7.x should - // pass. Similarly, <=7.x is actually <8.0.0, etc. - gtlt = '<'; - if (xm) { - M = +M + 1; - } else { - m = +m + 1; - } - } - - if (gtlt === '<') - pr = '-0'; - - ret = `${gtlt + M}.${m}.${p}${pr}`; - } else if (xm) { - ret = `>=${M}.0.0${pr} <${+M + 1}.0.0-0`; - } else if (xp) { - ret = `>=${M}.${m}.0${pr - } <${M}.${+m + 1}.0-0`; - } - - debug$d('xRange return', ret); - - return ret - }) -}; - -// Because * is AND-ed with everything else in the comparator, -// and '' means "any version", just remove the *s entirely. -const replaceStars = (comp, options) => { - debug$d('replaceStars', comp, options); - // Looseness is ignored here. star is always as loose as it gets! - return comp.trim().replace(re$2[t$1.STAR], '') -}; - -const replaceGTE0 = (comp, options) => { - debug$d('replaceGTE0', comp, options); - return comp.trim() - .replace(re$2[options.includePrerelease ? t$1.GTE0PRE : t$1.GTE0], '') -}; - -// This function is passed to string.replace(re[t.HYPHENRANGE]) -// M, m, patch, prerelease, build -// 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 -// 1.2.3 - 3.4 => >=1.2.0 <3.5.0-0 Any 3.4.x will do -// 1.2 - 3.4 => >=1.2.0 <3.5.0-0 -const hyphenReplace = incPr => ($0, - from, fM, fm, fp, fpr, fb, - to, tM, tm, tp, tpr, tb) => { - if (isX(fM)) { - from = ''; - } else if (isX(fm)) { - from = `>=${fM}.0.0${incPr ? '-0' : ''}`; - } else if (isX(fp)) { - from = `>=${fM}.${fm}.0${incPr ? '-0' : ''}`; - } else if (fpr) { - from = `>=${from}`; - } else { - from = `>=${from}${incPr ? '-0' : ''}`; - } - - if (isX(tM)) { - to = ''; - } else if (isX(tm)) { - to = `<${+tM + 1}.0.0-0`; - } else if (isX(tp)) { - to = `<${tM}.${+tm + 1}.0-0`; - } else if (tpr) { - to = `<=${tM}.${tm}.${tp}-${tpr}`; - } else if (incPr) { - to = `<${tM}.${tm}.${+tp + 1}-0`; - } else { - to = `<=${to}`; - } - - return (`${from} ${to}`).trim() -}; - -const testSet = (set, version, options) => { - for (let i = 0; i < set.length; i++) { - if (!set[i].test(version)) { - return false - } - } - - if (version.prerelease.length && !options.includePrerelease) { - // Find the set of versions that are allowed to have prereleases - // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 - // That should allow `1.2.3-pr.2` to pass. - // However, `1.2.4-alpha.notready` should NOT be allowed, - // even though it's within the range set by the comparators. - for (let i = 0; i < set.length; i++) { - debug$d(set[i].semver); - if (set[i].semver === Comparator$3.ANY) { - continue - } - - if (set[i].semver.prerelease.length > 0) { - const allowed = set[i].semver; - if (allowed.major === version.major && - allowed.minor === version.minor && - allowed.patch === version.patch) { - return true - } - } - } - - // Version has a -pre, but it's not one of the ones we like. - return false - } - - return true -}; - -const ANY$2 = Symbol('SemVer ANY'); -// hoisted class for cyclic dependency -class Comparator$2 { - static get ANY () { - return ANY$2 - } - constructor (comp, options) { - options = parseOptions(options); - - if (comp instanceof Comparator$2) { - if (comp.loose === !!options.loose) { - return comp - } else { - comp = comp.value; - } - } - - debug$c('comparator', comp, options); - this.options = options; - this.loose = !!options.loose; - this.parse(comp); - - if (this.semver === ANY$2) { - this.value = ''; - } else { - this.value = this.operator + this.semver.version; - } - - debug$c('comp', this); - } - - parse (comp) { - const r = this.options.loose ? re$1[t.COMPARATORLOOSE] : re$1[t.COMPARATOR]; - const m = comp.match(r); - - if (!m) { - throw new TypeError(`Invalid comparator: ${comp}`) - } - - this.operator = m[1] !== undefined ? m[1] : ''; - if (this.operator === '=') { - this.operator = ''; - } - - // if it literally is just '>' or '' then allow anything. - if (!m[2]) { - this.semver = ANY$2; - } else { - this.semver = new SemVer$4(m[2], this.options.loose); - } - } - - toString () { - return this.value - } - - test (version) { - debug$c('Comparator.test', version, this.options.loose); - - if (this.semver === ANY$2 || version === ANY$2) { - return true - } - - if (typeof version === 'string') { - try { - version = new SemVer$4(version, this.options); - } catch (er) { - return false - } - } - - return cmp(version, this.operator, this.semver, this.options) - } - - intersects (comp, options) { - if (!(comp instanceof Comparator$2)) { - throw new TypeError('a Comparator is required') - } - - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false - }; - } - - if (this.operator === '') { - if (this.value === '') { - return true - } - return new Range$9(comp.value, options).test(this.value) - } else if (comp.operator === '') { - if (comp.value === '') { - return true - } - return new Range$9(this.value, options).test(comp.semver) - } - - const sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>'); - const sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<'); - const sameSemVer = this.semver.version === comp.semver.version; - const differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<='); - const oppositeDirectionsLessThan = - cmp(this.semver, '<', comp.semver, options) && - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<'); - const oppositeDirectionsGreaterThan = - cmp(this.semver, '>', comp.semver, options) && - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>'); - - return ( - sameDirectionIncreasing || - sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || - oppositeDirectionsGreaterThan - ) - } -} - -var comparator$1 = Comparator$2; - -const parseOptions = parseOptions_1; -const {re: re$1, t} = re$6.exports; -const cmp = cmp_1; -const debug$c = debug_1; -const SemVer$4 = semver$2; -const Range$9 = range$1; - -const Range$8 = range$1; -const satisfies$3 = (version, range, options) => { - try { - range = new Range$8(range, options); - } catch (er) { - return false - } - return range.test(version) -}; -var satisfies_1 = satisfies$3; - -const Range$7 = range$1; - -// Mostly just for testing and legacy API reasons -const toComparators = (range, options) => - new Range$7(range, options).set - .map(comp => comp.map(c => c.value).join(' ').trim().split(' ')); - -var toComparators_1 = toComparators; - -const SemVer$3 = semver$2; -const Range$6 = range$1; - -const maxSatisfying = (versions, range, options) => { - let max = null; - let maxSV = null; - let rangeObj = null; - try { - rangeObj = new Range$6(range, options); - } catch (er) { - return null - } - versions.forEach((v) => { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!max || maxSV.compare(v) === -1) { - // compare(max, v, true) - max = v; - maxSV = new SemVer$3(max, options); - } - } - }); - return max -}; -var maxSatisfying_1 = maxSatisfying; - -const SemVer$2 = semver$2; -const Range$5 = range$1; -const minSatisfying = (versions, range, options) => { - let min = null; - let minSV = null; - let rangeObj = null; - try { - rangeObj = new Range$5(range, options); - } catch (er) { - return null - } - versions.forEach((v) => { - if (rangeObj.test(v)) { - // satisfies(v, range, options) - if (!min || minSV.compare(v) === 1) { - // compare(min, v, true) - min = v; - minSV = new SemVer$2(min, options); - } - } - }); - return min -}; -var minSatisfying_1 = minSatisfying; - -const SemVer$1 = semver$2; -const Range$4 = range$1; -const gt$1 = gt_1; - -const minVersion = (range, loose) => { - range = new Range$4(range, loose); - - let minver = new SemVer$1('0.0.0'); - if (range.test(minver)) { - return minver - } - - minver = new SemVer$1('0.0.0-0'); - if (range.test(minver)) { - return minver - } - - minver = null; - for (let i = 0; i < range.set.length; ++i) { - const comparators = range.set[i]; - - let setMin = null; - comparators.forEach((comparator) => { - // Clone to avoid manipulating the comparator's semver object. - const compver = new SemVer$1(comparator.semver.version); - switch (comparator.operator) { - case '>': - if (compver.prerelease.length === 0) { - compver.patch++; - } else { - compver.prerelease.push(0); - } - compver.raw = compver.format(); - /* fallthrough */ - case '': - case '>=': - if (!setMin || gt$1(compver, setMin)) { - setMin = compver; - } - break - case '<': - case '<=': - /* Ignore maximum versions */ - break - /* istanbul ignore next */ - default: - throw new Error(`Unexpected operation: ${comparator.operator}`) - } - }); - if (setMin && (!minver || gt$1(minver, setMin))) - minver = setMin; - } - - if (minver && range.test(minver)) { - return minver - } - - return null -}; -var minVersion_1 = minVersion; - -const Range$3 = range$1; -const validRange = (range, options) => { - try { - // Return '*' instead of '' so that truthiness works. - // This will throw if it's invalid anyway - return new Range$3(range, options).range || '*' - } catch (er) { - return null - } -}; -var valid = validRange; - -const SemVer = semver$2; -const Comparator$1 = comparator$1; -const {ANY: ANY$1} = Comparator$1; -const Range$2 = range$1; -const satisfies$2 = satisfies_1; -const gt = gt_1; -const lt = lt_1; -const lte$1 = lte_1; -const gte$1 = gte_1; - -const outside$2 = (version, range, hilo, options) => { - version = new SemVer(version, options); - range = new Range$2(range, options); - - let gtfn, ltefn, ltfn, comp, ecomp; - switch (hilo) { - case '>': - gtfn = gt; - ltefn = lte$1; - ltfn = lt; - comp = '>'; - ecomp = '>='; - break - case '<': - gtfn = lt; - ltefn = gte$1; - ltfn = gt; - comp = '<'; - ecomp = '<='; - break - default: - throw new TypeError('Must provide a hilo val of "<" or ">"') - } - - // If it satisfies the range it is not outside - if (satisfies$2(version, range, options)) { - return false - } - - // From now on, variable terms are as if we're in "gtr" mode. - // but note that everything is flipped for the "ltr" function. - - for (let i = 0; i < range.set.length; ++i) { - const comparators = range.set[i]; - - let high = null; - let low = null; - - comparators.forEach((comparator) => { - if (comparator.semver === ANY$1) { - comparator = new Comparator$1('>=0.0.0'); - } - high = high || comparator; - low = low || comparator; - if (gtfn(comparator.semver, high.semver, options)) { - high = comparator; - } else if (ltfn(comparator.semver, low.semver, options)) { - low = comparator; - } - }); - - // If the edge version comparator has a operator then our version - // isn't outside it - if (high.operator === comp || high.operator === ecomp) { - return false - } - - // If the lowest version comparator has an operator and our version - // is less than it then it isn't higher than the range - if ((!low.operator || low.operator === comp) && - ltefn(version, low.semver)) { - return false - } else if (low.operator === ecomp && ltfn(version, low.semver)) { - return false - } - } - return true -}; - -var outside_1 = outside$2; - -// Determine if version is greater than all the versions possible in the range. -const outside$1 = outside_1; -const gtr = (version, range, options) => outside$1(version, range, '>', options); -var gtr_1 = gtr; - -const outside = outside_1; -// Determine if version is less than all the versions possible in the range -const ltr = (version, range, options) => outside(version, range, '<', options); -var ltr_1 = ltr; - -const Range$1 = range$1; -const intersects = (r1, r2, options) => { - r1 = new Range$1(r1, options); - r2 = new Range$1(r2, options); - return r1.intersects(r2) -}; -var intersects_1 = intersects; - -// given a set of versions and a range, create a "simplified" range -// that includes the same versions that the original range does -// If the original range is shorter than the simplified one, return that. -const satisfies$1 = satisfies_1; -const compare$2 = compare_1; -var simplify = (versions, range, options) => { - const set = []; - let min = null; - let prev = null; - const v = versions.sort((a, b) => compare$2(a, b, options)); - for (const version of v) { - const included = satisfies$1(version, range, options); - if (included) { - prev = version; - if (!min) - min = version; - } else { - if (prev) { - set.push([min, prev]); - } - prev = null; - min = null; - } - } - if (min) - set.push([min, null]); - - const ranges = []; - for (const [min, max] of set) { - if (min === max) - ranges.push(min); - else if (!max && min === v[0]) - ranges.push('*'); - else if (!max) - ranges.push(`>=${min}`); - else if (min === v[0]) - ranges.push(`<=${max}`); - else - ranges.push(`${min} - ${max}`); - } - const simplified = ranges.join(' || '); - const original = typeof range.raw === 'string' ? range.raw : String(range); - return simplified.length < original.length ? simplified : range -}; - -const Range = range$1; -const Comparator = comparator$1; -const { ANY } = Comparator; -const satisfies = satisfies_1; -const compare$1 = compare_1; - -// Complex range `r1 || r2 || ...` is a subset of `R1 || R2 || ...` iff: -// - Every simple range `r1, r2, ...` is a null set, OR -// - Every simple range `r1, r2, ...` which is not a null set is a subset of -// some `R1, R2, ...` -// -// Simple range `c1 c2 ...` is a subset of simple range `C1 C2 ...` iff: -// - If c is only the ANY comparator -// - If C is only the ANY comparator, return true -// - Else if in prerelease mode, return false -// - else replace c with `[>=0.0.0]` -// - If C is only the ANY comparator -// - if in prerelease mode, return true -// - else replace C with `[>=0.0.0]` -// - Let EQ be the set of = comparators in c -// - If EQ is more than one, return true (null set) -// - Let GT be the highest > or >= comparator in c -// - Let LT be the lowest < or <= comparator in c -// - If GT and LT, and GT.semver > LT.semver, return true (null set) -// - If any C is a = range, and GT or LT are set, return false -// - If EQ -// - If GT, and EQ does not satisfy GT, return true (null set) -// - If LT, and EQ does not satisfy LT, return true (null set) -// - If EQ satisfies every C, return true -// - Else return false -// - If GT -// - If GT.semver is lower than any > or >= comp in C, return false -// - If GT is >=, and GT.semver does not satisfy every C, return false -// - If GT.semver has a prerelease, and not in prerelease mode -// - If no C has a prerelease and the GT.semver tuple, return false -// - If LT -// - If LT.semver is greater than any < or <= comp in C, return false -// - If LT is <=, and LT.semver does not satisfy every C, return false -// - If GT.semver has a prerelease, and not in prerelease mode -// - If no C has a prerelease and the LT.semver tuple, return false -// - Else return true - -const subset = (sub, dom, options = {}) => { - if (sub === dom) - return true - - sub = new Range(sub, options); - dom = new Range(dom, options); - let sawNonNull = false; - - OUTER: for (const simpleSub of sub.set) { - for (const simpleDom of dom.set) { - const isSub = simpleSubset(simpleSub, simpleDom, options); - sawNonNull = sawNonNull || isSub !== null; - if (isSub) - continue OUTER - } - // the null set is a subset of everything, but null simple ranges in - // a complex range should be ignored. so if we saw a non-null range, - // then we know this isn't a subset, but if EVERY simple range was null, - // then it is a subset. - if (sawNonNull) - return false - } - return true -}; - -const simpleSubset = (sub, dom, options) => { - if (sub === dom) - return true - - if (sub.length === 1 && sub[0].semver === ANY) { - if (dom.length === 1 && dom[0].semver === ANY) - return true - else if (options.includePrerelease) - sub = [ new Comparator('>=0.0.0-0') ]; - else - sub = [ new Comparator('>=0.0.0') ]; - } - - if (dom.length === 1 && dom[0].semver === ANY) { - if (options.includePrerelease) - return true - else - dom = [ new Comparator('>=0.0.0') ]; - } - - const eqSet = new Set(); - let gt, lt; - for (const c of sub) { - if (c.operator === '>' || c.operator === '>=') - gt = higherGT(gt, c, options); - else if (c.operator === '<' || c.operator === '<=') - lt = lowerLT(lt, c, options); - else - eqSet.add(c.semver); - } - - if (eqSet.size > 1) - return null - - let gtltComp; - if (gt && lt) { - gtltComp = compare$1(gt.semver, lt.semver, options); - if (gtltComp > 0) - return null - else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) - return null - } - - // will iterate one or zero times - for (const eq of eqSet) { - if (gt && !satisfies(eq, String(gt), options)) - return null - - if (lt && !satisfies(eq, String(lt), options)) - return null - - for (const c of dom) { - if (!satisfies(eq, String(c), options)) - return false - } - - return true - } - - let higher, lower; - let hasDomLT, hasDomGT; - // if the subset has a prerelease, we need a comparator in the superset - // with the same tuple and a prerelease, or it's not a subset - let needDomLTPre = lt && - !options.includePrerelease && - lt.semver.prerelease.length ? lt.semver : false; - let needDomGTPre = gt && - !options.includePrerelease && - gt.semver.prerelease.length ? gt.semver : false; - // exception: <1.2.3-0 is the same as <1.2.3 - if (needDomLTPre && needDomLTPre.prerelease.length === 1 && - lt.operator === '<' && needDomLTPre.prerelease[0] === 0) { - needDomLTPre = false; - } - - for (const c of dom) { - hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>='; - hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<='; - if (gt) { - if (needDomGTPre) { - if (c.semver.prerelease && c.semver.prerelease.length && - c.semver.major === needDomGTPre.major && - c.semver.minor === needDomGTPre.minor && - c.semver.patch === needDomGTPre.patch) { - needDomGTPre = false; - } - } - if (c.operator === '>' || c.operator === '>=') { - higher = higherGT(gt, c, options); - if (higher === c && higher !== gt) - return false - } else if (gt.operator === '>=' && !satisfies(gt.semver, String(c), options)) - return false - } - if (lt) { - if (needDomLTPre) { - if (c.semver.prerelease && c.semver.prerelease.length && - c.semver.major === needDomLTPre.major && - c.semver.minor === needDomLTPre.minor && - c.semver.patch === needDomLTPre.patch) { - needDomLTPre = false; - } - } - if (c.operator === '<' || c.operator === '<=') { - lower = lowerLT(lt, c, options); - if (lower === c && lower !== lt) - return false - } else if (lt.operator === '<=' && !satisfies(lt.semver, String(c), options)) - return false - } - if (!c.operator && (lt || gt) && gtltComp !== 0) - return false - } - - // if there was a < or >, and nothing in the dom, then must be false - // UNLESS it was limited by another range in the other direction. - // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 - if (gt && hasDomLT && !lt && gtltComp !== 0) - return false - - if (lt && hasDomGT && !gt && gtltComp !== 0) - return false - - // we needed a prerelease range in a specific tuple, but didn't get one - // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, - // because it includes prereleases in the 1.2.3 tuple - if (needDomGTPre || needDomLTPre) - return false - - return true -}; - -// >=1.2.3 is lower than >1.2.3 -const higherGT = (a, b, options) => { - if (!a) - return b - const comp = compare$1(a.semver, b.semver, options); - return comp > 0 ? a - : comp < 0 ? b - : b.operator === '>' && a.operator === '>=' ? b - : a -}; - -// <=1.2.3 is higher than <1.2.3 -const lowerLT = (a, b, options) => { - if (!a) - return b - const comp = compare$1(a.semver, b.semver, options); - return comp < 0 ? a - : comp > 0 ? b - : b.operator === '<' && a.operator === '<=' ? b - : a -}; - -var subset_1 = subset; - -// just pre-load all the stuff that index.js lazily exports -const internalRe = re$6.exports; -var semver$1 = { - re: internalRe.re, - src: internalRe.src, - tokens: internalRe.t, - SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, - SemVer: semver$2, - compareIdentifiers: identifiers.compareIdentifiers, - rcompareIdentifiers: identifiers.rcompareIdentifiers, - parse: parse_1, - valid: valid_1, - clean: clean_1, - inc: inc_1, - diff: diff_1, - major: major_1, - minor: minor_1, - patch: patch_1, - prerelease: prerelease_1, - compare: compare_1, - rcompare: rcompare_1, - compareLoose: compareLoose_1, - compareBuild: compareBuild_1, - sort: sort_1, - rsort: rsort_1, - gt: gt_1, - lt: lt_1, - eq: eq_1, - neq: neq_1, - gte: gte_1, - lte: lte_1, - cmp: cmp_1, - coerce: coerce_1, - Comparator: comparator$1, - Range: range$1, - satisfies: satisfies_1, - toComparators: toComparators_1, - maxSatisfying: maxSatisfying_1, - minSatisfying: minSatisfying_1, - minVersion: minVersion_1, - validRange: valid, - outside: outside_1, - gtr: gtr_1, - ltr: ltr_1, - intersects: intersects_1, - simplifyRange: simplify, - subset: subset_1, -}; - -var semver = semver$1; - -var builtins = function ({ - version = process.version, - experimental = false -} = {}) { - var coreModules = [ - 'assert', - 'buffer', - 'child_process', - 'cluster', - 'console', - 'constants', - 'crypto', - 'dgram', - 'dns', - 'domain', - 'events', - 'fs', - 'http', - 'https', - 'module', - 'net', - 'os', - 'path', - 'punycode', - 'querystring', - 'readline', - 'repl', - 'stream', - 'string_decoder', - 'sys', - 'timers', - 'tls', - 'tty', - 'url', - 'util', - 'vm', - 'zlib' - ]; - - if (semver.lt(version, '6.0.0')) coreModules.push('freelist'); - if (semver.gte(version, '1.0.0')) coreModules.push('v8'); - if (semver.gte(version, '1.1.0')) coreModules.push('process'); - if (semver.gte(version, '8.0.0')) coreModules.push('inspector'); - if (semver.gte(version, '8.1.0')) coreModules.push('async_hooks'); - if (semver.gte(version, '8.4.0')) coreModules.push('http2'); - if (semver.gte(version, '8.5.0')) coreModules.push('perf_hooks'); - if (semver.gte(version, '10.0.0')) coreModules.push('trace_events'); - - if ( - semver.gte(version, '10.5.0') && - (experimental || semver.gte(version, '12.0.0')) - ) { - coreModules.push('worker_threads'); - } - if (semver.gte(version, '12.16.0') && experimental) { - coreModules.push('wasi'); - } - - return coreModules -}; - -// Manually “tree shaken” from: - -const reader = {read: read$3}; -var packageJsonReader = reader; - -/** - * @param {string} jsonPath - * @returns {{string: string}} - */ -function read$3(jsonPath) { - return find$1(path$b.dirname(jsonPath)) -} - -/** - * @param {string} dir - * @returns {{string: string}} - */ -function find$1(dir) { - try { - const string = require$$0$3.readFileSync( - path$b.toNamespacedPath(path$b.join(dir, 'package.json')), - 'utf8' - ); - return {string} - } catch (error) { - if (error.code === 'ENOENT') { - const parent = path$b.dirname(dir); - if (dir !== parent) return find$1(parent) - return {string: undefined} - // Throw all other errors. - /* c8 ignore next 4 */ - } - - throw error - } -} - -// Manually “tree shaken” from: - -const isWindows$1 = process.platform === 'win32'; - -const own$e = {}.hasOwnProperty; - -const codes = {}; - -/** - * @typedef {(...args: unknown[]) => string} MessageFunction - */ - -/** @type {Map} */ -const messages = new Map(); -const nodeInternalPrefix = '__node_internal_'; -/** @type {number} */ -let userStackTraceLimit; - -codes.ERR_INVALID_MODULE_SPECIFIER = createError( - 'ERR_INVALID_MODULE_SPECIFIER', - /** - * @param {string} request - * @param {string} reason - * @param {string} [base] - */ - (request, reason, base = undefined) => { - return `Invalid module "${request}" ${reason}${ - base ? ` imported from ${base}` : '' - }` - }, - TypeError -); - -codes.ERR_INVALID_PACKAGE_CONFIG = createError( - 'ERR_INVALID_PACKAGE_CONFIG', - /** - * @param {string} path - * @param {string} [base] - * @param {string} [message] - */ - (path, base, message) => { - return `Invalid package config ${path}${ - base ? ` while importing ${base}` : '' - }${message ? `. ${message}` : ''}` - }, - Error -); - -codes.ERR_INVALID_PACKAGE_TARGET = createError( - 'ERR_INVALID_PACKAGE_TARGET', - /** - * @param {string} pkgPath - * @param {string} key - * @param {unknown} target - * @param {boolean} [isImport=false] - * @param {string} [base] - */ - (pkgPath, key, target, isImport = false, base = undefined) => { - const relError = - typeof target === 'string' && - !isImport && - target.length > 0 && - !target.startsWith('./'); - if (key === '.') { - assert$2(isImport === false); - return ( - `Invalid "exports" main target ${JSON.stringify(target)} defined ` + - `in the package config ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }${relError ? '; targets must start with "./"' : ''}` - ) - } - - return `Invalid "${ - isImport ? 'imports' : 'exports' - }" target ${JSON.stringify( - target - )} defined for '${key}' in the package config ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }${relError ? '; targets must start with "./"' : ''}` - }, - Error -); - -codes.ERR_MODULE_NOT_FOUND = createError( - 'ERR_MODULE_NOT_FOUND', - /** - * @param {string} path - * @param {string} base - * @param {string} [type] - */ - (path, base, type = 'package') => { - return `Cannot find ${type} '${path}' imported from ${base}` - }, - Error -); - -codes.ERR_PACKAGE_IMPORT_NOT_DEFINED = createError( - 'ERR_PACKAGE_IMPORT_NOT_DEFINED', - /** - * @param {string} specifier - * @param {string} packagePath - * @param {string} base - */ - (specifier, packagePath, base) => { - return `Package import specifier "${specifier}" is not defined${ - packagePath ? ` in package ${packagePath}package.json` : '' - } imported from ${base}` - }, - TypeError -); - -codes.ERR_PACKAGE_PATH_NOT_EXPORTED = createError( - 'ERR_PACKAGE_PATH_NOT_EXPORTED', - /** - * @param {string} pkgPath - * @param {string} subpath - * @param {string} [base] - */ - (pkgPath, subpath, base = undefined) => { - if (subpath === '.') - return `No "exports" main defined in ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }` - return `Package subpath '${subpath}' is not defined by "exports" in ${pkgPath}package.json${ - base ? ` imported from ${base}` : '' - }` - }, - Error -); - -codes.ERR_UNSUPPORTED_DIR_IMPORT = createError( - 'ERR_UNSUPPORTED_DIR_IMPORT', - "Directory import '%s' is not supported " + - 'resolving ES modules imported from %s', - Error -); - -codes.ERR_UNKNOWN_FILE_EXTENSION = createError( - 'ERR_UNKNOWN_FILE_EXTENSION', - 'Unknown file extension "%s" for %s', - TypeError -); - -codes.ERR_INVALID_ARG_VALUE = createError( - 'ERR_INVALID_ARG_VALUE', - /** - * @param {string} name - * @param {unknown} value - * @param {string} [reason='is invalid'] - */ - (name, value, reason = 'is invalid') => { - let inspected = inspect$1(value); - - if (inspected.length > 128) { - inspected = `${inspected.slice(0, 128)}...`; - } - - const type = name.includes('.') ? 'property' : 'argument'; - - return `The ${type} '${name}' ${reason}. Received ${inspected}` - }, - TypeError - // Note: extra classes have been shaken out. - // , RangeError -); - -codes.ERR_UNSUPPORTED_ESM_URL_SCHEME = createError( - 'ERR_UNSUPPORTED_ESM_URL_SCHEME', - /** - * @param {URL} url - */ - (url) => { - let message = - 'Only file and data URLs are supported by the default ESM loader'; - - if (isWindows$1 && url.protocol.length === 2) { - message += '. On Windows, absolute paths must be valid file:// URLs'; - } - - message += `. Received protocol '${url.protocol}'`; - return message - }, - Error -); - -/** - * Utility function for registering the error codes. Only used here. Exported - * *only* to allow for testing. - * @param {string} sym - * @param {MessageFunction|string} value - * @param {ErrorConstructor} def - * @returns {new (...args: unknown[]) => Error} - */ -function createError(sym, value, def) { - // Special case for SystemError that formats the error message differently - // The SystemErrors only have SystemError as their base classes. - messages.set(sym, value); - - return makeNodeErrorWithCode(def, sym) -} - -/** - * @param {ErrorConstructor} Base - * @param {string} key - * @returns {ErrorConstructor} - */ -function makeNodeErrorWithCode(Base, key) { - // @ts-expect-error It’s a Node error. - return NodeError - /** - * @param {unknown[]} args - */ - function NodeError(...args) { - const limit = Error.stackTraceLimit; - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = 0; - const error = new Base(); - // Reset the limit and setting the name property. - if (isErrorStackTraceLimitWritable()) Error.stackTraceLimit = limit; - const message = getMessage(key, args, error); - Object.defineProperty(error, 'message', { - value: message, - enumerable: false, - writable: true, - configurable: true - }); - Object.defineProperty(error, 'toString', { - /** @this {Error} */ - value() { - return `${this.name} [${key}]: ${this.message}` - }, - enumerable: false, - writable: true, - configurable: true - }); - addCodeToName(error, Base.name, key); - // @ts-expect-error It’s a Node error. - error.code = key; - return error - } -} - -const addCodeToName = hideStackFrames( - /** - * @param {Error} error - * @param {string} name - * @param {string} code - * @returns {void} - */ - function (error, name, code) { - // Set the stack - error = captureLargerStackTrace(error); - // Add the error code to the name to include it in the stack trace. - error.name = `${name} [${code}]`; - // Access the stack to generate the error message including the error code - // from the name. - error.stack; // eslint-disable-line no-unused-expressions - // Reset the name to the actual name. - if (name === 'SystemError') { - Object.defineProperty(error, 'name', { - value: name, - enumerable: false, - writable: true, - configurable: true - }); - } else { - delete error.name; - } - } -); - -/** - * @returns {boolean} - */ -function isErrorStackTraceLimitWritable() { - const desc = Object.getOwnPropertyDescriptor(Error, 'stackTraceLimit'); - if (desc === undefined) { - return Object.isExtensible(Error) - } - - return own$e.call(desc, 'writable') ? desc.writable : desc.set !== undefined -} - -/** - * This function removes unnecessary frames from Node.js core errors. - * @template {(...args: unknown[]) => unknown} T - * @type {(fn: T) => T} - */ -function hideStackFrames(fn) { - // We rename the functions that will be hidden to cut off the stacktrace - // at the outermost one - const hidden = nodeInternalPrefix + fn.name; - Object.defineProperty(fn, 'name', {value: hidden}); - return fn -} - -const captureLargerStackTrace = hideStackFrames( - /** - * @param {Error} error - * @returns {Error} - */ - function (error) { - const stackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); - if (stackTraceLimitIsWritable) { - userStackTraceLimit = Error.stackTraceLimit; - Error.stackTraceLimit = Number.POSITIVE_INFINITY; - } - - Error.captureStackTrace(error); - - // Reset the limit - if (stackTraceLimitIsWritable) Error.stackTraceLimit = userStackTraceLimit; - - return error - } -); - -/** - * @param {string} key - * @param {unknown[]} args - * @param {Error} self - * @returns {string} - */ -function getMessage(key, args, self) { - const message = messages.get(key); - - if (typeof message === 'function') { - assert$2( - message.length <= args.length, // Default options do not count. - `Code: ${key}; The provided arguments length (${args.length}) does not ` + - `match the required ones (${message.length}).` - ); - return Reflect.apply(message, self, args) - } - - const expectedLength = (message.match(/%[dfijoOs]/g) || []).length; - assert$2( - expectedLength === args.length, - `Code: ${key}; The provided arguments length (${args.length}) does not ` + - `match the required ones (${expectedLength}).` - ); - if (args.length === 0) return message - - args.unshift(message); - return Reflect.apply(format$2, null, args) -} - -// Manually “tree shaken” from: - -const {ERR_UNKNOWN_FILE_EXTENSION} = codes; - -const extensionFormatMap = { - __proto__: null, - '.cjs': 'commonjs', - '.js': 'module', - '.mjs': 'module' -}; - -/** - * @param {string} url - * @returns {{format: string|null}} - */ -function defaultGetFormat(url) { - if (url.startsWith('node:')) { - return {format: 'builtin'} - } - - const parsed = new URL$1(url); - - if (parsed.protocol === 'data:') { - const {1: mime} = /^([^/]+\/[^;,]+)[^,]*?(;base64)?,/.exec( - parsed.pathname - ) || [null, null]; - const format = mime === 'text/javascript' ? 'module' : null; - return {format} - } - - if (parsed.protocol === 'file:') { - const ext = path$b.extname(parsed.pathname); - /** @type {string} */ - let format; - if (ext === '.js') { - format = getPackageType(parsed.href) === 'module' ? 'module' : 'commonjs'; - } else { - format = extensionFormatMap[ext]; - } - - if (!format) { - throw new ERR_UNKNOWN_FILE_EXTENSION(ext, fileURLToPath(url)) - } - - return {format: format || null} - } - - return {format: null} -} - -// Manually “tree shaken” from: - -const listOfBuiltins = builtins(); - -const { - ERR_INVALID_MODULE_SPECIFIER, - ERR_INVALID_PACKAGE_CONFIG, - ERR_INVALID_PACKAGE_TARGET, - ERR_MODULE_NOT_FOUND, - ERR_PACKAGE_IMPORT_NOT_DEFINED, - ERR_PACKAGE_PATH_NOT_EXPORTED, - ERR_UNSUPPORTED_DIR_IMPORT, - ERR_UNSUPPORTED_ESM_URL_SCHEME, - ERR_INVALID_ARG_VALUE -} = codes; - -const own$d = {}.hasOwnProperty; - -const DEFAULT_CONDITIONS = Object.freeze(['node', 'import']); -const DEFAULT_CONDITIONS_SET = new Set(DEFAULT_CONDITIONS); - -const invalidSegmentRegEx = /(^|\\|\/)(\.\.?|node_modules)(\\|\/|$)/; -const patternRegEx = /\*/g; -const encodedSepRegEx = /%2f|%2c/i; -/** @type {Set} */ -const emittedPackageWarnings = new Set(); -/** @type {Map} */ -const packageJsonCache = new Map(); - -/** - * @param {string} match - * @param {URL} pjsonUrl - * @param {boolean} isExports - * @param {URL} base - * @returns {void} - */ -function emitFolderMapDeprecation(match, pjsonUrl, isExports, base) { - const pjsonPath = fileURLToPath(pjsonUrl); - - if (emittedPackageWarnings.has(pjsonPath + '|' + match)) return - emittedPackageWarnings.add(pjsonPath + '|' + match); - process.emitWarning( - `Use of deprecated folder mapping "${match}" in the ${ - isExports ? '"exports"' : '"imports"' - } field module resolution of the package at ${pjsonPath}${ - base ? ` imported from ${fileURLToPath(base)}` : '' - }.\n` + - `Update this package.json to use a subpath pattern like "${match}*".`, - 'DeprecationWarning', - 'DEP0148' - ); -} - -/** - * @param {URL} url - * @param {URL} packageJsonUrl - * @param {URL} base - * @param {unknown} [main] - * @returns {void} - */ -function emitLegacyIndexDeprecation(url, packageJsonUrl, base, main) { - const {format} = defaultGetFormat(url.href); - if (format !== 'module') return - const path = fileURLToPath(url.href); - const pkgPath = fileURLToPath(new URL$1('.', packageJsonUrl)); - const basePath = fileURLToPath(base); - if (main) - process.emitWarning( - `Package ${pkgPath} has a "main" field set to ${JSON.stringify(main)}, ` + - `excluding the full filename and extension to the resolved file at "${path.slice( - pkgPath.length - )}", imported from ${basePath}.\n Automatic extension resolution of the "main" field is` + - 'deprecated for ES modules.', - 'DeprecationWarning', - 'DEP0151' - ); - else - process.emitWarning( - `No "main" or "exports" field defined in the package.json for ${pkgPath} resolving the main entry point "${path.slice( - pkgPath.length - )}", imported from ${basePath}.\nDefault "index" lookups for the main are deprecated for ES modules.`, - 'DeprecationWarning', - 'DEP0151' - ); -} - -/** - * @param {string[]} [conditions] - * @returns {Set} - */ -function getConditionsSet(conditions) { - if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) { - if (!Array.isArray(conditions)) { - throw new ERR_INVALID_ARG_VALUE( - 'conditions', - conditions, - 'expected an array' - ) - } - - return new Set(conditions) - } - - return DEFAULT_CONDITIONS_SET -} - -/** - * @param {string} path - * @returns {Stats} - */ -function tryStatSync(path) { - // Note: from Node 15 onwards we can use `throwIfNoEntry: false` instead. - try { - return statSync(path) - } catch { - return new Stats() - } -} - -/** - * @param {string} path - * @param {string|URL} specifier Note: `specifier` is actually optional, not base. - * @param {URL} [base] - * @returns {PackageConfig} - */ -function getPackageConfig(path, specifier, base) { - const existing = packageJsonCache.get(path); - if (existing !== undefined) { - return existing - } - - const source = packageJsonReader.read(path).string; - - if (source === undefined) { - /** @type {PackageConfig} */ - const packageConfig = { - pjsonPath: path, - exists: false, - main: undefined, - name: undefined, - type: 'none', - exports: undefined, - imports: undefined - }; - packageJsonCache.set(path, packageConfig); - return packageConfig - } - - /** @type {Object.} */ - let packageJson; - try { - packageJson = JSON.parse(source); - } catch (error) { - throw new ERR_INVALID_PACKAGE_CONFIG( - path, - (base ? `"${specifier}" from ` : '') + fileURLToPath(base || specifier), - error.message - ) - } - - const {exports, imports, main, name, type} = packageJson; - - /** @type {PackageConfig} */ - const packageConfig = { - pjsonPath: path, - exists: true, - main: typeof main === 'string' ? main : undefined, - name: typeof name === 'string' ? name : undefined, - type: type === 'module' || type === 'commonjs' ? type : 'none', - // @ts-expect-error Assume `Object.`. - exports, - // @ts-expect-error Assume `Object.`. - imports: imports && typeof imports === 'object' ? imports : undefined - }; - packageJsonCache.set(path, packageConfig); - return packageConfig -} - -/** - * @param {URL|string} resolved - * @returns {PackageConfig} - */ -function getPackageScopeConfig(resolved) { - let packageJsonUrl = new URL$1('./package.json', resolved); - - while (true) { - const packageJsonPath = packageJsonUrl.pathname; - - if (packageJsonPath.endsWith('node_modules/package.json')) break - - const packageConfig = getPackageConfig( - fileURLToPath(packageJsonUrl), - resolved - ); - if (packageConfig.exists) return packageConfig - - const lastPackageJsonUrl = packageJsonUrl; - packageJsonUrl = new URL$1('../package.json', packageJsonUrl); - - // Terminates at root where ../package.json equals ../../package.json - // (can't just check "/package.json" for Windows support). - if (packageJsonUrl.pathname === lastPackageJsonUrl.pathname) break - } - - const packageJsonPath = fileURLToPath(packageJsonUrl); - /** @type {PackageConfig} */ - const packageConfig = { - pjsonPath: packageJsonPath, - exists: false, - main: undefined, - name: undefined, - type: 'none', - exports: undefined, - imports: undefined - }; - packageJsonCache.set(packageJsonPath, packageConfig); - return packageConfig -} - -/** - * Legacy CommonJS main resolution: - * 1. let M = pkg_url + (json main field) - * 2. TRY(M, M.js, M.json, M.node) - * 3. TRY(M/index.js, M/index.json, M/index.node) - * 4. TRY(pkg_url/index.js, pkg_url/index.json, pkg_url/index.node) - * 5. NOT_FOUND - * - * @param {URL} url - * @returns {boolean} - */ -function fileExists(url) { - return tryStatSync(fileURLToPath(url)).isFile() -} - -/** - * @param {URL} packageJsonUrl - * @param {PackageConfig} packageConfig - * @param {URL} base - * @returns {URL} - */ -function legacyMainResolve(packageJsonUrl, packageConfig, base) { - /** @type {URL} */ - let guess; - if (packageConfig.main !== undefined) { - guess = new URL$1(`./${packageConfig.main}`, packageJsonUrl); - // Note: fs check redundances will be handled by Descriptor cache here. - if (fileExists(guess)) return guess - - const tries = [ - `./${packageConfig.main}.js`, - `./${packageConfig.main}.json`, - `./${packageConfig.main}.node`, - `./${packageConfig.main}/index.js`, - `./${packageConfig.main}/index.json`, - `./${packageConfig.main}/index.node` - ]; - let i = -1; - - while (++i < tries.length) { - guess = new URL$1(tries[i], packageJsonUrl); - if (fileExists(guess)) break - guess = undefined; - } - - if (guess) { - emitLegacyIndexDeprecation( - guess, - packageJsonUrl, - base, - packageConfig.main - ); - return guess - } - // Fallthrough. - } - - const tries = ['./index.js', './index.json', './index.node']; - let i = -1; - - while (++i < tries.length) { - guess = new URL$1(tries[i], packageJsonUrl); - if (fileExists(guess)) break - guess = undefined; - } - - if (guess) { - emitLegacyIndexDeprecation(guess, packageJsonUrl, base, packageConfig.main); - return guess - } - - // Not found. - throw new ERR_MODULE_NOT_FOUND( - fileURLToPath(new URL$1('.', packageJsonUrl)), - fileURLToPath(base) - ) -} - -/** - * @param {URL} resolved - * @param {URL} base - * @returns {URL} - */ -function finalizeResolution(resolved, base) { - if (encodedSepRegEx.test(resolved.pathname)) - throw new ERR_INVALID_MODULE_SPECIFIER( - resolved.pathname, - 'must not include encoded "/" or "\\" characters', - fileURLToPath(base) - ) - - const path = fileURLToPath(resolved); - - const stats = tryStatSync(path.endsWith('/') ? path.slice(-1) : path); - - if (stats.isDirectory()) { - const error = new ERR_UNSUPPORTED_DIR_IMPORT(path, fileURLToPath(base)); - // @ts-expect-error Add this for `import.meta.resolve`. - error.url = String(resolved); - throw error - } - - if (!stats.isFile()) { - throw new ERR_MODULE_NOT_FOUND( - path || resolved.pathname, - base && fileURLToPath(base), - 'module' - ) - } - - return resolved -} - -/** - * @param {string} specifier - * @param {URL?} packageJsonUrl - * @param {URL} base - * @returns {never} - */ -function throwImportNotDefined(specifier, packageJsonUrl, base) { - throw new ERR_PACKAGE_IMPORT_NOT_DEFINED( - specifier, - packageJsonUrl && fileURLToPath(new URL$1('.', packageJsonUrl)), - fileURLToPath(base) - ) -} - -/** - * @param {string} subpath - * @param {URL} packageJsonUrl - * @param {URL} base - * @returns {never} - */ -function throwExportsNotFound(subpath, packageJsonUrl, base) { - throw new ERR_PACKAGE_PATH_NOT_EXPORTED( - fileURLToPath(new URL$1('.', packageJsonUrl)), - subpath, - base && fileURLToPath(base) - ) -} - -/** - * @param {string} subpath - * @param {URL} packageJsonUrl - * @param {boolean} internal - * @param {URL} [base] - * @returns {never} - */ -function throwInvalidSubpath(subpath, packageJsonUrl, internal, base) { - const reason = `request is not a valid subpath for the "${ - internal ? 'imports' : 'exports' - }" resolution of ${fileURLToPath(packageJsonUrl)}`; - - throw new ERR_INVALID_MODULE_SPECIFIER( - subpath, - reason, - base && fileURLToPath(base) - ) -} - -/** - * @param {string} subpath - * @param {unknown} target - * @param {URL} packageJsonUrl - * @param {boolean} internal - * @param {URL} [base] - * @returns {never} - */ -function throwInvalidPackageTarget( - subpath, - target, - packageJsonUrl, - internal, - base -) { - target = - typeof target === 'object' && target !== null - ? JSON.stringify(target, null, '') - : `${target}`; - - throw new ERR_INVALID_PACKAGE_TARGET( - fileURLToPath(new URL$1('.', packageJsonUrl)), - subpath, - target, - internal, - base && fileURLToPath(base) - ) -} - -/** - * @param {string} target - * @param {string} subpath - * @param {string} match - * @param {URL} packageJsonUrl - * @param {URL} base - * @param {boolean} pattern - * @param {boolean} internal - * @param {Set} conditions - * @returns {URL} - */ -function resolvePackageTargetString( - target, - subpath, - match, - packageJsonUrl, - base, - pattern, - internal, - conditions -) { - if (subpath !== '' && !pattern && target[target.length - 1] !== '/') - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - - if (!target.startsWith('./')) { - if (internal && !target.startsWith('../') && !target.startsWith('/')) { - let isURL = false; - - try { - new URL$1(target); - isURL = true; - } catch {} - - if (!isURL) { - const exportTarget = pattern - ? target.replace(patternRegEx, subpath) - : target + subpath; - - return packageResolve(exportTarget, packageJsonUrl, conditions) - } - } - - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - } - - if (invalidSegmentRegEx.test(target.slice(2))) - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - - const resolved = new URL$1(target, packageJsonUrl); - const resolvedPath = resolved.pathname; - const packagePath = new URL$1('.', packageJsonUrl).pathname; - - if (!resolvedPath.startsWith(packagePath)) - throwInvalidPackageTarget(match, target, packageJsonUrl, internal, base); - - if (subpath === '') return resolved - - if (invalidSegmentRegEx.test(subpath)) - throwInvalidSubpath(match + subpath, packageJsonUrl, internal, base); - - if (pattern) return new URL$1(resolved.href.replace(patternRegEx, subpath)) - return new URL$1(subpath, resolved) -} - -/** - * @param {string} key - * @returns {boolean} - */ -function isArrayIndex(key) { - const keyNumber = Number(key); - if (`${keyNumber}` !== key) return false - return keyNumber >= 0 && keyNumber < 0xffff_ffff -} - -/** - * @param {URL} packageJsonUrl - * @param {unknown} target - * @param {string} subpath - * @param {string} packageSubpath - * @param {URL} base - * @param {boolean} pattern - * @param {boolean} internal - * @param {Set} conditions - * @returns {URL} - */ -function resolvePackageTarget( - packageJsonUrl, - target, - subpath, - packageSubpath, - base, - pattern, - internal, - conditions -) { - if (typeof target === 'string') { - return resolvePackageTargetString( - target, - subpath, - packageSubpath, - packageJsonUrl, - base, - pattern, - internal, - conditions - ) - } - - if (Array.isArray(target)) { - /** @type {unknown[]} */ - const targetList = target; - if (targetList.length === 0) return null - - /** @type {Error} */ - let lastException; - let i = -1; - - while (++i < targetList.length) { - const targetItem = targetList[i]; - /** @type {URL} */ - let resolved; - try { - resolved = resolvePackageTarget( - packageJsonUrl, - targetItem, - subpath, - packageSubpath, - base, - pattern, - internal, - conditions - ); - } catch (error) { - lastException = error; - if (error.code === 'ERR_INVALID_PACKAGE_TARGET') continue - throw error - } - - if (resolved === undefined) continue - - if (resolved === null) { - lastException = null; - continue - } - - return resolved - } - - if (lastException === undefined || lastException === null) { - // @ts-expect-error The diff between `undefined` and `null` seems to be - // intentional - return lastException - } - - throw lastException - } - - if (typeof target === 'object' && target !== null) { - const keys = Object.getOwnPropertyNames(target); - let i = -1; - - while (++i < keys.length) { - const key = keys[i]; - if (isArrayIndex(key)) { - throw new ERR_INVALID_PACKAGE_CONFIG( - fileURLToPath(packageJsonUrl), - base, - '"exports" cannot contain numeric property keys.' - ) - } - } - - i = -1; - - while (++i < keys.length) { - const key = keys[i]; - if (key === 'default' || (conditions && conditions.has(key))) { - /** @type {unknown} */ - const conditionalTarget = target[key]; - const resolved = resolvePackageTarget( - packageJsonUrl, - conditionalTarget, - subpath, - packageSubpath, - base, - pattern, - internal, - conditions - ); - if (resolved === undefined) continue - return resolved - } - } - - return undefined - } - - if (target === null) { - return null - } - - throwInvalidPackageTarget( - packageSubpath, - target, - packageJsonUrl, - internal, - base - ); -} - -/** - * @param {unknown} exports - * @param {URL} packageJsonUrl - * @param {URL} base - * @returns {boolean} - */ -function isConditionalExportsMainSugar(exports, packageJsonUrl, base) { - if (typeof exports === 'string' || Array.isArray(exports)) return true - if (typeof exports !== 'object' || exports === null) return false - - const keys = Object.getOwnPropertyNames(exports); - let isConditionalSugar = false; - let i = 0; - let j = -1; - while (++j < keys.length) { - const key = keys[j]; - const curIsConditionalSugar = key === '' || key[0] !== '.'; - if (i++ === 0) { - isConditionalSugar = curIsConditionalSugar; - } else if (isConditionalSugar !== curIsConditionalSugar) { - throw new ERR_INVALID_PACKAGE_CONFIG( - fileURLToPath(packageJsonUrl), - base, - '"exports" cannot contain some keys starting with \'.\' and some not.' + - ' The exports object must either be an object of package subpath keys' + - ' or an object of main entry condition name keys only.' - ) - } - } - - return isConditionalSugar -} - -/** - * @param {URL} packageJsonUrl - * @param {string} packageSubpath - * @param {Object.} packageConfig - * @param {URL} base - * @param {Set} conditions - * @returns {ResolveObject} - */ -function packageExportsResolve( - packageJsonUrl, - packageSubpath, - packageConfig, - base, - conditions -) { - let exports = packageConfig.exports; - if (isConditionalExportsMainSugar(exports, packageJsonUrl, base)) - exports = {'.': exports}; - - if (own$d.call(exports, packageSubpath)) { - const target = exports[packageSubpath]; - const resolved = resolvePackageTarget( - packageJsonUrl, - target, - '', - packageSubpath, - base, - false, - false, - conditions - ); - if (resolved === null || resolved === undefined) - throwExportsNotFound(packageSubpath, packageJsonUrl, base); - return {resolved, exact: true} - } - - let bestMatch = ''; - const keys = Object.getOwnPropertyNames(exports); - let i = -1; - - while (++i < keys.length) { - const key = keys[i]; - if ( - key[key.length - 1] === '*' && - packageSubpath.startsWith(key.slice(0, -1)) && - packageSubpath.length >= key.length && - key.length > bestMatch.length - ) { - bestMatch = key; - } else if ( - key[key.length - 1] === '/' && - packageSubpath.startsWith(key) && - key.length > bestMatch.length - ) { - bestMatch = key; - } - } - - if (bestMatch) { - const target = exports[bestMatch]; - const pattern = bestMatch[bestMatch.length - 1] === '*'; - const subpath = packageSubpath.slice(bestMatch.length - (pattern ? 1 : 0)); - const resolved = resolvePackageTarget( - packageJsonUrl, - target, - subpath, - bestMatch, - base, - pattern, - false, - conditions - ); - if (resolved === null || resolved === undefined) - throwExportsNotFound(packageSubpath, packageJsonUrl, base); - if (!pattern) - emitFolderMapDeprecation(bestMatch, packageJsonUrl, true, base); - return {resolved, exact: pattern} - } - - throwExportsNotFound(packageSubpath, packageJsonUrl, base); -} - -/** - * @param {string} name - * @param {URL} base - * @param {Set} [conditions] - * @returns {ResolveObject} - */ -function packageImportsResolve(name, base, conditions) { - if (name === '#' || name.startsWith('#/')) { - const reason = 'is not a valid internal imports specifier name'; - throw new ERR_INVALID_MODULE_SPECIFIER(name, reason, fileURLToPath(base)) - } - - /** @type {URL} */ - let packageJsonUrl; - - const packageConfig = getPackageScopeConfig(base); - - if (packageConfig.exists) { - packageJsonUrl = pathToFileURL(packageConfig.pjsonPath); - const imports = packageConfig.imports; - if (imports) { - if (own$d.call(imports, name)) { - const resolved = resolvePackageTarget( - packageJsonUrl, - imports[name], - '', - name, - base, - false, - true, - conditions - ); - if (resolved !== null) return {resolved, exact: true} - } else { - let bestMatch = ''; - const keys = Object.getOwnPropertyNames(imports); - let i = -1; - - while (++i < keys.length) { - const key = keys[i]; - - if ( - key[key.length - 1] === '*' && - name.startsWith(key.slice(0, -1)) && - name.length >= key.length && - key.length > bestMatch.length - ) { - bestMatch = key; - } else if ( - key[key.length - 1] === '/' && - name.startsWith(key) && - key.length > bestMatch.length - ) { - bestMatch = key; - } - } - - if (bestMatch) { - const target = imports[bestMatch]; - const pattern = bestMatch[bestMatch.length - 1] === '*'; - const subpath = name.slice(bestMatch.length - (pattern ? 1 : 0)); - const resolved = resolvePackageTarget( - packageJsonUrl, - target, - subpath, - bestMatch, - base, - pattern, - true, - conditions - ); - if (resolved !== null) { - if (!pattern) - emitFolderMapDeprecation(bestMatch, packageJsonUrl, false, base); - return {resolved, exact: pattern} - } - } - } - } - } - - throwImportNotDefined(name, packageJsonUrl, base); -} - -/** - * @param {string} url - * @returns {PackageType} - */ -function getPackageType(url) { - const packageConfig = getPackageScopeConfig(url); - return packageConfig.type -} - -/** - * @param {string} specifier - * @param {URL} base - */ -function parsePackageName(specifier, base) { - let separatorIndex = specifier.indexOf('/'); - let validPackageName = true; - let isScoped = false; - if (specifier[0] === '@') { - isScoped = true; - if (separatorIndex === -1 || specifier.length === 0) { - validPackageName = false; - } else { - separatorIndex = specifier.indexOf('/', separatorIndex + 1); - } - } - - const packageName = - separatorIndex === -1 ? specifier : specifier.slice(0, separatorIndex); - - // Package name cannot have leading . and cannot have percent-encoding or - // separators. - let i = -1; - while (++i < packageName.length) { - if (packageName[i] === '%' || packageName[i] === '\\') { - validPackageName = false; - break - } - } - - if (!validPackageName) { - throw new ERR_INVALID_MODULE_SPECIFIER( - specifier, - 'is not a valid package name', - fileURLToPath(base) - ) - } - - const packageSubpath = - '.' + (separatorIndex === -1 ? '' : specifier.slice(separatorIndex)); - - return {packageName, packageSubpath, isScoped} -} - -/** - * @param {string} specifier - * @param {URL} base - * @param {Set} conditions - * @returns {URL} - */ -function packageResolve(specifier, base, conditions) { - const {packageName, packageSubpath, isScoped} = parsePackageName( - specifier, - base - ); - - // ResolveSelf - const packageConfig = getPackageScopeConfig(base); - - // Can’t test. - /* c8 ignore next 16 */ - if (packageConfig.exists) { - const packageJsonUrl = pathToFileURL(packageConfig.pjsonPath); - if ( - packageConfig.name === packageName && - packageConfig.exports !== undefined && - packageConfig.exports !== null - ) { - return packageExportsResolve( - packageJsonUrl, - packageSubpath, - packageConfig, - base, - conditions - ).resolved - } - } - - let packageJsonUrl = new URL$1( - './node_modules/' + packageName + '/package.json', - base - ); - let packageJsonPath = fileURLToPath(packageJsonUrl); - /** @type {string} */ - let lastPath; - do { - const stat = tryStatSync(packageJsonPath.slice(0, -13)); - if (!stat.isDirectory()) { - lastPath = packageJsonPath; - packageJsonUrl = new URL$1( - (isScoped ? '../../../../node_modules/' : '../../../node_modules/') + - packageName + - '/package.json', - packageJsonUrl - ); - packageJsonPath = fileURLToPath(packageJsonUrl); - continue - } - - // Package match. - const packageConfig = getPackageConfig(packageJsonPath, specifier, base); - if (packageConfig.exports !== undefined && packageConfig.exports !== null) - return packageExportsResolve( - packageJsonUrl, - packageSubpath, - packageConfig, - base, - conditions - ).resolved - if (packageSubpath === '.') - return legacyMainResolve(packageJsonUrl, packageConfig, base) - return new URL$1(packageSubpath, packageJsonUrl) - // Cross-platform root check. - } while (packageJsonPath.length !== lastPath.length) - - throw new ERR_MODULE_NOT_FOUND(packageName, fileURLToPath(base)) -} - -/** - * @param {string} specifier - * @returns {boolean} - */ -function isRelativeSpecifier(specifier) { - if (specifier[0] === '.') { - if (specifier.length === 1 || specifier[1] === '/') return true - if ( - specifier[1] === '.' && - (specifier.length === 2 || specifier[2] === '/') - ) { - return true - } - } - - return false -} - -/** - * @param {string} specifier - * @returns {boolean} - */ -function shouldBeTreatedAsRelativeOrAbsolutePath(specifier) { - if (specifier === '') return false - if (specifier[0] === '/') return true - return isRelativeSpecifier(specifier) -} - -/** - * The “Resolver Algorithm Specification” as detailed in the Node docs (which is - * sync and slightly lower-level than `resolve`). - * - * - * - * @param {string} specifier - * @param {URL} base - * @param {Set} [conditions] - * @returns {URL} - */ -function moduleResolve(specifier, base, conditions) { - // Order swapped from spec for minor perf gain. - // Ok since relative URLs cannot parse as URLs. - /** @type {URL} */ - let resolved; - - if (shouldBeTreatedAsRelativeOrAbsolutePath(specifier)) { - resolved = new URL$1(specifier, base); - } else if (specifier[0] === '#') { -({resolved} = packageImportsResolve(specifier, base, conditions)); - } else { - try { - resolved = new URL$1(specifier); - } catch { - resolved = packageResolve(specifier, base, conditions); - } - } - - return finalizeResolution(resolved, base) -} - -/** - * @param {string} specifier - * @param {{parentURL?: string, conditions?: string[]}} context - * @returns {{url: string}} - */ -function defaultResolve(specifier, context = {}) { - const {parentURL} = context; - /** @type {URL} */ - let parsed; - - try { - parsed = new URL$1(specifier); - if (parsed.protocol === 'data:') { - return {url: specifier} - } - } catch {} - - if (parsed && parsed.protocol === 'node:') return {url: specifier} - if (parsed && parsed.protocol !== 'file:' && parsed.protocol !== 'data:') - throw new ERR_UNSUPPORTED_ESM_URL_SCHEME(parsed) - - if (listOfBuiltins.includes(specifier)) { - return {url: 'node:' + specifier} - } - - if (parentURL.startsWith('data:')) { - // This is gonna blow up, we want the error - new URL$1(specifier, parentURL); - } - - const conditions = getConditionsSet(context.conditions); - let url = moduleResolve(specifier, new URL$1(parentURL), conditions); - - const urlPath = fileURLToPath(url); - const real = realpathSync$1(urlPath); - const old = url; - url = pathToFileURL(real + (urlPath.endsWith(path$b.sep) ? '/' : '')); - url.search = old.search; - url.hash = old.hash; - - return {url: `${url}`} -} - -/** - * Provides a module-relative resolution function scoped to each module, - * returning the URL string. - * `import.meta.resolve` also accepts a second argument which is the parent - * module from which to resolve from. - * - * This function is asynchronous because the ES module resolver in Node.js is - * allowed to be asynchronous. - * - * @param {string} specifier The module specifier to resolve relative to parent. - * @param {string} parent The absolute parent module URL to resolve from. - * You should pass `import.meta.url` or something else - * @returns {Promise} - */ -async function resolve(specifier, parent) { - if (!parent) { - throw new Error( - 'Please pass `parent`: `import-meta-resolve` cannot ponyfill that' - ) - } - - try { - return defaultResolve(specifier, {parentURL: parent}).url - } catch (error) { - return error.code === 'ERR_UNSUPPORTED_DIR_IMPORT' - ? error.url - : Promise.reject(error) - } -} - -var libnpmconfig = {}; - -class FiggyPudding { - constructor (specs, opts, providers) { - this.__specs = specs || {}; - Object.keys(this.__specs).forEach(alias => { - if (typeof this.__specs[alias] === 'string') { - const key = this.__specs[alias]; - const realSpec = this.__specs[key]; - if (realSpec) { - const aliasArr = realSpec.aliases || []; - aliasArr.push(alias, key); - realSpec.aliases = [...(new Set(aliasArr))]; - this.__specs[alias] = realSpec; - } else { - throw new Error(`Alias refers to invalid key: ${key} -> ${alias}`) - } - } - }); - this.__opts = opts || {}; - this.__providers = reverse((providers).filter( - x => x != null && typeof x === 'object' - )); - this.__isFiggyPudding = true; - } - get (key) { - return pudGet(this, key, true) - } - get [Symbol.toStringTag] () { return 'FiggyPudding' } - forEach (fn, thisArg = this) { - for (let [key, value] of this.entries()) { - fn.call(thisArg, value, key, this); - } - } - toJSON () { - const obj = {}; - this.forEach((val, key) => { - obj[key] = val; - }); - return obj - } - * entries (_matcher) { - for (let key of Object.keys(this.__specs)) { - yield [key, this.get(key)]; - } - const matcher = _matcher || this.__opts.other; - if (matcher) { - const seen = new Set(); - for (let p of this.__providers) { - const iter = p.entries ? p.entries(matcher) : entries(p); - for (let [key, val] of iter) { - if (matcher(key) && !seen.has(key)) { - seen.add(key); - yield [key, val]; - } - } - } - } - } - * [Symbol.iterator] () { - for (let [key, value] of this.entries()) { - yield [key, value]; - } - } - * keys () { - for (let [key] of this.entries()) { - yield key; - } - } - * values () { - for (let [, value] of this.entries()) { - yield value; - } - } - concat (...moreConfig) { - return new Proxy(new FiggyPudding( - this.__specs, - this.__opts, - reverse(this.__providers).concat(moreConfig) - ), proxyHandler) - } -} -try { - const util = require$$0$4; - FiggyPudding.prototype[util.inspect.custom] = function (depth, opts) { - return ( - this[Symbol.toStringTag] + ' ' - ) + util.inspect(this.toJSON(), opts) - }; -} catch (e) {} - -function BadKeyError (key) { - throw Object.assign(new Error( - `invalid config key requested: ${key}` - ), {code: 'EBADKEY'}) -} - -function pudGet (pud, key, validate) { - let spec = pud.__specs[key]; - if (validate && !spec && (!pud.__opts.other || !pud.__opts.other(key))) { - BadKeyError(key); - } else { - if (!spec) { spec = {}; } - let ret; - for (let p of pud.__providers) { - ret = tryGet(key, p); - if (ret === undefined && spec.aliases && spec.aliases.length) { - for (let alias of spec.aliases) { - if (alias === key) { continue } - ret = tryGet(alias, p); - if (ret !== undefined) { - break - } - } - } - if (ret !== undefined) { - break - } - } - if (ret === undefined && spec.default !== undefined) { - if (typeof spec.default === 'function') { - return spec.default(pud) - } else { - return spec.default - } - } else { - return ret - } - } -} - -function tryGet (key, p) { - let ret; - if (p.__isFiggyPudding) { - ret = pudGet(p, key, false); - } else if (typeof p.get === 'function') { - ret = p.get(key); - } else { - ret = p[key]; - } - return ret -} - -const proxyHandler = { - has (obj, prop) { - return prop in obj.__specs && pudGet(obj, prop, false) !== undefined - }, - ownKeys (obj) { - return Object.keys(obj.__specs) - }, - get (obj, prop) { - if ( - typeof prop === 'symbol' || - prop.slice(0, 2) === '__' || - prop in FiggyPudding.prototype - ) { - return obj[prop] - } - return obj.get(prop) - }, - set (obj, prop, value) { - if ( - typeof prop === 'symbol' || - prop.slice(0, 2) === '__' - ) { - obj[prop] = value; - return true - } else { - throw new Error('figgyPudding options cannot be modified. Use .concat() instead.') - } - }, - deleteProperty () { - throw new Error('figgyPudding options cannot be deleted. Use .concat() and shadow them instead.') - } -}; - -var figgyPudding_1 = figgyPudding$1; -function figgyPudding$1 (specs, opts) { - function factory (...providers) { - return new Proxy(new FiggyPudding( - specs, - opts, - providers - ), proxyHandler) - } - return factory -} - -function reverse (arr) { - const ret = []; - arr.forEach(x => ret.unshift(x)); - return ret -} - -function entries (obj) { - return Object.keys(obj).map(k => [k, obj[k]]) -} - -var findUp$1 = {exports: {}}; - -var locatePath$1 = {exports: {}}; - -var pathExists$1 = {exports: {}}; - -const fs$5 = require$$0$3; - -pathExists$1.exports = fp => new Promise(resolve => { - fs$5.access(fp, err => { - resolve(!err); - }); -}); - -pathExists$1.exports.sync = fp => { - try { - fs$5.accessSync(fp); - return true; - } catch (err) { - return false; - } -}; - -var pLimit$2 = {exports: {}}; - -var pTry$2 = {exports: {}}; - -const pTry$1 = (fn, ...arguments_) => new Promise(resolve => { - resolve(fn(...arguments_)); -}); - -pTry$2.exports = pTry$1; -// TODO: remove this in the next major version -pTry$2.exports.default = pTry$1; - -const pTry = pTry$2.exports; - -const pLimit$1 = concurrency => { - if (!((Number.isInteger(concurrency) || concurrency === Infinity) && concurrency > 0)) { - return Promise.reject(new TypeError('Expected `concurrency` to be a number from 1 and up')); - } - - const queue = []; - let activeCount = 0; - - const next = () => { - activeCount--; - - if (queue.length > 0) { - queue.shift()(); - } - }; - - const run = (fn, resolve, ...args) => { - activeCount++; - - const result = pTry(fn, ...args); - - resolve(result); - - result.then(next, next); - }; - - const enqueue = (fn, resolve, ...args) => { - if (activeCount < concurrency) { - run(fn, resolve, ...args); - } else { - queue.push(run.bind(null, fn, resolve, ...args)); - } - }; - - const generator = (fn, ...args) => new Promise(resolve => enqueue(fn, resolve, ...args)); - Object.defineProperties(generator, { - activeCount: { - get: () => activeCount - }, - pendingCount: { - get: () => queue.length - }, - clearQueue: { - value: () => { - queue.length = 0; - } - } - }); - - return generator; -}; - -pLimit$2.exports = pLimit$1; -pLimit$2.exports.default = pLimit$1; - -const pLimit = pLimit$2.exports; - -class EndError extends Error { - constructor(value) { - super(); - this.value = value; - } -} - -// The input can also be a promise, so we `Promise.resolve()` it -const testElement = (el, tester) => Promise.resolve(el).then(tester); - -// The input can also be a promise, so we `Promise.all()` them both -const finder$1 = el => Promise.all(el).then(val => val[1] === true && Promise.reject(new EndError(val[0]))); - -var pLocate$1 = (iterable, tester, opts) => { - opts = Object.assign({ - concurrency: Infinity, - preserveOrder: true - }, opts); - - const limit = pLimit(opts.concurrency); - - // Start all the promises concurrently with optional limit - const items = [...iterable].map(el => [el, limit(testElement, el, tester)]); - - // Check the promises either serially or concurrently - const checkLimit = pLimit(opts.preserveOrder ? 1 : Infinity); - - return Promise.all(items.map(el => checkLimit(finder$1, el))) - .then(() => {}) - .catch(err => err instanceof EndError ? err.value : Promise.reject(err)); -}; - -const path$7 = path$b; -const pathExists = pathExists$1.exports; -const pLocate = pLocate$1; - -locatePath$1.exports = (iterable, options) => { - options = Object.assign({ - cwd: process.cwd() - }, options); - - return pLocate(iterable, el => pathExists(path$7.resolve(options.cwd, el)), options); -}; - -locatePath$1.exports.sync = (iterable, options) => { - options = Object.assign({ - cwd: process.cwd() - }, options); - - for (const el of iterable) { - if (pathExists.sync(path$7.resolve(options.cwd, el))) { - return el; - } - } -}; - -const path$6 = path$b; -const locatePath = locatePath$1.exports; - -findUp$1.exports = (filename, opts = {}) => { - const startDir = path$6.resolve(opts.cwd || ''); - const {root} = path$6.parse(startDir); - - const filenames = [].concat(filename); - - return new Promise(resolve => { - (function find(dir) { - locatePath(filenames, {cwd: dir}).then(file => { - if (file) { - resolve(path$6.join(dir, file)); - } else if (dir === root) { - resolve(null); - } else { - find(path$6.dirname(dir)); - } - }); - })(startDir); - }); -}; - -findUp$1.exports.sync = (filename, opts = {}) => { - let dir = path$6.resolve(opts.cwd || ''); - const {root} = path$6.parse(dir); - - const filenames = [].concat(filename); - - // eslint-disable-next-line no-constant-condition - while (true) { - const file = locatePath.sync(filenames, {cwd: dir}); - - if (file) { - return path$6.join(dir, file); - } - - if (dir === root) { - return null; - } - - dir = path$6.dirname(dir); - } -}; - -var ini$1 = {}; - -ini$1.parse = ini$1.decode = decode; - -ini$1.stringify = ini$1.encode = encode$1; - -ini$1.safe = safe$1; -ini$1.unsafe = unsafe$1; - -var eol$1 = typeof process !== 'undefined' && - process.platform === 'win32' ? '\r\n' : '\n'; - -function encode$1 (obj, opt) { - var children = []; - var out = ''; - - if (typeof opt === 'string') { - opt = { - section: opt, - whitespace: false, - }; - } else { - opt = opt || {}; - opt.whitespace = opt.whitespace === true; - } - - var separator = opt.whitespace ? ' = ' : '='; - - Object.keys(obj).forEach(function (k, _, __) { - var val = obj[k]; - if (val && Array.isArray(val)) { - val.forEach(function (item) { - out += safe$1(k + '[]') + separator + safe$1(item) + '\n'; - }); - } else if (val && typeof val === 'object') - children.push(k); - else - out += safe$1(k) + separator + safe$1(val) + eol$1; - }); - - if (opt.section && out.length) - out = '[' + safe$1(opt.section) + ']' + eol$1 + out; - - children.forEach(function (k, _, __) { - var nk = dotSplit(k).join('\\.'); - var section = (opt.section ? opt.section + '.' : '') + nk; - var child = encode$1(obj[k], { - section: section, - whitespace: opt.whitespace, - }); - if (out.length && child.length) - out += eol$1; - - out += child; - }); - - return out -} - -function dotSplit (str) { - return str.replace(/\1/g, '\u0002LITERAL\\1LITERAL\u0002') - .replace(/\\\./g, '\u0001') - .split(/\./).map(function (part) { - return part.replace(/\1/g, '\\.') - .replace(/\2LITERAL\\1LITERAL\2/g, '\u0001') - }) -} - -function decode (str) { - var out = {}; - var p = out; - var section = null; - // section |key = value - var re = /^\[([^\]]*)\]$|^([^=]+)(=(.*))?$/i; - var lines = str.split(/[\r\n]+/g); - - lines.forEach(function (line, _, __) { - if (!line || line.match(/^\s*[;#]/)) - return - var match = line.match(re); - if (!match) - return - if (match[1] !== undefined) { - section = unsafe$1(match[1]); - if (section === '__proto__') { - // not allowed - // keep parsing the section, but don't attach it. - p = {}; - return - } - p = out[section] = out[section] || {}; - return - } - var key = unsafe$1(match[2]); - if (key === '__proto__') - return - var value = match[3] ? unsafe$1(match[4]) : true; - switch (value) { - case 'true': - case 'false': - case 'null': value = JSON.parse(value); - } - - // Convert keys with '[]' suffix to an array - if (key.length > 2 && key.slice(-2) === '[]') { - key = key.substring(0, key.length - 2); - if (key === '__proto__') - return - if (!p[key]) - p[key] = []; - else if (!Array.isArray(p[key])) - p[key] = [p[key]]; - } - - // safeguard against resetting a previously defined - // array by accidentally forgetting the brackets - if (Array.isArray(p[key])) - p[key].push(value); - else - p[key] = value; - }); - - // {a:{y:1},"a.b":{x:2}} --> {a:{y:1,b:{x:2}}} - // use a filter to return the keys that have to be deleted. - Object.keys(out).filter(function (k, _, __) { - if (!out[k] || - typeof out[k] !== 'object' || - Array.isArray(out[k])) - return false - - // see if the parent section is also an object. - // if so, add it to that, and mark this one for deletion - var parts = dotSplit(k); - var p = out; - var l = parts.pop(); - var nl = l.replace(/\\\./g, '.'); - parts.forEach(function (part, _, __) { - if (part === '__proto__') - return - if (!p[part] || typeof p[part] !== 'object') - p[part] = {}; - p = p[part]; - }); - if (p === out && nl === l) - return false - - p[nl] = out[k]; - return true - }).forEach(function (del, _, __) { - delete out[del]; - }); - - return out -} - -function isQuoted (val) { - return (val.charAt(0) === '"' && val.slice(-1) === '"') || - (val.charAt(0) === "'" && val.slice(-1) === "'") -} - -function safe$1 (val) { - return (typeof val !== 'string' || - val.match(/[=\r\n]/) || - val.match(/^\[/) || - (val.length > 1 && - isQuoted(val)) || - val !== val.trim()) - ? JSON.stringify(val) - : val.replace(/;/g, '\\;').replace(/#/g, '\\#') -} - -function unsafe$1 (val, doUnesc) { - val = (val || '').trim(); - if (isQuoted(val)) { - // remove the single quotes before calling JSON.parse - if (val.charAt(0) === "'") - val = val.substr(1, val.length - 2); - - try { - val = JSON.parse(val); - } catch (_) {} - } else { - // walk the val to find the first not-escaped ; character - var esc = false; - var unesc = ''; - for (var i = 0, l = val.length; i < l; i++) { - var c = val.charAt(i); - if (esc) { - if ('\\;#'.indexOf(c) !== -1) - unesc += c; - else - unesc += '\\' + c; - - esc = false; - } else if (';#'.indexOf(c) !== -1) - break - else if (c === '\\') - esc = true; - else - unesc += c; - } - if (esc) - unesc += '\\'; - - return unesc.trim() - } - return val -} - -const fs$4 = require$$0$3; -const figgyPudding = figgyPudding_1; -const findUp = findUp$1.exports; -const ini = ini$1; -const os = require$$0$2; -const path$5 = path$b; - -const NpmConfig = figgyPudding({}, { - // Open up the pudding object. - other () { return true } -}); - -const ConfigOpts = figgyPudding({ - cache: { default: path$5.join(os.homedir(), '.npm') }, - configNames: { default: ['npmrc', '.npmrc'] }, - envPrefix: { default: /^npm_config_/i }, - cwd: { default: () => process.cwd() }, - globalconfig: { - default: () => path$5.join(getGlobalPrefix(), 'etc', 'npmrc') - }, - userconfig: { default: path$5.join(os.homedir(), '.npmrc') } -}); - -libnpmconfig.read = getNpmConfig; -function getNpmConfig (_opts, _builtin) { - const builtin = ConfigOpts(_builtin); - const env = {}; - for (let key of Object.keys(process.env)) { - if (!key.match(builtin.envPrefix)) continue - const newKey = key.toLowerCase() - .replace(builtin.envPrefix, '') - .replace(/(?!^)_/g, '-'); - env[newKey] = process.env[key]; - } - const cli = NpmConfig(_opts); - const userConfPath = ( - builtin.userconfig || - cli.userconfig || - env.userconfig - ); - const user = userConfPath && maybeReadIni(userConfPath); - const globalConfPath = ( - builtin.globalconfig || - cli.globalconfig || - env.globalconfig - ); - const global = globalConfPath && maybeReadIni(globalConfPath); - const projConfPath = findUp.sync(builtin.configNames, { cwd: builtin.cwd }); - let proj = {}; - if (projConfPath && projConfPath !== userConfPath) { - proj = maybeReadIni(projConfPath); - } - const newOpts = NpmConfig(builtin, global, user, proj, env, cli); - if (newOpts.cache) { - return newOpts.concat({ - cache: path$5.resolve( - ( - (cli.cache || env.cache) - ? builtin.cwd - : proj.cache - ? path$5.dirname(projConfPath) - : user.cache - ? path$5.dirname(userConfPath) - : global.cache - ? path$5.dirname(globalConfPath) - : path$5.dirname(userConfPath) - ), - newOpts.cache - ) - }) - } else { - return newOpts - } -} - -function maybeReadIni (f) { - let txt; - try { - txt = fs$4.readFileSync(f, 'utf8'); - } catch (err) { - if (err.code === 'ENOENT') { - return '' - } else { - throw err - } - } - return ini.parse(txt) -} - -function getGlobalPrefix () { - if (process.env.PREFIX) { - return process.env.PREFIX - } else if (process.platform === 'win32') { - // c:\node\node.exe --> prefix=c:\node\ - return path$5.dirname(process.execPath) - } else { - // /usr/local/bin/node --> prefix=/usr/local - let pref = path$5.dirname(path$5.dirname(process.execPath)); - // destdir only is respected on Unix - if (process.env.DESTDIR) { - pref = path$5.join(process.env.DESTDIR, pref); - } - return pref - } -} - -/** - * @typedef ResolveOptions - * @property {string} [prefix] - * @property {string|string[]} [cwd] - * @property {boolean} [global] - */ - -const electron = process.versions.electron !== undefined; -const windows = process.platform === 'win32'; - -const argv = process.argv[1] || /* c8 ignore next */ ''; -const nvm = process.env.NVM_BIN; -const appData = process.env.APPDATA; - -/* c8 ignore next */ -const globalsLibrary = windows ? '' : 'lib'; - -/** @type {{prefix?: string}} */ -let builtinNpmConfig; - -// The prefix config defaults to the location where node is installed. -// On Windows, this is in a place called `%AppData%`, which we have to -// pass to `libnpmconfig` explicitly: -/* c8 ignore next 4 */ -if (windows && appData) { - builtinNpmConfig = {prefix: path$b.join(appData, 'npm')}; -} - -/** - * Note: `libnpmconfig` uses `figgy-pudding` which is slated for archival. - * Either `libnpmconfig` will switch to an alternative or we’ll have to. - * @type {string} - */ -let npmPrefix = libnpmconfig.read(null, builtinNpmConfig).prefix; - -// If there is no prefix defined, use the defaults -// See: -/* c8 ignore next 5 */ -if (!npmPrefix) { - npmPrefix = windows - ? path$b.dirname(process.execPath) - : path$b.resolve(process.execPath, '../..'); -} - -const globalsDefault = electron || argv.indexOf(npmPrefix) === 0; -let globalDir = path$b.resolve(npmPrefix, globalsLibrary, 'node_modules'); - -// If we’re in Electron, we’re running in a modified Node that cannot really -// install global node modules. -// To find the actual modules, the user has to set `prefix` somewhere in an -// `.npmrc` (which is picked up by `libnpmconfig`). -// Most people don’t do that, and some use NVM instead to manage different -// versions of Node. -// Luckily NVM leaks some environment variables that we can pick up on to try -// and detect the actual modules. -/* c8 ignore next 3 */ -if (electron && nvm && !require$$0$3.existsSync(globalDir)) { - globalDir = path$b.resolve(nvm, '..', globalsLibrary, 'node_modules'); -} - -/** - * Load the plugin found using `resolvePlugin`. - * - * @param {string} name The name to import. - * @param {LoadOptions} [options] - * @returns {Promise} - */ -async function loadPlugin(name, options = {}) { - const {key = 'default', ...rest} = options; - const fp = await resolvePlugin(name, rest); - /** @type {Object.} */ - // Bug with coverage on Node@12. - /* c8 ignore next 3 */ - const mod = await import(pathToFileURL(fp).href); - return key === false ? mod : mod[key] -} - -/** - * Find a plugin. - * - * See also: - * * https://docs.npmjs.com/files/folders#node-modules - * * https://github.com/sindresorhus/resolve-from - * - * Uses the standard node module loading strategy to find `$name` in each given - * `cwd` (and optionally the global `node_modules` directory). - * - * If a prefix is given and `$name` is not a path, `$prefix-$name` is also - * searched (preferring these over non-prefixed modules). - * - * @param {string} name - * @param {ResolveOptions} [options] - * @returns {Promise.} - */ -async function resolvePlugin(name, options = {}) { - const prefix = options.prefix - ? options.prefix + - (options.prefix.charAt(options.prefix.length - 1) === '-' ? '' : '-') - : undefined; - const cwd = options.cwd; - const globals = - options.global === undefined || options.global === null - ? globalsDefault - : options.global; - const sources = Array.isArray(cwd) ? cwd.concat() : [cwd || process.cwd()]; - /** @type {string} */ - let plugin; - /** @type {Error} */ - let lastError; - - // Non-path. - if (name.charAt(0) !== '.') { - if (globals) { - sources.push(globalDir); - } - - let scope = ''; - - // Unprefix module. - if (prefix) { - // Scope? - if (name.charAt(0) === '@') { - const slash = name.indexOf('/'); - - // Let’s keep the algorithm simple. - // No need to care if this is a “valid” scope (I think?). - // But we do check for the slash. - if (slash !== -1) { - scope = name.slice(0, slash + 1); - name = name.slice(slash + 1); - } - } - - if (name.slice(0, prefix.length) !== prefix) { - plugin = scope + prefix + name; - } - - name = scope + name; - } - } - - let index = -1; - /** @type {string} */ - let fp; - - while (++index < sources.length) { - fp = plugin && (await attempt(sources[index], plugin)); - if (fp) return fp - - fp = await attempt(sources[index], name); - if (fp) return fp - } - - // There’s always an error. - // Bug with coverage on Node@12. - /* c8 ignore next 8 */ - throw lastError - - /** - * @param {string} base - * @param {string} name - * @returns {Promise} - */ - async function attempt(base, name) { - try { - // `import-meta-resolve` resolves from files, whereas `load-plugin` works - // on folders, which is why we add a `/` at the end. - return fileURLToPath( - await resolve(name, pathToFileURL(base).href + '/') - ) - // Bug with coverage on Node@12. - /* c8 ignore next 1 */ - } catch (error) { - lastError = error; - } - } -} - -function isPlainObject$1(value) { - if (Object.prototype.toString.call(value) !== '[object Object]') { - return false; - } - - const prototype = Object.getPrototypeOf(value); - return prototype === null || prototype === Object.prototype; -} - -var format$1 = {exports: {}}; - -(function (module) { -(function() { - - //// Export the API - var namespace; - - // CommonJS / Node module - { - namespace = module.exports = format; - } - - namespace.format = format; - namespace.vsprintf = vsprintf; - - if (typeof console !== 'undefined' && typeof console.log === 'function') { - namespace.printf = printf; - } - - function printf(/* ... */) { - console.log(format.apply(null, arguments)); - } - - function vsprintf(fmt, replacements) { - return format.apply(null, [fmt].concat(replacements)); - } - - function format(fmt) { - var argIndex = 1 // skip initial format argument - , args = [].slice.call(arguments) - , i = 0 - , n = fmt.length - , result = '' - , c - , escaped = false - , arg - , tmp - , leadingZero = false - , precision - , nextArg = function() { return args[argIndex++]; } - , slurpNumber = function() { - var digits = ''; - while (/\d/.test(fmt[i])) { - digits += fmt[i++]; - c = fmt[i]; - } - return digits.length > 0 ? parseInt(digits) : null; - } - ; - for (; i < n; ++i) { - c = fmt[i]; - if (escaped) { - escaped = false; - if (c == '.') { - leadingZero = false; - c = fmt[++i]; - } - else if (c == '0' && fmt[i + 1] == '.') { - leadingZero = true; - i += 2; - c = fmt[i]; - } - else { - leadingZero = true; - } - precision = slurpNumber(); - switch (c) { - case 'b': // number in binary - result += parseInt(nextArg(), 10).toString(2); - break; - case 'c': // character - arg = nextArg(); - if (typeof arg === 'string' || arg instanceof String) - result += arg; - else - result += String.fromCharCode(parseInt(arg, 10)); - break; - case 'd': // number in decimal - result += parseInt(nextArg(), 10); - break; - case 'f': // floating point number - tmp = String(parseFloat(nextArg()).toFixed(precision || 6)); - result += leadingZero ? tmp : tmp.replace(/^0/, ''); - break; - case 'j': // JSON - result += JSON.stringify(nextArg()); - break; - case 'o': // number in octal - result += '0' + parseInt(nextArg(), 10).toString(8); - break; - case 's': // string - result += nextArg(); - break; - case 'x': // lowercase hexadecimal - result += '0x' + parseInt(nextArg(), 10).toString(16); - break; - case 'X': // uppercase hexadecimal - result += '0x' + parseInt(nextArg(), 10).toString(16).toUpperCase(); - break; - default: - result += c; - break; - } - } else if (c === '%') { - escaped = true; - } else { - result += c; - } - } - return result; - } - -}()); -}(format$1)); - -var formatter = format$1.exports; - -// @ts-ignore - -var fault = Object.assign(create$1(Error), { - eval: create$1(EvalError), - range: create$1(RangeError), - reference: create$1(ReferenceError), - syntax: create$1(SyntaxError), - type: create$1(TypeError), - uri: create$1(URIError) -}); - -/** - * Create a new `EConstructor`, with the formatted `format` as a first argument. - * - * @template {Error} Fault - * @template {new (reason: string) => Fault} Class - * @param {Class} Constructor - */ -function create$1(Constructor) { - /** @type {string} */ - // @ts-ignore - FormattedError.displayName = Constructor.displayName || Constructor.name; - - return FormattedError - - /** - * @param {string} [format] - * @param {...unknown} values - * @returns {Fault} - */ - function FormattedError(format, ...values) { - /** @type {string} */ - var reason = format ? formatter(format, ...values) : format; - return new Constructor(reason) - } -} - -const debug$b = createDebug('unified-engine:find-up'); - -/** - * @template Value - */ -class FindUp { - /** - * @callback Create - * @param {Buffer} buf - * @param {string} filePath - * @returns {Promise|Value|undefined} - */ - - /** - * @callback Callback - * @param {Error|null} error - * @param {Value} [result] - * @returns {void} - */ - - /** - * @typedef Options - * @property {string} cwd - * @property {string|undefined} filePath - * @property {boolean|undefined} [detect] - * @property {string[]} names - * @property {Create} create - */ - - /** - * @param {Options} options - */ - constructor(options) { - /** @type {Record} */ - this.cache = {}; - /** @type {string} */ - this.cwd = options.cwd; - /** @type {boolean|undefined} */ - this.detect = options.detect; - /** @type {string[]} */ - this.names = options.names; - /** @type {Create} */ - this.create = options.create; - - /** @type {string|undefined} */ - this.givenFilePath = options.filePath - ? path$c.resolve(options.cwd, options.filePath) - : undefined; - - /* eslint-disable no-unused-expressions */ - /** @type {Error|Value|Callback[]|undefined} */ - this.givenFile; - /* eslint-enable no-unused-expressions */ - } - - /** - * @param {string} filePath - * @param {Callback} callback - */ - load(filePath, callback) { - const self = this; - const givenFile = this.givenFile; - const {givenFilePath} = this; - - if (givenFilePath) { - if (givenFile) { - apply(callback, givenFile); - } else { - const cbs = [callback]; - this.givenFile = cbs; - debug$b('Checking given file `%s`', givenFilePath); - fs$a.readFile(givenFilePath, (error, buf) => { - if (error) { - /** @type {NodeJS.ErrnoException} */ - const result = fault( - 'Cannot read given file `%s`\n%s', - path$c.relative(this.cwd, givenFilePath), - error.stack - ); - result.code = 'ENOENT'; - result.path = error.path; - result.syscall = error.syscall; - loaded(result); - } else { - wrap(this.create, (error, /** @type {Value} */ result) => { - if (error) { - debug$b(error.message); - loaded( - fault( - 'Cannot parse given file `%s`\n%s', - path$c.relative(this.cwd, givenFilePath), - error.stack - ) - ); - } else { - debug$b('Read given file `%s`', givenFilePath); - loaded(result); - } - })(buf, givenFilePath); - } - - /** @param {Error|Value} result */ - function loaded(result) { - self.givenFile = result; - applyAll(cbs, result); - } - }); - } - - return - } - - if (!this.detect) { - return callback(null) - } - - filePath = path$c.resolve(this.cwd, filePath); - const parent = path$c.dirname(filePath); - - if (parent in this.cache) { - apply(callback, this.cache[parent]); - } else { - this.cache[parent] = [callback]; - find(parent); - } - - /** - * @param {string} directory - */ - function find(directory) { - let index = -1; - - next(); - - function next() { - // Try to read the next file. - // We do not use `readdir` because on huge directories, that could be - // *very* slow. - if (++index < self.names.length) { - fs$a.readFile(path$c.join(directory, self.names[index]), done); - } else { - const parent = path$c.dirname(directory); - - if (directory === parent) { - debug$b('No files found for `%s`', filePath); - found(null); - } else if (parent in self.cache) { - apply(found, self.cache[parent]); - } else { - self.cache[parent] = [found]; - find(parent); - } - } - } - - /** - * @param {NodeJS.ErrnoException|null} error - * @param {Buffer} [buf] - * @returns {void} - */ - function done(error, buf) { - const fp = path$c.join(directory, self.names[index]); - - if (error) { - // Hard to test. - /* c8 ignore next 13 */ - if (error.code === 'ENOENT') { - return next() - } - - debug$b(error.message); - return found( - fault( - 'Cannot read file `%s`\n%s', - path$c.relative(self.cwd, fp), - error.message - ) - ) - } - - wrap(self.create, (error, /** @type {Value} */ result) => { - if (error) { - found( - fault( - 'Cannot parse file `%s`\n%s', - path$c.relative(self.cwd, fp), - error.message - ) - ); - } else if (result) { - debug$b('Read file `%s`', fp); - found(null, result); - } else { - next(); - } - })(buf, fp); - } - - /** - * @param {Error|null} error - * @param {Value} [result] - * @returns {void} - */ - function found(error, result) { - /** @type {Callback[]} */ - // @ts-expect-error: always a list if found. - const cbs = self.cache[directory]; - self.cache[directory] = error || result; - applyAll(cbs, error || result); - } - } - - /** - * @param {Callback[]} cbs - * @param {Value|Error|undefined} result - */ - function applyAll(cbs, result) { - let index = cbs.length; - - while (index--) { - apply(cbs[index], result); - } - } - - /** - * @param {Callback} cb - * @param {Value|Error|Callback[]|undefined} result - */ - function apply(cb, result) { - if (Array.isArray(result)) { - result.push(cb); - } else if (result instanceof Error) { - cb(result); - } else { - cb(null, result); - } - } - } -} - -/** - * @typedef {import('unified').Plugin} Plugin - * @typedef {import('unified').PluginTuple} PluginTuple - * @typedef {import('unified').PluggableList} PluggableList - * - * @typedef {Record} Settings - * - * @typedef {Record} PluginIdObject - * @typedef {Array} PluginIdList - * - * @typedef Preset - * @property {Settings} [settings] - * @property {PluggableList|PluginIdObject|PluginIdList|undefined} [plugins] - * - * @typedef Config - * @property {Settings} [settings] - * @property {Array} [plugins] - * - * @callback ConfigTransform - * @param {any} config - * @param {string} filePath - * @returns {Preset} - * - * @callback Loader - * @param {Buffer} buf - * @param {string} filePath - * @returns {Promise} - * - * @callback Callback - * @param {Error|null} error - * @param {Config} [result] - * @returns {void} - */ - -const debug$a = createDebug('unified-engine:configuration'); - -const own$c = {}.hasOwnProperty; - -/** @type {Record} */ -const loaders = { - '.json': loadJson, - '.cjs': loadScriptOrModule, - '.mjs': loadScriptOrModule, - '.js': loadScriptOrModule, - '.yaml': loadYaml, - '.yml': loadYaml -}; - -const defaultLoader = loadJson; - -/** - * @typedef Options - * @property {string} cwd - * @property {string} [packageField] - * @property {string} [pluginPrefix] - * @property {string} [rcName] - * @property {string} [rcPath] - * @property {boolean} [detectConfig] - * @property {ConfigTransform} [configTransform] - * @property {Preset} [defaultConfig] - * @property {Preset['settings']} [settings] - * @property {Preset['plugins']} [plugins] - */ - -class Configuration { - /** - * @param {Options} options - */ - constructor(options) { - /** @type {string[]} */ - const names = []; - - /** @type {string} */ - this.cwd = options.cwd; - /** @type {string|undefined} */ - this.packageField = options.packageField; - /** @type {string|undefined} */ - this.pluginPrefix = options.pluginPrefix; - /** @type {ConfigTransform|undefined} */ - this.configTransform = options.configTransform; - /** @type {Preset|undefined} */ - this.defaultConfig = options.defaultConfig; - - if (options.rcName) { - names.push( - options.rcName, - ...Object.keys(loaders).map((d) => options.rcName + d) - ); - debug$a('Looking for `%s` configuration files', names); - } - - if (options.packageField) { - names.push('package.json'); - debug$a( - 'Looking for `%s` fields in `package.json` files', - options.packageField - ); - } - - /** @type {Preset} */ - this.given = {settings: options.settings, plugins: options.plugins}; - this.create = this.create.bind(this); - - /** @type {FindUp} */ - this.findUp = new FindUp({ - cwd: options.cwd, - filePath: options.rcPath, - detect: options.detectConfig, - names, - create: this.create - }); - } - - /** - * @param {string} filePath - * @param {Callback} callback - * @returns {void} - */ - load(filePath, callback) { - this.findUp.load( - filePath || path$c.resolve(this.cwd, 'stdin.js'), - (error, file) => { - if (error || file) { - return callback(error, file) - } - - this.create(undefined, undefined).then((result) => { - callback(null, result); - }, callback); - } - ); - } - - /** - * @param {Buffer|undefined} buf - * @param {string|undefined} filePath - * @returns {Promise} - */ - async create(buf, filePath) { - const options = {prefix: this.pluginPrefix, cwd: this.cwd}; - const result = {settings: {}, plugins: []}; - const extname = filePath ? path$c.extname(filePath) : undefined; - const loader = - extname && extname in loaders ? loaders[extname] : defaultLoader; - /** @type {Preset|undefined} */ - let value; - - if (filePath && buf) { - value = await loader.call(this, buf, filePath); - - if (this.configTransform && value !== undefined) { - value = this.configTransform(value, filePath); - } - } - - // Exit if we did find a `package.json`, but it does not have configuration. - if ( - filePath && - value === undefined && - path$c.basename(filePath) === 'package.json' - ) { - return - } - - if (value === undefined) { - if (this.defaultConfig) { - await merge( - result, - this.defaultConfig, - Object.assign({}, options, {root: this.cwd}) - ); - } - } else { - await merge( - result, - value, - // @ts-expect-error: `value` can only exist if w/ `filePath`. - Object.assign({}, options, {root: path$c.dirname(filePath)}) - ); - } - - await merge( - result, - this.given, - Object.assign({}, options, {root: this.cwd}) - ); - - // C8 bug on Node@12 - /* c8 ignore next 2 */ - return result - } -} - -/** @type {Loader} */ -async function loadScriptOrModule(_, filePath) { - // C8 bug on Node@12 - /* c8 ignore next 4 */ - // @ts-expect-error: Assume it matches config. - // type-coverage:ignore-next-line - return loadFromAbsolutePath(filePath, this.cwd) -} - -/** @type {Loader} */ -async function loadYaml(buf, filePath) { - // C8 bug on Node@12 - /* c8 ignore next 4 */ - // @ts-expect-error: Assume it matches config. - return jsYaml.load(String(buf), {filename: path$c.basename(filePath)}) -} - -/** @type {Loader} */ -async function loadJson(buf, filePath) { - /** @type {Record} */ - const result = parseJson_1(String(buf), filePath); - - // C8 bug on Node@12 - /* c8 ignore next 8 */ - // @ts-expect-error: Assume it matches config. - return path$c.basename(filePath) === 'package.json' - ? // @ts-expect-error: `this` is the configuration context, TS doesn’t like - // `this` on callbacks. - // type-coverage:ignore-next-line - result[this.packageField] - : result -} - -/** - * @param {Required} target - * @param {Preset} raw - * @param {{root: string, prefix: string|undefined}} options - * @returns {Promise} - */ -async function merge(target, raw, options) { - if (typeof raw === 'object' && raw !== null) { - await addPreset(raw); - } else { - throw new Error('Expected preset, not `' + raw + '`') - } - - // C8 bug on Node@12 - /* c8 ignore next 6 */ - return target - - /** - * @param {Preset} result - */ - async function addPreset(result) { - const plugins = result.plugins; - - if (plugins === null || plugins === undefined) ; else if (typeof plugins === 'object' && plugins !== null) { - await (Array.isArray(plugins) ? addEach(plugins) : addIn(plugins)); - } else { - throw new Error( - 'Expected a list or object of plugins, not `' + plugins + '`' - ) - } - - target.settings = Object.assign({}, target.settings, result.settings); - // C8 bug on Node@12 - /* c8 ignore next 6 */ - } - - /** - * @param {PluginIdList|PluggableList} result - */ - async function addEach(result) { - let index = -1; - - while (++index < result.length) { - const value = result[index]; - - // Keep order sequential instead of parallel. - /* eslint-disable no-await-in-loop */ - // @ts-expect-error: Spreading is fine. - // type-coverage:ignore-next-line - await (Array.isArray(value) ? use(...value) : use(value, undefined)); - /* eslint-enable no-await-in-loop */ - } - // C8 bug on Node@12 - /* c8 ignore next 6 */ - } - - /** - * @param {PluginIdObject} result - */ - async function addIn(result) { - /** @type {string} */ - let key; - - for (key in result) { - if (own$c.call(result, key)) { - // Keep order sequential instead of parallel. - // eslint-disable-next-line no-await-in-loop - await use(key, result[key]); - } - } - // C8 bug on Node@12 - /* c8 ignore next 7 */ - } - - /** - * @param {string|Plugin|Preset} usable - * @param {Settings|null|undefined} value - */ - async function use(usable, value) { - if (typeof usable === 'string') { - await addModule(usable, value); - } else if (typeof usable === 'function') { - addPlugin(usable, value); - } else { - await merge(target, usable, options); - } - // C8 bug on Node@12 - /* c8 ignore next 7 */ - } - - /** - * @param {string} id - * @param {Settings|null|undefined} value - */ - async function addModule(id, value) { - /** @type {string} */ - let fp; - - try { - fp = await resolvePlugin(id, { - cwd: options.root, - prefix: options.prefix - }); - } catch (error) { - addPlugin(() => { - throw fault('Could not find module `%s`\n%s', id, error.stack) - }, value); - return - } - - const result = await loadFromAbsolutePath(fp, options.root); - - try { - if (typeof result === 'function') { - addPlugin(result, value); - } else { - await merge( - target, - result, - Object.assign({}, options, {root: path$c.dirname(fp)}) - ); - } - } catch { - throw fault( - 'Error: Expected preset or plugin, not %s, at `%s`', - result, - path$c.relative(options.root, fp) - ) - } - // C8 bug on Node@12 - /* c8 ignore next 8 */ - } - - /** - * @param {Plugin} plugin - * @param {Settings|null|undefined} value - * @returns {void} - */ - function addPlugin(plugin, value) { - const entry = find(target.plugins, plugin); - - if (value === null) { - value = undefined; - } - - if (entry) { - reconfigure(entry, value); - } else { - target.plugins.push([plugin, value]); - } - } -} - -/** - * @param {PluginTuple} entry - * @param {Settings|undefined} value - * @returns {void} - */ -function reconfigure(entry, value) { - if (isPlainObject$1(entry[1]) && isPlainObject$1(value)) { - value = Object.assign({}, entry[1], value); - } - - entry[1] = value; -} - -/** - * @param {Array} entries - * @param {Plugin} plugin - * @returns {PluginTuple|undefined} - */ -function find(entries, plugin) { - let index = -1; - - while (++index < entries.length) { - const entry = entries[index]; - if (entry[0] === plugin) { - return entry - } - } -} - -/** - * @param {string} fp - * @param {string} base - * @returns {Promise} - */ -async function loadFromAbsolutePath(fp, base) { - try { - /** @type {{default?: unknown}} */ - const result = await import(pathToFileURL$1(fp).href); - - if (!('default' in result)) { - throw new Error( - 'Expected a plugin or preset exported as the default export' - ) - } - - // @ts-expect-error: assume plugin/preset. - return result.default - // C8 bug on Node@12 - /* c8 ignore next 4 */ - } catch (error) { - throw fault('Cannot import `%s`\n%s', path$c.relative(base, fp), error.stack) - } -} - -/** - * @typedef {import('./index.js').Settings} Settings - */ - -/** - * @param {Context} context - * @param {Settings} settings - */ -function configure$3(context, settings) { - context.configuration = new Configuration(settings); -} - -// A simple implementation of make-array -function makeArray (subject) { - return Array.isArray(subject) - ? subject - : [subject] -} - -const EMPTY = ''; -const SPACE = ' '; -const ESCAPE = '\\'; -const REGEX_TEST_BLANK_LINE = /^\s+$/; -const REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION = /^\\!/; -const REGEX_REPLACE_LEADING_EXCAPED_HASH = /^\\#/; -const REGEX_SPLITALL_CRLF = /\r?\n/g; -// /foo, -// ./foo, -// ../foo, -// . -// .. -const REGEX_TEST_INVALID_PATH = /^\.*\/|^\.+$/; - -const SLASH = '/'; -const KEY_IGNORE = typeof Symbol !== 'undefined' - ? Symbol.for('node-ignore') - /* istanbul ignore next */ - : 'node-ignore'; - -const define = (object, key, value) => - Object.defineProperty(object, key, {value}); - -const REGEX_REGEXP_RANGE = /([0-z])-([0-z])/g; - -// Sanitize the range of a regular expression -// The cases are complicated, see test cases for details -const sanitizeRange = range => range.replace( - REGEX_REGEXP_RANGE, - (match, from, to) => from.charCodeAt(0) <= to.charCodeAt(0) - ? match - // Invalid range (out of order) which is ok for gitignore rules but - // fatal for JavaScript regular expression, so eliminate it. - : EMPTY -); - -// See fixtures #59 -const cleanRangeBackSlash = slashes => { - const {length} = slashes; - return slashes.slice(0, length - length % 2) -}; - -// > If the pattern ends with a slash, -// > it is removed for the purpose of the following description, -// > but it would only find a match with a directory. -// > In other words, foo/ will match a directory foo and paths underneath it, -// > but will not match a regular file or a symbolic link foo -// > (this is consistent with the way how pathspec works in general in Git). -// '`foo/`' will not match regular file '`foo`' or symbolic link '`foo`' -// -> ignore-rules will not deal with it, because it costs extra `fs.stat` call -// you could use option `mark: true` with `glob` - -// '`foo/`' should not continue with the '`..`' -const REPLACERS = [ - - // > Trailing spaces are ignored unless they are quoted with backslash ("\") - [ - // (a\ ) -> (a ) - // (a ) -> (a) - // (a \ ) -> (a ) - /\\?\s+$/, - match => match.indexOf('\\') === 0 - ? SPACE - : EMPTY - ], - - // replace (\ ) with ' ' - [ - /\\\s/g, - () => SPACE - ], - - // Escape metacharacters - // which is written down by users but means special for regular expressions. - - // > There are 12 characters with special meanings: - // > - the backslash \, - // > - the caret ^, - // > - the dollar sign $, - // > - the period or dot ., - // > - the vertical bar or pipe symbol |, - // > - the question mark ?, - // > - the asterisk or star *, - // > - the plus sign +, - // > - the opening parenthesis (, - // > - the closing parenthesis ), - // > - and the opening square bracket [, - // > - the opening curly brace {, - // > These special characters are often called "metacharacters". - [ - /[\\$.|*+(){^]/g, - match => `\\${match}` - ], - - [ - // > a question mark (?) matches a single character - /(?!\\)\?/g, - () => '[^/]' - ], - - // leading slash - [ - - // > A leading slash matches the beginning of the pathname. - // > For example, "/*.c" matches "cat-file.c" but not "mozilla-sha1/sha1.c". - // A leading slash matches the beginning of the pathname - /^\//, - () => '^' - ], - - // replace special metacharacter slash after the leading slash - [ - /\//g, - () => '\\/' - ], - - [ - // > A leading "**" followed by a slash means match in all directories. - // > For example, "**/foo" matches file or directory "foo" anywhere, - // > the same as pattern "foo". - // > "**/foo/bar" matches file or directory "bar" anywhere that is directly - // > under directory "foo". - // Notice that the '*'s have been replaced as '\\*' - /^\^*\\\*\\\*\\\//, - - // '**/foo' <-> 'foo' - () => '^(?:.*\\/)?' - ], - - // starting - [ - // there will be no leading '/' - // (which has been replaced by section "leading slash") - // If starts with '**', adding a '^' to the regular expression also works - /^(?=[^^])/, - function startingReplacer () { - // If has a slash `/` at the beginning or middle - return !/\/(?!$)/.test(this) - // > Prior to 2.22.1 - // > If the pattern does not contain a slash /, - // > Git treats it as a shell glob pattern - // Actually, if there is only a trailing slash, - // git also treats it as a shell glob pattern - - // After 2.22.1 (compatible but clearer) - // > If there is a separator at the beginning or middle (or both) - // > of the pattern, then the pattern is relative to the directory - // > level of the particular .gitignore file itself. - // > Otherwise the pattern may also match at any level below - // > the .gitignore level. - ? '(?:^|\\/)' - - // > Otherwise, Git treats the pattern as a shell glob suitable for - // > consumption by fnmatch(3) - : '^' - } - ], - - // two globstars - [ - // Use lookahead assertions so that we could match more than one `'/**'` - /\\\/\\\*\\\*(?=\\\/|$)/g, - - // Zero, one or several directories - // should not use '*', or it will be replaced by the next replacer - - // Check if it is not the last `'/**'` - (_, index, str) => index + 6 < str.length - - // case: /**/ - // > A slash followed by two consecutive asterisks then a slash matches - // > zero or more directories. - // > For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on. - // '/**/' - ? '(?:\\/[^\\/]+)*' - - // case: /** - // > A trailing `"/**"` matches everything inside. - - // #21: everything inside but it should not include the current folder - : '\\/.+' - ], - - // intermediate wildcards - [ - // Never replace escaped '*' - // ignore rule '\*' will match the path '*' - - // 'abc.*/' -> go - // 'abc.*' -> skip this rule - /(^|[^\\]+)\\\*(?=.+)/g, - - // '*.js' matches '.js' - // '*.js' doesn't match 'abc' - (_, p1) => `${p1}[^\\/]*` - ], - - [ - // unescape, revert step 3 except for back slash - // For example, if a user escape a '\\*', - // after step 3, the result will be '\\\\\\*' - /\\\\\\(?=[$.|*+(){^])/g, - () => ESCAPE - ], - - [ - // '\\\\' -> '\\' - /\\\\/g, - () => ESCAPE - ], - - [ - // > The range notation, e.g. [a-zA-Z], - // > can be used to match one of the characters in a range. - - // `\` is escaped by step 3 - /(\\)?\[([^\]/]*?)(\\*)($|\])/g, - (match, leadEscape, range, endEscape, close) => leadEscape === ESCAPE - // '\\[bar]' -> '\\\\[bar\\]' - ? `\\[${range}${cleanRangeBackSlash(endEscape)}${close}` - : close === ']' - ? endEscape.length % 2 === 0 - // A normal case, and it is a range notation - // '[bar]' - // '[bar\\\\]' - ? `[${sanitizeRange(range)}${endEscape}]` - // Invalid range notaton - // '[bar\\]' -> '[bar\\\\]' - : '[]' - : '[]' - ], - - // ending - [ - // 'js' will not match 'js.' - // 'ab' will not match 'abc' - /(?:[^*])$/, - - // WTF! - // https://git-scm.com/docs/gitignore - // changes in [2.22.1](https://git-scm.com/docs/gitignore/2.22.1) - // which re-fixes #24, #38 - - // > If there is a separator at the end of the pattern then the pattern - // > will only match directories, otherwise the pattern can match both - // > files and directories. - - // 'js*' will not match 'a.js' - // 'js/' will not match 'a.js' - // 'js' will match 'a.js' and 'a.js/' - match => /\/$/.test(match) - // foo/ will not match 'foo' - ? `${match}$` - // foo matches 'foo' and 'foo/' - : `${match}(?=$|\\/$)` - ], - - // trailing wildcard - [ - /(\^|\\\/)?\\\*$/, - (_, p1) => { - const prefix = p1 - // '\^': - // '/*' does not match EMPTY - // '/*' does not match everything - - // '\\\/': - // 'abc/*' does not match 'abc/' - ? `${p1}[^/]+` - - // 'a*' matches 'a' - // 'a*' matches 'aa' - : '[^/]*'; - - return `${prefix}(?=$|\\/$)` - } - ], -]; - -// A simple cache, because an ignore rule only has only one certain meaning -const regexCache = Object.create(null); - -// @param {pattern} -const makeRegex = (pattern, negative, ignorecase) => { - const r = regexCache[pattern]; - if (r) { - return r - } - - // const replacers = negative - // ? NEGATIVE_REPLACERS - // : POSITIVE_REPLACERS - - const source = REPLACERS.reduce( - (prev, current) => prev.replace(current[0], current[1].bind(pattern)), - pattern - ); - - return regexCache[pattern] = ignorecase - ? new RegExp(source, 'i') - : new RegExp(source) -}; - -const isString = subject => typeof subject === 'string'; - -// > A blank line matches no files, so it can serve as a separator for readability. -const checkPattern = pattern => pattern - && isString(pattern) - && !REGEX_TEST_BLANK_LINE.test(pattern) - - // > A line starting with # serves as a comment. - && pattern.indexOf('#') !== 0; - -const splitPattern = pattern => pattern.split(REGEX_SPLITALL_CRLF); - -class IgnoreRule { - constructor ( - origin, - pattern, - negative, - regex - ) { - this.origin = origin; - this.pattern = pattern; - this.negative = negative; - this.regex = regex; - } -} - -const createRule = (pattern, ignorecase) => { - const origin = pattern; - let negative = false; - - // > An optional prefix "!" which negates the pattern; - if (pattern.indexOf('!') === 0) { - negative = true; - pattern = pattern.substr(1); - } - - pattern = pattern - // > Put a backslash ("\") in front of the first "!" for patterns that - // > begin with a literal "!", for example, `"\!important!.txt"`. - .replace(REGEX_REPLACE_LEADING_EXCAPED_EXCLAMATION, '!') - // > Put a backslash ("\") in front of the first hash for patterns that - // > begin with a hash. - .replace(REGEX_REPLACE_LEADING_EXCAPED_HASH, '#'); - - const regex = makeRegex(pattern, negative, ignorecase); - - return new IgnoreRule( - origin, - pattern, - negative, - regex - ) -}; - -const throwError = (message, Ctor) => { - throw new Ctor(message) -}; - -const checkPath = (path, originalPath, doThrow) => { - if (!isString(path)) { - return doThrow( - `path must be a string, but got \`${originalPath}\``, - TypeError - ) - } - - // We don't know if we should ignore EMPTY, so throw - if (!path) { - return doThrow(`path must not be empty`, TypeError) - } - - // Check if it is a relative path - if (checkPath.isNotRelative(path)) { - const r = '`path.relative()`d'; - return doThrow( - `path should be a ${r} string, but got "${originalPath}"`, - RangeError - ) - } - - return true -}; - -const isNotRelative = path => REGEX_TEST_INVALID_PATH.test(path); - -checkPath.isNotRelative = isNotRelative; -checkPath.convert = p => p; - -class Ignore$1 { - constructor ({ - ignorecase = true - } = {}) { - this._rules = []; - this._ignorecase = ignorecase; - define(this, KEY_IGNORE, true); - this._initCache(); - } - - _initCache () { - this._ignoreCache = Object.create(null); - this._testCache = Object.create(null); - } - - _addPattern (pattern) { - // #32 - if (pattern && pattern[KEY_IGNORE]) { - this._rules = this._rules.concat(pattern._rules); - this._added = true; - return - } - - if (checkPattern(pattern)) { - const rule = createRule(pattern, this._ignorecase); - this._added = true; - this._rules.push(rule); - } - } - - // @param {Array | string | Ignore} pattern - add (pattern) { - this._added = false; - - makeArray( - isString(pattern) - ? splitPattern(pattern) - : pattern - ).forEach(this._addPattern, this); - - // Some rules have just added to the ignore, - // making the behavior changed. - if (this._added) { - this._initCache(); - } - - return this - } - - // legacy - addPattern (pattern) { - return this.add(pattern) - } - - // | ignored : unignored - // negative | 0:0 | 0:1 | 1:0 | 1:1 - // -------- | ------- | ------- | ------- | -------- - // 0 | TEST | TEST | SKIP | X - // 1 | TESTIF | SKIP | TEST | X - - // - SKIP: always skip - // - TEST: always test - // - TESTIF: only test if checkUnignored - // - X: that never happen - - // @param {boolean} whether should check if the path is unignored, - // setting `checkUnignored` to `false` could reduce additional - // path matching. - - // @returns {TestResult} true if a file is ignored - _testOne (path, checkUnignored) { - let ignored = false; - let unignored = false; - - this._rules.forEach(rule => { - const {negative} = rule; - if ( - unignored === negative && ignored !== unignored - || negative && !ignored && !unignored && !checkUnignored - ) { - return - } - - const matched = rule.regex.test(path); - - if (matched) { - ignored = !negative; - unignored = negative; - } - }); - - return { - ignored, - unignored - } - } - - // @returns {TestResult} - _test (originalPath, cache, checkUnignored, slices) { - const path = originalPath - // Supports nullable path - && checkPath.convert(originalPath); - - checkPath(path, originalPath, throwError); - - return this._t(path, cache, checkUnignored, slices) - } - - _t (path, cache, checkUnignored, slices) { - if (path in cache) { - return cache[path] - } - - if (!slices) { - // path/to/a.js - // ['path', 'to', 'a.js'] - slices = path.split(SLASH); - } - - slices.pop(); - - // If the path has no parent directory, just test it - if (!slices.length) { - return cache[path] = this._testOne(path, checkUnignored) - } - - const parent = this._t( - slices.join(SLASH) + SLASH, - cache, - checkUnignored, - slices - ); - - // If the path contains a parent directory, check the parent first - return cache[path] = parent.ignored - // > It is not possible to re-include a file if a parent directory of - // > that file is excluded. - ? parent - : this._testOne(path, checkUnignored) - } - - ignores (path) { - return this._test(path, this._ignoreCache, false).ignored - } - - createFilter () { - return path => !this.ignores(path) - } - - filter (paths) { - return makeArray(paths).filter(this.createFilter()) - } - - // @returns {TestResult} - test (path) { - return this._test(path, this._testCache, true) - } -} - -const factory$1 = options => new Ignore$1(options); - -const returnFalse = () => false; - -const isPathValid = path => - checkPath(path && checkPath.convert(path), path, returnFalse); - -factory$1.isPathValid = isPathValid; - -// Fixes typescript -factory$1.default = factory$1; - -var ignore = factory$1; - -// Windows -// -------------------------------------------------------------- -/* istanbul ignore if */ -if ( - // Detect `process` so that it can run in browsers. - typeof process !== 'undefined' - && ( - process.env && process.env.IGNORE_TEST_WIN32 - || process.platform === 'win32' - ) -) { - /* eslint no-control-regex: "off" */ - const makePosix = str => /^\\\\\?\\/.test(str) - || /["<>|\u0000-\u001F]+/u.test(str) - ? str - : str.replace(/\\/g, '/'); - - checkPath.convert = makePosix; - - // 'C:\\foo' <- 'C:\\foo' has been converted to 'C:/' - // 'd:\\foo' - const REGIX_IS_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i; - checkPath.isNotRelative = path => - REGIX_IS_WINDOWS_PATH_ABSOLUTE.test(path) - || isNotRelative(path); -} - -/** - * @typedef {import('ignore').Ignore & {filePath: string}} IgnoreConfig - * - * @typedef {'cwd'|'dir'} ResolveFrom - * - * @typedef Options - * @property {string} cwd - * @property {boolean|undefined} detectIgnore - * @property {string|undefined} ignoreName - * @property {string|undefined} ignorePath - * @property {ResolveFrom|undefined} ignorePathResolveFrom - * - * @callback Callback - * @param {Error|null} error - * @param {boolean|undefined} [result] - */ - -class Ignore { - /** - * @param {Options} options - */ - constructor(options) { - /** @type {string} */ - this.cwd = options.cwd; - /** @type {ResolveFrom|undefined} */ - this.ignorePathResolveFrom = options.ignorePathResolveFrom; - - /** @type {FindUp} */ - this.findUp = new FindUp({ - cwd: options.cwd, - filePath: options.ignorePath, - detect: options.detectIgnore, - names: options.ignoreName ? [options.ignoreName] : [], - create - }); - } - - /** - * @param {string} filePath - * @param {Callback} callback - */ - check(filePath, callback) { - this.findUp.load(filePath, (error, ignoreSet) => { - if (error) { - callback(error); - } else if (ignoreSet) { - const normal = path$c.relative( - path$c.resolve( - this.cwd, - this.ignorePathResolveFrom === 'cwd' ? '.' : ignoreSet.filePath - ), - path$c.resolve(this.cwd, filePath) - ); - - if ( - normal === '' || - normal === '..' || - normal.charAt(0) === path$c.sep || - normal.slice(0, 3) === '..' + path$c.sep - ) { - callback(null, false); - } else { - callback(null, ignoreSet.ignores(normal)); - } - } else { - callback(null, false); - } - }); - } -} - -/** - * @param {Buffer} buf - * @param {string} filePath - * @returns {IgnoreConfig} - */ -function create(buf, filePath) { - /** @type {IgnoreConfig} */ - return Object.assign(ignore().add(String(buf)), { - filePath: path$c.dirname(filePath) - }) -} - -var old$1 = {}; - -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -var pathModule = path$b; -var isWindows = process.platform === 'win32'; -var fs$3 = require$$0$3; - -// JavaScript implementation of realpath, ported from node pre-v6 - -var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG); - -function rethrow() { - // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and - // is fairly slow to generate. - var callback; - if (DEBUG) { - var backtrace = new Error; - callback = debugCallback; - } else - callback = missingCallback; - - return callback; - - function debugCallback(err) { - if (err) { - backtrace.message = err.message; - err = backtrace; - missingCallback(err); - } - } - - function missingCallback(err) { - if (err) { - if (process.throwDeprecation) - throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs - else if (!process.noDeprecation) { - var msg = 'fs: missing callback ' + (err.stack || err.message); - if (process.traceDeprecation) - console.trace(msg); - else - console.error(msg); - } - } - } -} - -function maybeCallback(cb) { - return typeof cb === 'function' ? cb : rethrow(); -} - -pathModule.normalize; - -// Regexp that finds the next partion of a (partial) path -// result is [base_with_slash, base], e.g. ['somedir/', 'somedir'] -if (isWindows) { - var nextPartRe = /(.*?)(?:[\/\\]+|$)/g; -} else { - var nextPartRe = /(.*?)(?:[\/]+|$)/g; -} - -// Regex to find the device root, including trailing slash. E.g. 'c:\\'. -if (isWindows) { - var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/; -} else { - var splitRootRe = /^[\/]*/; -} - -old$1.realpathSync = function realpathSync(p, cache) { - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return cache[p]; - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs$3.lstatSync(base); - knownHard[base] = true; - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - // NB: p.length changes. - while (pos < p.length) { - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - continue; - } - - var resolvedLink; - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // some known symbolic link. no need to stat again. - resolvedLink = cache[base]; - } else { - var stat = fs$3.lstatSync(base); - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - continue; - } - - // read the link if it wasn't read before - // dev/ino always return 0 on windows, so skip the check. - var linkTarget = null; - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - linkTarget = seenLinks[id]; - } - } - if (linkTarget === null) { - fs$3.statSync(base); - linkTarget = fs$3.readlinkSync(base); - } - resolvedLink = pathModule.resolve(previous, linkTarget); - // track this, if given a cache. - if (cache) cache[base] = resolvedLink; - if (!isWindows) seenLinks[id] = linkTarget; - } - - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } - - if (cache) cache[original] = p; - - return p; -}; - - -old$1.realpath = function realpath(p, cache, cb) { - if (typeof cb !== 'function') { - cb = maybeCallback(cache); - cache = null; - } - - // make p is absolute - p = pathModule.resolve(p); - - if (cache && Object.prototype.hasOwnProperty.call(cache, p)) { - return process.nextTick(cb.bind(null, null, cache[p])); - } - - var original = p, - seenLinks = {}, - knownHard = {}; - - // current character position in p - var pos; - // the partial path so far, including a trailing slash if any - var current; - // the partial path without a trailing slash (except when pointing at a root) - var base; - // the partial path scanned in the previous round, with slash - var previous; - - start(); - - function start() { - // Skip over roots - var m = splitRootRe.exec(p); - pos = m[0].length; - current = m[0]; - base = m[0]; - previous = ''; - - // On windows, check that the root exists. On unix there is no need. - if (isWindows && !knownHard[base]) { - fs$3.lstat(base, function(err) { - if (err) return cb(err); - knownHard[base] = true; - LOOP(); - }); - } else { - process.nextTick(LOOP); - } - } - - // walk down the path, swapping out linked pathparts for their real - // values - function LOOP() { - // stop if scanned past end of path - if (pos >= p.length) { - if (cache) cache[original] = p; - return cb(null, p); - } - - // find the next part - nextPartRe.lastIndex = pos; - var result = nextPartRe.exec(p); - previous = current; - current += result[0]; - base = previous + result[1]; - pos = nextPartRe.lastIndex; - - // continue if not a symlink - if (knownHard[base] || (cache && cache[base] === base)) { - return process.nextTick(LOOP); - } - - if (cache && Object.prototype.hasOwnProperty.call(cache, base)) { - // known symbolic link. no need to stat again. - return gotResolvedLink(cache[base]); - } - - return fs$3.lstat(base, gotStat); - } - - function gotStat(err, stat) { - if (err) return cb(err); - - // if not a symlink, skip to the next path part - if (!stat.isSymbolicLink()) { - knownHard[base] = true; - if (cache) cache[base] = base; - return process.nextTick(LOOP); - } - - // stat & read the link if not read before - // call gotTarget as soon as the link target is known - // dev/ino always return 0 on windows, so skip the check. - if (!isWindows) { - var id = stat.dev.toString(32) + ':' + stat.ino.toString(32); - if (seenLinks.hasOwnProperty(id)) { - return gotTarget(null, seenLinks[id], base); - } - } - fs$3.stat(base, function(err) { - if (err) return cb(err); - - fs$3.readlink(base, function(err, target) { - if (!isWindows) seenLinks[id] = target; - gotTarget(err, target); - }); - }); - } - - function gotTarget(err, target, base) { - if (err) return cb(err); - - var resolvedLink = pathModule.resolve(previous, target); - if (cache) cache[base] = resolvedLink; - gotResolvedLink(resolvedLink); - } - - function gotResolvedLink(resolvedLink) { - // resolve the link, then start over - p = pathModule.resolve(resolvedLink, p.slice(pos)); - start(); - } -}; - -var fs_realpath = realpath; -realpath.realpath = realpath; -realpath.sync = realpathSync; -realpath.realpathSync = realpathSync; -realpath.monkeypatch = monkeypatch; -realpath.unmonkeypatch = unmonkeypatch; - -var fs$2 = require$$0$3; -var origRealpath = fs$2.realpath; -var origRealpathSync = fs$2.realpathSync; - -var version$2 = process.version; -var ok$1 = /^v[0-5]\./.test(version$2); -var old = old$1; - -function newError (er) { - return er && er.syscall === 'realpath' && ( - er.code === 'ELOOP' || - er.code === 'ENOMEM' || - er.code === 'ENAMETOOLONG' - ) -} - -function realpath (p, cache, cb) { - if (ok$1) { - return origRealpath(p, cache, cb) - } - - if (typeof cache === 'function') { - cb = cache; - cache = null; - } - origRealpath(p, cache, function (er, result) { - if (newError(er)) { - old.realpath(p, cache, cb); - } else { - cb(er, result); - } - }); -} - -function realpathSync (p, cache) { - if (ok$1) { - return origRealpathSync(p, cache) - } - - try { - return origRealpathSync(p, cache) - } catch (er) { - if (newError(er)) { - return old.realpathSync(p, cache) - } else { - throw er - } - } -} - -function monkeypatch () { - fs$2.realpath = realpath; - fs$2.realpathSync = realpathSync; -} - -function unmonkeypatch () { - fs$2.realpath = origRealpath; - fs$2.realpathSync = origRealpathSync; -} - -var concatMap$1 = function (xs, fn) { - var res = []; - for (var i = 0; i < xs.length; i++) { - var x = fn(xs[i], i); - if (isArray$1(x)) res.push.apply(res, x); - else res.push(x); - } - return res; -}; - -var isArray$1 = Array.isArray || function (xs) { - return Object.prototype.toString.call(xs) === '[object Array]'; -}; - -var balancedMatch = balanced$1; -function balanced$1(a, b, str) { - if (a instanceof RegExp) a = maybeMatch(a, str); - if (b instanceof RegExp) b = maybeMatch(b, str); - - var r = range(a, b, str); - - return r && { - start: r[0], - end: r[1], - pre: str.slice(0, r[0]), - body: str.slice(r[0] + a.length, r[1]), - post: str.slice(r[1] + b.length) - }; -} - -function maybeMatch(reg, str) { - var m = str.match(reg); - return m ? m[0] : null; -} - -balanced$1.range = range; -function range(a, b, str) { - var begs, beg, left, right, result; - var ai = str.indexOf(a); - var bi = str.indexOf(b, ai + 1); - var i = ai; - - if (ai >= 0 && bi > 0) { - if(a===b) { - return [ai, bi]; - } - begs = []; - left = str.length; - - while (i >= 0 && !result) { - if (i == ai) { - begs.push(i); - ai = str.indexOf(a, i + 1); - } else if (begs.length == 1) { - result = [ begs.pop(), bi ]; - } else { - beg = begs.pop(); - if (beg < left) { - left = beg; - right = bi; - } - - bi = str.indexOf(b, i + 1); - } - - i = ai < bi && ai >= 0 ? ai : bi; - } - - if (begs.length) { - result = [ left, right ]; - } - } - - return result; -} - -var concatMap = concatMap$1; -var balanced = balancedMatch; - -var braceExpansion = expandTop; - -var escSlash = '\0SLASH'+Math.random()+'\0'; -var escOpen = '\0OPEN'+Math.random()+'\0'; -var escClose = '\0CLOSE'+Math.random()+'\0'; -var escComma = '\0COMMA'+Math.random()+'\0'; -var escPeriod = '\0PERIOD'+Math.random()+'\0'; - -function numeric(str) { - return parseInt(str, 10) == str - ? parseInt(str, 10) - : str.charCodeAt(0); -} - -function escapeBraces(str) { - return str.split('\\\\').join(escSlash) - .split('\\{').join(escOpen) - .split('\\}').join(escClose) - .split('\\,').join(escComma) - .split('\\.').join(escPeriod); -} - -function unescapeBraces(str) { - return str.split(escSlash).join('\\') - .split(escOpen).join('{') - .split(escClose).join('}') - .split(escComma).join(',') - .split(escPeriod).join('.'); -} - - -// Basically just str.split(","), but handling cases -// where we have nested braced sections, which should be -// treated as individual members, like {a,{b,c},d} -function parseCommaParts(str) { - if (!str) - return ['']; - - var parts = []; - var m = balanced('{', '}', str); - - if (!m) - return str.split(','); - - var pre = m.pre; - var body = m.body; - var post = m.post; - var p = pre.split(','); - - p[p.length-1] += '{' + body + '}'; - var postParts = parseCommaParts(post); - if (post.length) { - p[p.length-1] += postParts.shift(); - p.push.apply(p, postParts); - } - - parts.push.apply(parts, p); - - return parts; -} - -function expandTop(str) { - if (!str) - return []; - - // I don't know why Bash 4.3 does this, but it does. - // Anything starting with {} will have the first two bytes preserved - // but *only* at the top level, so {},a}b will not expand to anything, - // but a{},b}c will be expanded to [a}c,abc]. - // One could argue that this is a bug in Bash, but since the goal of - // this module is to match Bash's rules, we escape a leading {} - if (str.substr(0, 2) === '{}') { - str = '\\{\\}' + str.substr(2); - } - - return expand$2(escapeBraces(str), true).map(unescapeBraces); -} - -function embrace(str) { - return '{' + str + '}'; -} -function isPadded(el) { - return /^-?0\d/.test(el); -} - -function lte(i, y) { - return i <= y; -} -function gte(i, y) { - return i >= y; -} - -function expand$2(str, isTop) { - var expansions = []; - - var m = balanced('{', '}', str); - if (!m || /\$$/.test(m.pre)) return [str]; - - var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body); - var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body); - var isSequence = isNumericSequence || isAlphaSequence; - var isOptions = m.body.indexOf(',') >= 0; - if (!isSequence && !isOptions) { - // {a},b} - if (m.post.match(/,.*\}/)) { - str = m.pre + '{' + m.body + escClose + m.post; - return expand$2(str); - } - return [str]; - } - - var n; - if (isSequence) { - n = m.body.split(/\.\./); - } else { - n = parseCommaParts(m.body); - if (n.length === 1) { - // x{{a,b}}y ==> x{a}y x{b}y - n = expand$2(n[0], false).map(embrace); - if (n.length === 1) { - var post = m.post.length - ? expand$2(m.post, false) - : ['']; - return post.map(function(p) { - return m.pre + n[0] + p; - }); - } - } - } - - // at this point, n is the parts, and we know it's not a comma set - // with a single entry. - - // no need to expand pre, since it is guaranteed to be free of brace-sets - var pre = m.pre; - var post = m.post.length - ? expand$2(m.post, false) - : ['']; - - var N; - - if (isSequence) { - var x = numeric(n[0]); - var y = numeric(n[1]); - var width = Math.max(n[0].length, n[1].length); - var incr = n.length == 3 - ? Math.abs(numeric(n[2])) - : 1; - var test = lte; - var reverse = y < x; - if (reverse) { - incr *= -1; - test = gte; - } - var pad = n.some(isPadded); - - N = []; - - for (var i = x; test(i, y); i += incr) { - var c; - if (isAlphaSequence) { - c = String.fromCharCode(i); - if (c === '\\') - c = ''; - } else { - c = String(i); - if (pad) { - var need = width - c.length; - if (need > 0) { - var z = new Array(need + 1).join('0'); - if (i < 0) - c = '-' + z + c.slice(1); - else - c = z + c; - } - } - } - N.push(c); - } - } else { - N = concatMap(n, function(el) { return expand$2(el, false) }); - } - - for (var j = 0; j < N.length; j++) { - for (var k = 0; k < post.length; k++) { - var expansion = pre + N[j] + post[k]; - if (!isTop || isSequence || expansion) - expansions.push(expansion); - } - } - - return expansions; -} - -var minimatch_1 = minimatch$3; -minimatch$3.Minimatch = Minimatch$1; - -var path$4 = { sep: '/' }; -try { - path$4 = path$b; -} catch (er) {} - -var GLOBSTAR = minimatch$3.GLOBSTAR = Minimatch$1.GLOBSTAR = {}; -var expand$1 = braceExpansion; - -var plTypes = { - '!': { open: '(?:(?!(?:', close: '))[^/]*?)'}, - '?': { open: '(?:', close: ')?' }, - '+': { open: '(?:', close: ')+' }, - '*': { open: '(?:', close: ')*' }, - '@': { open: '(?:', close: ')' } -}; - -// any single thing other than / -// don't need to escape / when using new RegExp() -var qmark = '[^/]'; - -// * => any number of characters -var star = qmark + '*?'; - -// ** when dots are allowed. Anything goes, except .. and . -// not (^ or / followed by one or two dots followed by $ or /), -// followed by anything, any number of times. -var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'; - -// not a ^ or / followed by a dot, -// followed by anything, any number of times. -var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'; - -// characters that need to be escaped in RegExp. -var reSpecials = charSet('().*{}+?[]^$\\!'); - -// "abc" -> { a:true, b:true, c:true } -function charSet (s) { - return s.split('').reduce(function (set, c) { - set[c] = true; - return set - }, {}) -} - -// normalizes slashes. -var slashSplit = /\/+/; - -minimatch$3.filter = filter; -function filter (pattern, options) { - options = options || {}; - return function (p, i, list) { - return minimatch$3(p, pattern, options) - } -} - -function ext (a, b) { - a = a || {}; - b = b || {}; - var t = {}; - Object.keys(b).forEach(function (k) { - t[k] = b[k]; - }); - Object.keys(a).forEach(function (k) { - t[k] = a[k]; - }); - return t -} - -minimatch$3.defaults = function (def) { - if (!def || !Object.keys(def).length) return minimatch$3 - - var orig = minimatch$3; - - var m = function minimatch (p, pattern, options) { - return orig.minimatch(p, pattern, ext(def, options)) - }; - - m.Minimatch = function Minimatch (pattern, options) { - return new orig.Minimatch(pattern, ext(def, options)) - }; - - return m -}; - -Minimatch$1.defaults = function (def) { - if (!def || !Object.keys(def).length) return Minimatch$1 - return minimatch$3.defaults(def).Minimatch -}; - -function minimatch$3 (p, pattern, options) { - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {}; - - // shortcut: comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - return false - } - - // "" only matches "" - if (pattern.trim() === '') return p === '' - - return new Minimatch$1(pattern, options).match(p) -} - -function Minimatch$1 (pattern, options) { - if (!(this instanceof Minimatch$1)) { - return new Minimatch$1(pattern, options) - } - - if (typeof pattern !== 'string') { - throw new TypeError('glob pattern string required') - } - - if (!options) options = {}; - pattern = pattern.trim(); - - // windows support: need to use /, not \ - if (path$4.sep !== '/') { - pattern = pattern.split(path$4.sep).join('/'); - } - - this.options = options; - this.set = []; - this.pattern = pattern; - this.regexp = null; - this.negate = false; - this.comment = false; - this.empty = false; - - // make the set of regexps etc. - this.make(); -} - -Minimatch$1.prototype.debug = function () {}; - -Minimatch$1.prototype.make = make; -function make () { - // don't do it more than once. - if (this._made) return - - var pattern = this.pattern; - var options = this.options; - - // empty patterns and comments match nothing. - if (!options.nocomment && pattern.charAt(0) === '#') { - this.comment = true; - return - } - if (!pattern) { - this.empty = true; - return - } - - // step 1: figure out negation, etc. - this.parseNegate(); - - // step 2: expand braces - var set = this.globSet = this.braceExpand(); - - if (options.debug) this.debug = console.error; - - this.debug(this.pattern, set); - - // step 3: now we have a set, so turn each one into a series of path-portion - // matching patterns. - // These will be regexps, except in the case of "**", which is - // set to the GLOBSTAR object for globstar behavior, - // and will not contain any / characters - set = this.globParts = set.map(function (s) { - return s.split(slashSplit) - }); - - this.debug(this.pattern, set); - - // glob --> regexps - set = set.map(function (s, si, set) { - return s.map(this.parse, this) - }, this); - - this.debug(this.pattern, set); - - // filter out everything that didn't compile properly. - set = set.filter(function (s) { - return s.indexOf(false) === -1 - }); - - this.debug(this.pattern, set); - - this.set = set; -} - -Minimatch$1.prototype.parseNegate = parseNegate; -function parseNegate () { - var pattern = this.pattern; - var negate = false; - var options = this.options; - var negateOffset = 0; - - if (options.nonegate) return - - for (var i = 0, l = pattern.length - ; i < l && pattern.charAt(i) === '!' - ; i++) { - negate = !negate; - negateOffset++; - } - - if (negateOffset) this.pattern = pattern.substr(negateOffset); - this.negate = negate; -} - -// Brace expansion: -// a{b,c}d -> abd acd -// a{b,}c -> abc ac -// a{0..3}d -> a0d a1d a2d a3d -// a{b,c{d,e}f}g -> abg acdfg acefg -// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg -// -// Invalid sets are not expanded. -// a{2..}b -> a{2..}b -// a{b}c -> a{b}c -minimatch$3.braceExpand = function (pattern, options) { - return braceExpand(pattern, options) -}; - -Minimatch$1.prototype.braceExpand = braceExpand; - -function braceExpand (pattern, options) { - if (!options) { - if (this instanceof Minimatch$1) { - options = this.options; - } else { - options = {}; - } - } - - pattern = typeof pattern === 'undefined' - ? this.pattern : pattern; - - if (typeof pattern === 'undefined') { - throw new TypeError('undefined pattern') - } - - if (options.nobrace || - !pattern.match(/\{.*\}/)) { - // shortcut. no need to expand. - return [pattern] - } - - return expand$1(pattern) -} - -// parse a component of the expanded set. -// At this point, no pattern may contain "/" in it -// so we're going to return a 2d array, where each entry is the full -// pattern, split on '/', and then turned into a regular expression. -// A regexp is made at the end which joins each array with an -// escaped /, and another full one which joins each regexp with |. -// -// Following the lead of Bash 4.1, note that "**" only has special meaning -// when it is the *only* thing in a path portion. Otherwise, any series -// of * is equivalent to a single *. Globstar behavior is enabled by -// default, and can be disabled by setting options.noglobstar. -Minimatch$1.prototype.parse = parse$3; -var SUBPARSE = {}; -function parse$3 (pattern, isSub) { - if (pattern.length > 1024 * 64) { - throw new TypeError('pattern is too long') - } - - var options = this.options; - - // shortcuts - if (!options.noglobstar && pattern === '**') return GLOBSTAR - if (pattern === '') return '' - - var re = ''; - var hasMagic = !!options.nocase; - var escaping = false; - // ? => one single character - var patternListStack = []; - var negativeLists = []; - var stateChar; - var inClass = false; - var reClassStart = -1; - var classStart = -1; - // . and .. never match anything that doesn't start with ., - // even when options.dot is set. - var patternStart = pattern.charAt(0) === '.' ? '' // anything - // not (start or / followed by . or .. followed by / or end) - : options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))' - : '(?!\\.)'; - var self = this; - - function clearStateChar () { - if (stateChar) { - // we had some state-tracking character - // that wasn't consumed by this pass. - switch (stateChar) { - case '*': - re += star; - hasMagic = true; - break - case '?': - re += qmark; - hasMagic = true; - break - default: - re += '\\' + stateChar; - break - } - self.debug('clearStateChar %j %j', stateChar, re); - stateChar = false; - } - } - - for (var i = 0, len = pattern.length, c - ; (i < len) && (c = pattern.charAt(i)) - ; i++) { - this.debug('%s\t%s %s %j', pattern, i, re, c); - - // skip over any that are escaped. - if (escaping && reSpecials[c]) { - re += '\\' + c; - escaping = false; - continue - } - - switch (c) { - case '/': - // completely not allowed, even escaped. - // Should already be path-split by now. - return false - - case '\\': - clearStateChar(); - escaping = true; - continue - - // the various stateChar values - // for the "extglob" stuff. - case '?': - case '*': - case '+': - case '@': - case '!': - this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c); - - // all of those are literals inside a class, except that - // the glob [!a] means [^a] in regexp - if (inClass) { - this.debug(' in class'); - if (c === '!' && i === classStart + 1) c = '^'; - re += c; - continue - } - - // if we already have a stateChar, then it means - // that there was something like ** or +? in there. - // Handle the stateChar, then proceed with this one. - self.debug('call clearStateChar %j', stateChar); - clearStateChar(); - stateChar = c; - // if extglob is disabled, then +(asdf|foo) isn't a thing. - // just clear the statechar *now*, rather than even diving into - // the patternList stuff. - if (options.noext) clearStateChar(); - continue - - case '(': - if (inClass) { - re += '('; - continue - } - - if (!stateChar) { - re += '\\('; - continue - } - - patternListStack.push({ - type: stateChar, - start: i - 1, - reStart: re.length, - open: plTypes[stateChar].open, - close: plTypes[stateChar].close - }); - // negation is (?:(?!js)[^/]*) - re += stateChar === '!' ? '(?:(?!(?:' : '(?:'; - this.debug('plType %j %j', stateChar, re); - stateChar = false; - continue - - case ')': - if (inClass || !patternListStack.length) { - re += '\\)'; - continue - } - - clearStateChar(); - hasMagic = true; - var pl = patternListStack.pop(); - // negation is (?:(?!js)[^/]*) - // The others are (?:) - re += pl.close; - if (pl.type === '!') { - negativeLists.push(pl); - } - pl.reEnd = re.length; - continue - - case '|': - if (inClass || !patternListStack.length || escaping) { - re += '\\|'; - escaping = false; - continue - } - - clearStateChar(); - re += '|'; - continue - - // these are mostly the same in regexp and glob - case '[': - // swallow any state-tracking char before the [ - clearStateChar(); - - if (inClass) { - re += '\\' + c; - continue - } - - inClass = true; - classStart = i; - reClassStart = re.length; - re += c; - continue - - case ']': - // a right bracket shall lose its special - // meaning and represent itself in - // a bracket expression if it occurs - // first in the list. -- POSIX.2 2.8.3.2 - if (i === classStart + 1 || !inClass) { - re += '\\' + c; - escaping = false; - continue - } - - // handle the case where we left a class open. - // "[z-a]" is valid, equivalent to "\[z-a\]" - if (inClass) { - // split where the last [ was, make sure we don't have - // an invalid re. if so, re-walk the contents of the - // would-be class to re-translate any characters that - // were passed through as-is - // TODO: It would probably be faster to determine this - // without a try/catch and a new RegExp, but it's tricky - // to do safely. For now, this is safe and works. - var cs = pattern.substring(classStart + 1, i); - try { - RegExp('[' + cs + ']'); - } catch (er) { - // not a valid class! - var sp = this.parse(cs, SUBPARSE); - re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'; - hasMagic = hasMagic || sp[1]; - inClass = false; - continue - } - } - - // finish up the class. - hasMagic = true; - inClass = false; - re += c; - continue - - default: - // swallow any state char that wasn't consumed - clearStateChar(); - - if (escaping) { - // no need - escaping = false; - } else if (reSpecials[c] - && !(c === '^' && inClass)) { - re += '\\'; - } - - re += c; - - } // switch - } // for - - // handle the case where we left a class open. - // "[abc" is valid, equivalent to "\[abc" - if (inClass) { - // split where the last [ was, and escape it - // this is a huge pita. We now have to re-walk - // the contents of the would-be class to re-translate - // any characters that were passed through as-is - cs = pattern.substr(classStart + 1); - sp = this.parse(cs, SUBPARSE); - re = re.substr(0, reClassStart) + '\\[' + sp[0]; - hasMagic = hasMagic || sp[1]; - } - - // handle the case where we had a +( thing at the *end* - // of the pattern. - // each pattern list stack adds 3 chars, and we need to go through - // and escape any | chars that were passed through as-is for the regexp. - // Go through and escape them, taking care not to double-escape any - // | chars that were already escaped. - for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) { - var tail = re.slice(pl.reStart + pl.open.length); - this.debug('setting tail', re, pl); - // maybe some even number of \, then maybe 1 \, followed by a | - tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) { - if (!$2) { - // the | isn't already escaped, so escape it. - $2 = '\\'; - } - - // need to escape all those slashes *again*, without escaping the - // one that we need for escaping the | character. As it works out, - // escaping an even number of slashes can be done by simply repeating - // it exactly after itself. That's why this trick works. - // - // I am sorry that you have to see this. - return $1 + $1 + $2 + '|' - }); - - this.debug('tail=%j\n %s', tail, tail, pl, re); - var t = pl.type === '*' ? star - : pl.type === '?' ? qmark - : '\\' + pl.type; - - hasMagic = true; - re = re.slice(0, pl.reStart) + t + '\\(' + tail; - } - - // handle trailing things that only matter at the very end. - clearStateChar(); - if (escaping) { - // trailing \\ - re += '\\\\'; - } - - // only need to apply the nodot start if the re starts with - // something that could conceivably capture a dot - var addPatternStart = false; - switch (re.charAt(0)) { - case '.': - case '[': - case '(': addPatternStart = true; - } - - // Hack to work around lack of negative lookbehind in JS - // A pattern like: *.!(x).!(y|z) needs to ensure that a name - // like 'a.xyz.yz' doesn't match. So, the first negative - // lookahead, has to look ALL the way ahead, to the end of - // the pattern. - for (var n = negativeLists.length - 1; n > -1; n--) { - var nl = negativeLists[n]; - - var nlBefore = re.slice(0, nl.reStart); - var nlFirst = re.slice(nl.reStart, nl.reEnd - 8); - var nlLast = re.slice(nl.reEnd - 8, nl.reEnd); - var nlAfter = re.slice(nl.reEnd); - - nlLast += nlAfter; - - // Handle nested stuff like *(*.js|!(*.json)), where open parens - // mean that we should *not* include the ) in the bit that is considered - // "after" the negated section. - var openParensBefore = nlBefore.split('(').length - 1; - var cleanAfter = nlAfter; - for (i = 0; i < openParensBefore; i++) { - cleanAfter = cleanAfter.replace(/\)[+*?]?/, ''); - } - nlAfter = cleanAfter; - - var dollar = ''; - if (nlAfter === '' && isSub !== SUBPARSE) { - dollar = '$'; - } - var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast; - re = newRe; - } - - // if the re is not "" at this point, then we need to make sure - // it doesn't match against an empty path part. - // Otherwise a/* will match a/, which it should not. - if (re !== '' && hasMagic) { - re = '(?=.)' + re; - } - - if (addPatternStart) { - re = patternStart + re; - } - - // parsing just a piece of a larger pattern. - if (isSub === SUBPARSE) { - return [re, hasMagic] - } - - // skip the regexp for non-magical patterns - // unescape anything in it, though, so that it'll be - // an exact match against a file etc. - if (!hasMagic) { - return globUnescape(pattern) - } - - var flags = options.nocase ? 'i' : ''; - try { - var regExp = new RegExp('^' + re + '$', flags); - } catch (er) { - // If it was an invalid regular expression, then it can't match - // anything. This trick looks for a character after the end of - // the string, which is of course impossible, except in multi-line - // mode, but it's not a /m regex. - return new RegExp('$.') - } - - regExp._glob = pattern; - regExp._src = re; - - return regExp -} - -minimatch$3.makeRe = function (pattern, options) { - return new Minimatch$1(pattern, options || {}).makeRe() -}; - -Minimatch$1.prototype.makeRe = makeRe; -function makeRe () { - if (this.regexp || this.regexp === false) return this.regexp - - // at this point, this.set is a 2d array of partial - // pattern strings, or "**". - // - // It's better to use .match(). This function shouldn't - // be used, really, but it's pretty convenient sometimes, - // when you just want to work with a regex. - var set = this.set; - - if (!set.length) { - this.regexp = false; - return this.regexp - } - var options = this.options; - - var twoStar = options.noglobstar ? star - : options.dot ? twoStarDot - : twoStarNoDot; - var flags = options.nocase ? 'i' : ''; - - var re = set.map(function (pattern) { - return pattern.map(function (p) { - return (p === GLOBSTAR) ? twoStar - : (typeof p === 'string') ? regExpEscape(p) - : p._src - }).join('\\\/') - }).join('|'); - - // must match entire pattern - // ending in a * or ** will make it less strict. - re = '^(?:' + re + ')$'; - - // can match anything, as long as it's not this. - if (this.negate) re = '^(?!' + re + ').*$'; - - try { - this.regexp = new RegExp(re, flags); - } catch (ex) { - this.regexp = false; - } - return this.regexp -} - -minimatch$3.match = function (list, pattern, options) { - options = options || {}; - var mm = new Minimatch$1(pattern, options); - list = list.filter(function (f) { - return mm.match(f) - }); - if (mm.options.nonull && !list.length) { - list.push(pattern); - } - return list -}; - -Minimatch$1.prototype.match = match; -function match (f, partial) { - this.debug('match', f, this.pattern); - // short-circuit in the case of busted things. - // comments, etc. - if (this.comment) return false - if (this.empty) return f === '' - - if (f === '/' && partial) return true - - var options = this.options; - - // windows: need to use /, not \ - if (path$4.sep !== '/') { - f = f.split(path$4.sep).join('/'); - } - - // treat the test path as a set of pathparts. - f = f.split(slashSplit); - this.debug(this.pattern, 'split', f); - - // just ONE of the pattern sets in this.set needs to match - // in order for it to be valid. If negating, then just one - // match means that we have failed. - // Either way, return on the first hit. - - var set = this.set; - this.debug(this.pattern, 'set', set); - - // Find the basename of the path by looking for the last non-empty segment - var filename; - var i; - for (i = f.length - 1; i >= 0; i--) { - filename = f[i]; - if (filename) break - } - - for (i = 0; i < set.length; i++) { - var pattern = set[i]; - var file = f; - if (options.matchBase && pattern.length === 1) { - file = [filename]; - } - var hit = this.matchOne(file, pattern, partial); - if (hit) { - if (options.flipNegate) return true - return !this.negate - } - } - - // didn't get any hits. this is success if it's a negative - // pattern, failure otherwise. - if (options.flipNegate) return false - return this.negate -} - -// set partial to true to test if, for example, -// "/a/b" matches the start of "/*/b/*/d" -// Partial means, if you run out of file before you run -// out of pattern, then that's fine, as long as all -// the parts match. -Minimatch$1.prototype.matchOne = function (file, pattern, partial) { - var options = this.options; - - this.debug('matchOne', - { 'this': this, file: file, pattern: pattern }); - - this.debug('matchOne', file.length, pattern.length); - - for (var fi = 0, - pi = 0, - fl = file.length, - pl = pattern.length - ; (fi < fl) && (pi < pl) - ; fi++, pi++) { - this.debug('matchOne loop'); - var p = pattern[pi]; - var f = file[fi]; - - this.debug(pattern, p, f); - - // should be impossible. - // some invalid regexp stuff in the set. - if (p === false) return false - - if (p === GLOBSTAR) { - this.debug('GLOBSTAR', [pattern, p, f]); - - // "**" - // a/**/b/**/c would match the following: - // a/b/x/y/z/c - // a/x/y/z/b/c - // a/b/x/b/x/c - // a/b/c - // To do this, take the rest of the pattern after - // the **, and see if it would match the file remainder. - // If so, return success. - // If not, the ** "swallows" a segment, and try again. - // This is recursively awful. - // - // a/**/b/**/c matching a/b/x/y/z/c - // - a matches a - // - doublestar - // - matchOne(b/x/y/z/c, b/**/c) - // - b matches b - // - doublestar - // - matchOne(x/y/z/c, c) -> no - // - matchOne(y/z/c, c) -> no - // - matchOne(z/c, c) -> no - // - matchOne(c, c) yes, hit - var fr = fi; - var pr = pi + 1; - if (pr === pl) { - this.debug('** at the end'); - // a ** at the end will just swallow the rest. - // We have found a match. - // however, it will not swallow /.x, unless - // options.dot is set. - // . and .. are *never* matched by **, for explosively - // exponential reasons. - for (; fi < fl; fi++) { - if (file[fi] === '.' || file[fi] === '..' || - (!options.dot && file[fi].charAt(0) === '.')) return false - } - return true - } - - // ok, let's see if we can swallow whatever we can. - while (fr < fl) { - var swallowee = file[fr]; - - this.debug('\nglobstar while', file, fr, pattern, pr, swallowee); - - // XXX remove this slice. Just pass the start index. - if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) { - this.debug('globstar found match!', fr, fl, swallowee); - // found a match. - return true - } else { - // can't swallow "." or ".." ever. - // can only swallow ".foo" when explicitly asked. - if (swallowee === '.' || swallowee === '..' || - (!options.dot && swallowee.charAt(0) === '.')) { - this.debug('dot detected!', file, fr, pattern, pr); - break - } - - // ** swallows a segment, and continue. - this.debug('globstar swallow a segment, and continue'); - fr++; - } - } - - // no match was found. - // However, in partial mode, we can't say this is necessarily over. - // If there's more *pattern* left, then - if (partial) { - // ran out of file - this.debug('\n>>> no match, partial?', file, fr, pattern, pr); - if (fr === fl) return true - } - return false - } - - // something other than ** - // non-magic patterns just have to match exactly - // patterns with magic have been turned into regexps. - var hit; - if (typeof p === 'string') { - if (options.nocase) { - hit = f.toLowerCase() === p.toLowerCase(); - } else { - hit = f === p; - } - this.debug('string match', p, f, hit); - } else { - hit = f.match(p); - this.debug('pattern match', p, f, hit); - } - - if (!hit) return false - } - - // Note: ending in / means that we'll get a final "" - // at the end of the pattern. This can only match a - // corresponding "" at the end of the file. - // If the file ends in /, then it can only match a - // a pattern that ends in /, unless the pattern just - // doesn't have any more for it. But, a/b/ should *not* - // match "a/b/*", even though "" matches against the - // [^/]*? pattern, except in partial mode, where it might - // simply not be reached yet. - // However, a/b/ should still satisfy a/* - - // now either we fell off the end of the pattern, or we're done. - if (fi === fl && pi === pl) { - // ran out of pattern and filename at the same time. - // an exact hit! - return true - } else if (fi === fl) { - // ran out of file, but still had pattern left. - // this is ok if we're doing the match as part of - // a glob fs traversal. - return partial - } else if (pi === pl) { - // ran out of pattern, still have file left. - // this is only acceptable if we're on the very last - // empty segment of a file with a trailing slash. - // a/* should match a/b/ - var emptyFileEnd = (fi === fl - 1) && (file[fi] === ''); - return emptyFileEnd - } - - // should be unreachable. - throw new Error('wtf?') -}; - -// replace stuff like \* with * -function globUnescape (s) { - return s.replace(/\\(.)/g, '$1') -} - -function regExpEscape (s) { - return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') -} - -var inherits$2 = {exports: {}}; - -var inherits_browser = {exports: {}}; - -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - inherits_browser.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - } - }; -} else { - // old school shim for old browsers - inherits_browser.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - var TempCtor = function () {}; - TempCtor.prototype = superCtor.prototype; - ctor.prototype = new TempCtor(); - ctor.prototype.constructor = ctor; - } - }; -} - -try { - var util$1 = require$$0$4; - /* istanbul ignore next */ - if (typeof util$1.inherits !== 'function') throw ''; - inherits$2.exports = util$1.inherits; -} catch (e) { - /* istanbul ignore next */ - inherits$2.exports = inherits_browser.exports; -} - -var pathIsAbsolute = {exports: {}}; - -function posix(path) { - return path.charAt(0) === '/'; -} - -function win32(path) { - // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 - var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; - var result = splitDeviceRe.exec(path); - var device = result[1] || ''; - var isUnc = Boolean(device && device.charAt(1) !== ':'); - - // UNC paths are always absolute - return Boolean(result[2] || isUnc); -} - -pathIsAbsolute.exports = process.platform === 'win32' ? win32 : posix; -pathIsAbsolute.exports.posix = posix; -pathIsAbsolute.exports.win32 = win32; - -var common$2 = {}; - -common$2.setopts = setopts$2; -common$2.ownProp = ownProp$2; -common$2.makeAbs = makeAbs; -common$2.finish = finish; -common$2.mark = mark; -common$2.isIgnored = isIgnored$2; -common$2.childrenIgnored = childrenIgnored$2; - -function ownProp$2 (obj, field) { - return Object.prototype.hasOwnProperty.call(obj, field) -} - -var path$3 = path$b; -var minimatch$2 = minimatch_1; -var isAbsolute$2 = pathIsAbsolute.exports; -var Minimatch = minimatch$2.Minimatch; - -function alphasort (a, b) { - return a.localeCompare(b, 'en') -} - -function setupIgnores (self, options) { - self.ignore = options.ignore || []; - - if (!Array.isArray(self.ignore)) - self.ignore = [self.ignore]; - - if (self.ignore.length) { - self.ignore = self.ignore.map(ignoreMap); - } -} - -// ignore patterns are always in dot:true mode. -function ignoreMap (pattern) { - var gmatcher = null; - if (pattern.slice(-3) === '/**') { - var gpattern = pattern.replace(/(\/\*\*)+$/, ''); - gmatcher = new Minimatch(gpattern, { dot: true }); - } - - return { - matcher: new Minimatch(pattern, { dot: true }), - gmatcher: gmatcher - } -} - -function setopts$2 (self, pattern, options) { - if (!options) - options = {}; - - // base-matching: just use globstar for that. - if (options.matchBase && -1 === pattern.indexOf("/")) { - if (options.noglobstar) { - throw new Error("base matching requires globstar") - } - pattern = "**/" + pattern; - } - - self.silent = !!options.silent; - self.pattern = pattern; - self.strict = options.strict !== false; - self.realpath = !!options.realpath; - self.realpathCache = options.realpathCache || Object.create(null); - self.follow = !!options.follow; - self.dot = !!options.dot; - self.mark = !!options.mark; - self.nodir = !!options.nodir; - if (self.nodir) - self.mark = true; - self.sync = !!options.sync; - self.nounique = !!options.nounique; - self.nonull = !!options.nonull; - self.nosort = !!options.nosort; - self.nocase = !!options.nocase; - self.stat = !!options.stat; - self.noprocess = !!options.noprocess; - self.absolute = !!options.absolute; - - self.maxLength = options.maxLength || Infinity; - self.cache = options.cache || Object.create(null); - self.statCache = options.statCache || Object.create(null); - self.symlinks = options.symlinks || Object.create(null); - - setupIgnores(self, options); - - self.changedCwd = false; - var cwd = process.cwd(); - if (!ownProp$2(options, "cwd")) - self.cwd = cwd; - else { - self.cwd = path$3.resolve(options.cwd); - self.changedCwd = self.cwd !== cwd; - } - - self.root = options.root || path$3.resolve(self.cwd, "/"); - self.root = path$3.resolve(self.root); - if (process.platform === "win32") - self.root = self.root.replace(/\\/g, "/"); - - // TODO: is an absolute `cwd` supposed to be resolved against `root`? - // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') - self.cwdAbs = isAbsolute$2(self.cwd) ? self.cwd : makeAbs(self, self.cwd); - if (process.platform === "win32") - self.cwdAbs = self.cwdAbs.replace(/\\/g, "/"); - self.nomount = !!options.nomount; - - // disable comments and negation in Minimatch. - // Note that they are not supported in Glob itself anyway. - options.nonegate = true; - options.nocomment = true; - - self.minimatch = new Minimatch(pattern, options); - self.options = self.minimatch.options; -} - -function finish (self) { - var nou = self.nounique; - var all = nou ? [] : Object.create(null); - - for (var i = 0, l = self.matches.length; i < l; i ++) { - var matches = self.matches[i]; - if (!matches || Object.keys(matches).length === 0) { - if (self.nonull) { - // do like the shell, and spit out the literal glob - var literal = self.minimatch.globSet[i]; - if (nou) - all.push(literal); - else - all[literal] = true; - } - } else { - // had matches - var m = Object.keys(matches); - if (nou) - all.push.apply(all, m); - else - m.forEach(function (m) { - all[m] = true; - }); - } - } - - if (!nou) - all = Object.keys(all); - - if (!self.nosort) - all = all.sort(alphasort); - - // at *some* point we statted all of these - if (self.mark) { - for (var i = 0; i < all.length; i++) { - all[i] = self._mark(all[i]); - } - if (self.nodir) { - all = all.filter(function (e) { - var notDir = !(/\/$/.test(e)); - var c = self.cache[e] || self.cache[makeAbs(self, e)]; - if (notDir && c) - notDir = c !== 'DIR' && !Array.isArray(c); - return notDir - }); - } - } - - if (self.ignore.length) - all = all.filter(function(m) { - return !isIgnored$2(self, m) - }); - - self.found = all; -} - -function mark (self, p) { - var abs = makeAbs(self, p); - var c = self.cache[abs]; - var m = p; - if (c) { - var isDir = c === 'DIR' || Array.isArray(c); - var slash = p.slice(-1) === '/'; - - if (isDir && !slash) - m += '/'; - else if (!isDir && slash) - m = m.slice(0, -1); - - if (m !== p) { - var mabs = makeAbs(self, m); - self.statCache[mabs] = self.statCache[abs]; - self.cache[mabs] = self.cache[abs]; - } - } - - return m -} - -// lotta situps... -function makeAbs (self, f) { - var abs = f; - if (f.charAt(0) === '/') { - abs = path$3.join(self.root, f); - } else if (isAbsolute$2(f) || f === '') { - abs = f; - } else if (self.changedCwd) { - abs = path$3.resolve(self.cwd, f); - } else { - abs = path$3.resolve(f); - } - - if (process.platform === 'win32') - abs = abs.replace(/\\/g, '/'); - - return abs -} - - -// Return true, if pattern ends with globstar '**', for the accompanying parent directory. -// Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents -function isIgnored$2 (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -function childrenIgnored$2 (self, path) { - if (!self.ignore.length) - return false - - return self.ignore.some(function(item) { - return !!(item.gmatcher && item.gmatcher.match(path)) - }) -} - -var sync$1 = globSync$1; -globSync$1.GlobSync = GlobSync$1; - -var fs$1 = require$$0$3; -var rp$1 = fs_realpath; -var minimatch$1 = minimatch_1; -var path$2 = path$b; -var assert$1 = assert$2; -var isAbsolute$1 = pathIsAbsolute.exports; -var common$1 = common$2; -var setopts$1 = common$1.setopts; -var ownProp$1 = common$1.ownProp; -var childrenIgnored$1 = common$1.childrenIgnored; -var isIgnored$1 = common$1.isIgnored; - -function globSync$1 (pattern, options) { - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - return new GlobSync$1(pattern, options).found -} - -function GlobSync$1 (pattern, options) { - if (!pattern) - throw new Error('must provide pattern') - - if (typeof options === 'function' || arguments.length === 3) - throw new TypeError('callback provided to sync glob\n'+ - 'See: https://github.com/isaacs/node-glob/issues/167') - - if (!(this instanceof GlobSync$1)) - return new GlobSync$1(pattern, options) - - setopts$1(this, pattern, options); - - if (this.noprocess) - return this - - var n = this.minimatch.set.length; - this.matches = new Array(n); - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false); - } - this._finish(); -} - -GlobSync$1.prototype._finish = function () { - assert$1(this instanceof GlobSync$1); - if (this.realpath) { - var self = this; - this.matches.forEach(function (matchset, index) { - var set = self.matches[index] = Object.create(null); - for (var p in matchset) { - try { - p = self._makeAbs(p); - var real = rp$1.realpathSync(p, self.realpathCache); - set[real] = true; - } catch (er) { - if (er.syscall === 'stat') - set[self._makeAbs(p)] = true; - else - throw er - } - } - }); - } - common$1.finish(this); -}; - - -GlobSync$1.prototype._process = function (pattern, index, inGlobStar) { - assert$1(this instanceof GlobSync$1); - - // Get the first [n] parts of pattern that are all strings. - var n = 0; - while (typeof pattern[n] === 'string') { - n ++; - } - // now n is the index of the first one that is *not* a string. - - // See if there's anything else - var prefix; - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index); - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null; - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/'); - break - } - - var remain = pattern.slice(n); - - // get the list of entries. - var read; - if (prefix === null) - read = '.'; - else if (isAbsolute$1(prefix) || isAbsolute$1(pattern.join('/'))) { - if (!prefix || !isAbsolute$1(prefix)) - prefix = '/' + prefix; - read = prefix; - } else - read = prefix; - - var abs = this._makeAbs(read); - - //if ignored, skip processing - if (childrenIgnored$1(this, read)) - return - - var isGlobStar = remain[0] === minimatch$1.GLOBSTAR; - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar); - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar); -}; - - -GlobSync$1.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) { - var entries = this._readdir(abs, inGlobStar); - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0]; - var negate = !!this.minimatch.negate; - var rawGlob = pn._glob; - var dotOk = this.dot || rawGlob.charAt(0) === '.'; - - var matchedEntries = []; - for (var i = 0; i < entries.length; i++) { - var e = entries[i]; - if (e.charAt(0) !== '.' || dotOk) { - var m; - if (negate && !prefix) { - m = !e.match(pn); - } else { - m = e.match(pn); - } - if (m) - matchedEntries.push(e); - } - } - - var len = matchedEntries.length; - // If there are no matched entries, then nothing matches. - if (len === 0) - return - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - if (prefix) { - if (prefix.slice(-1) !== '/') - e = prefix + '/' + e; - else - e = prefix + e; - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path$2.join(this.root, e); - } - this._emitMatch(index, e); - } - // This was the last one, and no stats were needed - return - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift(); - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - var newPattern; - if (prefix) - newPattern = [prefix, e]; - else - newPattern = [e]; - this._process(newPattern.concat(remain), index, inGlobStar); - } -}; - - -GlobSync$1.prototype._emitMatch = function (index, e) { - if (isIgnored$1(this, e)) - return - - var abs = this._makeAbs(e); - - if (this.mark) - e = this._mark(e); - - if (this.absolute) { - e = abs; - } - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs]; - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true; - - if (this.stat) - this._stat(e); -}; - - -GlobSync$1.prototype._readdirInGlobStar = function (abs) { - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false) - - var entries; - var lstat; - try { - lstat = fs$1.lstatSync(abs); - } catch (er) { - if (er.code === 'ENOENT') { - // lstat failed, doesn't exist - return null - } - } - - var isSym = lstat && lstat.isSymbolicLink(); - this.symlinks[abs] = isSym; - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) - this.cache[abs] = 'FILE'; - else - entries = this._readdir(abs, false); - - return entries -}; - -GlobSync$1.prototype._readdir = function (abs, inGlobStar) { - - if (inGlobStar && !ownProp$1(this.symlinks, abs)) - return this._readdirInGlobStar(abs) - - if (ownProp$1(this.cache, abs)) { - var c = this.cache[abs]; - if (!c || c === 'FILE') - return null - - if (Array.isArray(c)) - return c - } - - try { - return this._readdirEntries(abs, fs$1.readdirSync(abs)) - } catch (er) { - this._readdirError(abs, er); - return null - } -}; - -GlobSync$1.prototype._readdirEntries = function (abs, entries) { - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i]; - if (abs === '/') - e = abs + e; - else - e = abs + '/' + e; - this.cache[e] = true; - } - } - - this.cache[abs] = entries; - - // mark and cache dir-ness - return entries -}; - -GlobSync$1.prototype._readdirError = function (f, er) { - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f); - this.cache[abs] = 'FILE'; - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd); - error.path = this.cwd; - error.code = er.code; - throw error - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false; - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false; - if (this.strict) - throw er - if (!this.silent) - console.error('glob error', er); - break - } -}; - -GlobSync$1.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) { - - var entries = this._readdir(abs, inGlobStar); - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1); - var gspref = prefix ? [ prefix ] : []; - var noGlobStar = gspref.concat(remainWithoutGlobStar); - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false); - - var len = entries.length; - var isSym = this.symlinks[abs]; - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return - - for (var i = 0; i < len; i++) { - var e = entries[i]; - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar); - this._process(instead, index, true); - - var below = gspref.concat(entries[i], remain); - this._process(below, index, true); - } -}; - -GlobSync$1.prototype._processSimple = function (prefix, index) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var exists = this._stat(prefix); - - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return - - if (prefix && isAbsolute$1(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix); - if (prefix.charAt(0) === '/') { - prefix = path$2.join(this.root, prefix); - } else { - prefix = path$2.resolve(this.root, prefix); - if (trail) - prefix += '/'; - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/'); - - // Mark this as a match - this._emitMatch(index, prefix); -}; - -// Returns either 'DIR', 'FILE', or false -GlobSync$1.prototype._stat = function (f) { - var abs = this._makeAbs(f); - var needDir = f.slice(-1) === '/'; - - if (f.length > this.maxLength) - return false - - if (!this.stat && ownProp$1(this.cache, abs)) { - var c = this.cache[abs]; - - if (Array.isArray(c)) - c = 'DIR'; - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return c - - if (needDir && c === 'FILE') - return false - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - var stat = this.statCache[abs]; - if (!stat) { - var lstat; - try { - lstat = fs$1.lstatSync(abs); - } catch (er) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false; - return false - } - } - - if (lstat && lstat.isSymbolicLink()) { - try { - stat = fs$1.statSync(abs); - } catch (er) { - stat = lstat; - } - } else { - stat = lstat; - } - } - - this.statCache[abs] = stat; - - var c = true; - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE'; - - this.cache[abs] = this.cache[abs] || c; - - if (needDir && c === 'FILE') - return false - - return c -}; - -GlobSync$1.prototype._mark = function (p) { - return common$1.mark(this, p) -}; - -GlobSync$1.prototype._makeAbs = function (f) { - return common$1.makeAbs(this, f) -}; - -// Returns a wrapper function that returns a wrapped callback -// The wrapper function should do some stuff, and return a -// presumably different callback function. -// This makes sure that own properties are retained, so that -// decorations and such are not lost along the way. -var wrappy_1 = wrappy$2; -function wrappy$2 (fn, cb) { - if (fn && cb) return wrappy$2(fn)(cb) - - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') - - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k]; - }); - - return wrapper - - function wrapper() { - var args = new Array(arguments.length); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i]; - } - var ret = fn.apply(this, args); - var cb = args[args.length-1]; - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k]; - }); - } - return ret - } -} - -var once$3 = {exports: {}}; - -var wrappy$1 = wrappy_1; -once$3.exports = wrappy$1(once$2); -once$3.exports.strict = wrappy$1(onceStrict); - -once$2.proto = once$2(function () { - Object.defineProperty(Function.prototype, 'once', { - value: function () { - return once$2(this) - }, - configurable: true - }); - - Object.defineProperty(Function.prototype, 'onceStrict', { - value: function () { - return onceStrict(this) - }, - configurable: true - }); -}); - -function once$2 (fn) { - var f = function () { - if (f.called) return f.value - f.called = true; - return f.value = fn.apply(this, arguments) - }; - f.called = false; - return f -} - -function onceStrict (fn) { - var f = function () { - if (f.called) - throw new Error(f.onceError) - f.called = true; - return f.value = fn.apply(this, arguments) - }; - var name = fn.name || 'Function wrapped with `once`'; - f.onceError = name + " shouldn't be called more than once"; - f.called = false; - return f -} - -var wrappy = wrappy_1; -var reqs = Object.create(null); -var once$1 = once$3.exports; - -var inflight_1 = wrappy(inflight$1); - -function inflight$1 (key, cb) { - if (reqs[key]) { - reqs[key].push(cb); - return null - } else { - reqs[key] = [cb]; - return makeres(key) - } -} - -function makeres (key) { - return once$1(function RES () { - var cbs = reqs[key]; - var len = cbs.length; - var args = slice$1(arguments); - - // XXX It's somewhat ambiguous whether a new callback added in this - // pass should be queued for later execution if something in the - // list of callbacks throws, or if it should just be discarded. - // However, it's such an edge case that it hardly matters, and either - // choice is likely as surprising as the other. - // As it happens, we do go ahead and schedule it for later execution. - try { - for (var i = 0; i < len; i++) { - cbs[i].apply(null, args); - } - } finally { - if (cbs.length > len) { - // added more in the interim. - // de-zalgo, just in case, but don't call again. - cbs.splice(0, len); - process.nextTick(function () { - RES.apply(null, args); - }); - } else { - delete reqs[key]; - } - } - }) -} - -function slice$1 (args) { - var length = args.length; - var array = []; - - for (var i = 0; i < length; i++) array[i] = args[i]; - return array -} - -// Approach: -// -// 1. Get the minimatch set -// 2. For each pattern in the set, PROCESS(pattern, false) -// 3. Store matches per-set, then uniq them -// -// PROCESS(pattern, inGlobStar) -// Get the first [n] items from pattern that are all strings -// Join these together. This is PREFIX. -// If there is no more remaining, then stat(PREFIX) and -// add to matches if it succeeds. END. -// -// If inGlobStar and PREFIX is symlink and points to dir -// set ENTRIES = [] -// else readdir(PREFIX) as ENTRIES -// If fail, END -// -// with ENTRIES -// If pattern[n] is GLOBSTAR -// // handle the case where the globstar match is empty -// // by pruning it out, and testing the resulting pattern -// PROCESS(pattern[0..n] + pattern[n+1 .. $], false) -// // handle other cases. -// for ENTRY in ENTRIES (not dotfiles) -// // attach globstar + tail onto the entry -// // Mark that this entry is a globstar match -// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true) -// -// else // not globstar -// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot) -// Test ENTRY against pattern[n] -// If fails, continue -// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $]) -// -// Caveat: -// Cache all stats and readdirs results to minimize syscall. Since all -// we ever care about is existence and directory-ness, we can just keep -// `true` for files, and [children,...] for directories, or `false` for -// things that don't exist. - -var glob_1 = glob; - -var fs = require$$0$3; -var rp = fs_realpath; -var minimatch = minimatch_1; -var inherits$1 = inherits$2.exports; -var EE = require$$0$5.EventEmitter; -var path$1 = path$b; -var assert = assert$2; -var isAbsolute = pathIsAbsolute.exports; -var globSync = sync$1; -var common = common$2; -var setopts = common.setopts; -var ownProp = common.ownProp; -var inflight = inflight_1; -var childrenIgnored = common.childrenIgnored; -var isIgnored = common.isIgnored; - -var once = once$3.exports; - -function glob (pattern, options, cb) { - if (typeof options === 'function') cb = options, options = {}; - if (!options) options = {}; - - if (options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return globSync(pattern, options) - } - - return new Glob(pattern, options, cb) -} - -glob.sync = globSync; -var GlobSync = glob.GlobSync = globSync.GlobSync; - -// old api surface -glob.glob = glob; - -function extend$1 (origin, add) { - if (add === null || typeof add !== 'object') { - return origin - } - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin -} - -glob.hasMagic = function (pattern, options_) { - var options = extend$1({}, options_); - options.noprocess = true; - - var g = new Glob(pattern, options); - var set = g.minimatch.set; - - if (!pattern) - return false - - if (set.length > 1) - return true - - for (var j = 0; j < set[0].length; j++) { - if (typeof set[0][j] !== 'string') - return true - } - - return false -}; - -glob.Glob = Glob; -inherits$1(Glob, EE); -function Glob (pattern, options, cb) { - if (typeof options === 'function') { - cb = options; - options = null; - } - - if (options && options.sync) { - if (cb) - throw new TypeError('callback provided to sync glob') - return new GlobSync(pattern, options) - } - - if (!(this instanceof Glob)) - return new Glob(pattern, options, cb) - - setopts(this, pattern, options); - this._didRealPath = false; - - // process each pattern in the minimatch set - var n = this.minimatch.set.length; - - // The matches are stored as {: true,...} so that - // duplicates are automagically pruned. - // Later, we do an Object.keys() on these. - // Keep them as a list so we can fill in when nonull is set. - this.matches = new Array(n); - - if (typeof cb === 'function') { - cb = once(cb); - this.on('error', cb); - this.on('end', function (matches) { - cb(null, matches); - }); - } - - var self = this; - this._processing = 0; - - this._emitQueue = []; - this._processQueue = []; - this.paused = false; - - if (this.noprocess) - return this - - if (n === 0) - return done() - - var sync = true; - for (var i = 0; i < n; i ++) { - this._process(this.minimatch.set[i], i, false, done); - } - sync = false; - - function done () { - --self._processing; - if (self._processing <= 0) { - if (sync) { - process.nextTick(function () { - self._finish(); - }); - } else { - self._finish(); - } - } - } -} - -Glob.prototype._finish = function () { - assert(this instanceof Glob); - if (this.aborted) - return - - if (this.realpath && !this._didRealpath) - return this._realpath() - - common.finish(this); - this.emit('end', this.found); -}; - -Glob.prototype._realpath = function () { - if (this._didRealpath) - return - - this._didRealpath = true; - - var n = this.matches.length; - if (n === 0) - return this._finish() - - var self = this; - for (var i = 0; i < this.matches.length; i++) - this._realpathSet(i, next); - - function next () { - if (--n === 0) - self._finish(); - } -}; - -Glob.prototype._realpathSet = function (index, cb) { - var matchset = this.matches[index]; - if (!matchset) - return cb() - - var found = Object.keys(matchset); - var self = this; - var n = found.length; - - if (n === 0) - return cb() - - var set = this.matches[index] = Object.create(null); - found.forEach(function (p, i) { - // If there's a problem with the stat, then it means that - // one or more of the links in the realpath couldn't be - // resolved. just return the abs value in that case. - p = self._makeAbs(p); - rp.realpath(p, self.realpathCache, function (er, real) { - if (!er) - set[real] = true; - else if (er.syscall === 'stat') - set[p] = true; - else - self.emit('error', er); // srsly wtf right here - - if (--n === 0) { - self.matches[index] = set; - cb(); - } - }); - }); -}; - -Glob.prototype._mark = function (p) { - return common.mark(this, p) -}; - -Glob.prototype._makeAbs = function (f) { - return common.makeAbs(this, f) -}; - -Glob.prototype.abort = function () { - this.aborted = true; - this.emit('abort'); -}; - -Glob.prototype.pause = function () { - if (!this.paused) { - this.paused = true; - this.emit('pause'); - } -}; - -Glob.prototype.resume = function () { - if (this.paused) { - this.emit('resume'); - this.paused = false; - if (this._emitQueue.length) { - var eq = this._emitQueue.slice(0); - this._emitQueue.length = 0; - for (var i = 0; i < eq.length; i ++) { - var e = eq[i]; - this._emitMatch(e[0], e[1]); - } - } - if (this._processQueue.length) { - var pq = this._processQueue.slice(0); - this._processQueue.length = 0; - for (var i = 0; i < pq.length; i ++) { - var p = pq[i]; - this._processing--; - this._process(p[0], p[1], p[2], p[3]); - } - } - } -}; - -Glob.prototype._process = function (pattern, index, inGlobStar, cb) { - assert(this instanceof Glob); - assert(typeof cb === 'function'); - - if (this.aborted) - return - - this._processing++; - if (this.paused) { - this._processQueue.push([pattern, index, inGlobStar, cb]); - return - } - - //console.error('PROCESS %d', this._processing, pattern) - - // Get the first [n] parts of pattern that are all strings. - var n = 0; - while (typeof pattern[n] === 'string') { - n ++; - } - // now n is the index of the first one that is *not* a string. - - // see if there's anything else - var prefix; - switch (n) { - // if not, then this is rather simple - case pattern.length: - this._processSimple(pattern.join('/'), index, cb); - return - - case 0: - // pattern *starts* with some non-trivial item. - // going to readdir(cwd), but not include the prefix in matches. - prefix = null; - break - - default: - // pattern has some string bits in the front. - // whatever it starts with, whether that's 'absolute' like /foo/bar, - // or 'relative' like '../baz' - prefix = pattern.slice(0, n).join('/'); - break - } - - var remain = pattern.slice(n); - - // get the list of entries. - var read; - if (prefix === null) - read = '.'; - else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) { - if (!prefix || !isAbsolute(prefix)) - prefix = '/' + prefix; - read = prefix; - } else - read = prefix; - - var abs = this._makeAbs(read); - - //if ignored, skip _processing - if (childrenIgnored(this, read)) - return cb() - - var isGlobStar = remain[0] === minimatch.GLOBSTAR; - if (isGlobStar) - this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb); - else - this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb); -}; - -Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this; - this._readdir(abs, inGlobStar, function (er, entries) { - return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb) - }); -}; - -Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - - // if the abs isn't a dir, then nothing can match! - if (!entries) - return cb() - - // It will only match dot entries if it starts with a dot, or if - // dot is set. Stuff like @(.foo|.bar) isn't allowed. - var pn = remain[0]; - var negate = !!this.minimatch.negate; - var rawGlob = pn._glob; - var dotOk = this.dot || rawGlob.charAt(0) === '.'; - - var matchedEntries = []; - for (var i = 0; i < entries.length; i++) { - var e = entries[i]; - if (e.charAt(0) !== '.' || dotOk) { - var m; - if (negate && !prefix) { - m = !e.match(pn); - } else { - m = e.match(pn); - } - if (m) - matchedEntries.push(e); - } - } - - //console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries) - - var len = matchedEntries.length; - // If there are no matched entries, then nothing matches. - if (len === 0) - return cb() - - // if this is the last remaining pattern bit, then no need for - // an additional stat *unless* the user has specified mark or - // stat explicitly. We know they exist, since readdir returned - // them. - - if (remain.length === 1 && !this.mark && !this.stat) { - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e; - else - e = prefix + e; - } - - if (e.charAt(0) === '/' && !this.nomount) { - e = path$1.join(this.root, e); - } - this._emitMatch(index, e); - } - // This was the last one, and no stats were needed - return cb() - } - - // now test all matched entries as stand-ins for that part - // of the pattern. - remain.shift(); - for (var i = 0; i < len; i ++) { - var e = matchedEntries[i]; - if (prefix) { - if (prefix !== '/') - e = prefix + '/' + e; - else - e = prefix + e; - } - this._process([e].concat(remain), index, inGlobStar, cb); - } - cb(); -}; - -Glob.prototype._emitMatch = function (index, e) { - if (this.aborted) - return - - if (isIgnored(this, e)) - return - - if (this.paused) { - this._emitQueue.push([index, e]); - return - } - - var abs = isAbsolute(e) ? e : this._makeAbs(e); - - if (this.mark) - e = this._mark(e); - - if (this.absolute) - e = abs; - - if (this.matches[index][e]) - return - - if (this.nodir) { - var c = this.cache[abs]; - if (c === 'DIR' || Array.isArray(c)) - return - } - - this.matches[index][e] = true; - - var st = this.statCache[abs]; - if (st) - this.emit('stat', e, st); - - this.emit('match', e); -}; - -Glob.prototype._readdirInGlobStar = function (abs, cb) { - if (this.aborted) - return - - // follow all symlinked directories forever - // just proceed as if this is a non-globstar situation - if (this.follow) - return this._readdir(abs, false, cb) - - var lstatkey = 'lstat\0' + abs; - var self = this; - var lstatcb = inflight(lstatkey, lstatcb_); - - if (lstatcb) - fs.lstat(abs, lstatcb); - - function lstatcb_ (er, lstat) { - if (er && er.code === 'ENOENT') - return cb() - - var isSym = lstat && lstat.isSymbolicLink(); - self.symlinks[abs] = isSym; - - // If it's not a symlink or a dir, then it's definitely a regular file. - // don't bother doing a readdir in that case. - if (!isSym && lstat && !lstat.isDirectory()) { - self.cache[abs] = 'FILE'; - cb(); - } else - self._readdir(abs, false, cb); - } -}; - -Glob.prototype._readdir = function (abs, inGlobStar, cb) { - if (this.aborted) - return - - cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb); - if (!cb) - return - - //console.error('RD %j %j', +inGlobStar, abs) - if (inGlobStar && !ownProp(this.symlinks, abs)) - return this._readdirInGlobStar(abs, cb) - - if (ownProp(this.cache, abs)) { - var c = this.cache[abs]; - if (!c || c === 'FILE') - return cb() - - if (Array.isArray(c)) - return cb(null, c) - } - fs.readdir(abs, readdirCb(this, abs, cb)); -}; - -function readdirCb (self, abs, cb) { - return function (er, entries) { - if (er) - self._readdirError(abs, er, cb); - else - self._readdirEntries(abs, entries, cb); - } -} - -Glob.prototype._readdirEntries = function (abs, entries, cb) { - if (this.aborted) - return - - // if we haven't asked to stat everything, then just - // assume that everything in there exists, so we can avoid - // having to stat it a second time. - if (!this.mark && !this.stat) { - for (var i = 0; i < entries.length; i ++) { - var e = entries[i]; - if (abs === '/') - e = abs + e; - else - e = abs + '/' + e; - this.cache[e] = true; - } - } - - this.cache[abs] = entries; - return cb(null, entries) -}; - -Glob.prototype._readdirError = function (f, er, cb) { - if (this.aborted) - return - - // handle errors, and cache the information - switch (er.code) { - case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205 - case 'ENOTDIR': // totally normal. means it *does* exist. - var abs = this._makeAbs(f); - this.cache[abs] = 'FILE'; - if (abs === this.cwdAbs) { - var error = new Error(er.code + ' invalid cwd ' + this.cwd); - error.path = this.cwd; - error.code = er.code; - this.emit('error', error); - this.abort(); - } - break - - case 'ENOENT': // not terribly unusual - case 'ELOOP': - case 'ENAMETOOLONG': - case 'UNKNOWN': - this.cache[this._makeAbs(f)] = false; - break - - default: // some unusual error. Treat as failure. - this.cache[this._makeAbs(f)] = false; - if (this.strict) { - this.emit('error', er); - // If the error is handled, then we abort - // if not, we threw out of here - this.abort(); - } - if (!this.silent) - console.error('glob error', er); - break - } - - return cb() -}; - -Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) { - var self = this; - this._readdir(abs, inGlobStar, function (er, entries) { - self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb); - }); -}; - - -Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) { - //console.error('pgs2', prefix, remain[0], entries) - - // no entries means not a dir, so it can never have matches - // foo.txt/** doesn't match foo.txt - if (!entries) - return cb() - - // test without the globstar, and with every child both below - // and replacing the globstar. - var remainWithoutGlobStar = remain.slice(1); - var gspref = prefix ? [ prefix ] : []; - var noGlobStar = gspref.concat(remainWithoutGlobStar); - - // the noGlobStar pattern exits the inGlobStar state - this._process(noGlobStar, index, false, cb); - - var isSym = this.symlinks[abs]; - var len = entries.length; - - // If it's a symlink, and we're in a globstar, then stop - if (isSym && inGlobStar) - return cb() - - for (var i = 0; i < len; i++) { - var e = entries[i]; - if (e.charAt(0) === '.' && !this.dot) - continue - - // these two cases enter the inGlobStar state - var instead = gspref.concat(entries[i], remainWithoutGlobStar); - this._process(instead, index, true, cb); - - var below = gspref.concat(entries[i], remain); - this._process(below, index, true, cb); - } - - cb(); -}; - -Glob.prototype._processSimple = function (prefix, index, cb) { - // XXX review this. Shouldn't it be doing the mounting etc - // before doing stat? kinda weird? - var self = this; - this._stat(prefix, function (er, exists) { - self._processSimple2(prefix, index, er, exists, cb); - }); -}; -Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) { - - //console.error('ps2', prefix, exists) - - if (!this.matches[index]) - this.matches[index] = Object.create(null); - - // If it doesn't exist, then just mark the lack of results - if (!exists) - return cb() - - if (prefix && isAbsolute(prefix) && !this.nomount) { - var trail = /[\/\\]$/.test(prefix); - if (prefix.charAt(0) === '/') { - prefix = path$1.join(this.root, prefix); - } else { - prefix = path$1.resolve(this.root, prefix); - if (trail) - prefix += '/'; - } - } - - if (process.platform === 'win32') - prefix = prefix.replace(/\\/g, '/'); - - // Mark this as a match - this._emitMatch(index, prefix); - cb(); -}; - -// Returns either 'DIR', 'FILE', or false -Glob.prototype._stat = function (f, cb) { - var abs = this._makeAbs(f); - var needDir = f.slice(-1) === '/'; - - if (f.length > this.maxLength) - return cb() - - if (!this.stat && ownProp(this.cache, abs)) { - var c = this.cache[abs]; - - if (Array.isArray(c)) - c = 'DIR'; - - // It exists, but maybe not how we need it - if (!needDir || c === 'DIR') - return cb(null, c) - - if (needDir && c === 'FILE') - return cb() - - // otherwise we have to stat, because maybe c=true - // if we know it exists, but not what it is. - } - var stat = this.statCache[abs]; - if (stat !== undefined) { - if (stat === false) - return cb(null, stat) - else { - var type = stat.isDirectory() ? 'DIR' : 'FILE'; - if (needDir && type === 'FILE') - return cb() - else - return cb(null, type, stat) - } - } - - var self = this; - var statcb = inflight('stat\0' + abs, lstatcb_); - if (statcb) - fs.lstat(abs, statcb); - - function lstatcb_ (er, lstat) { - if (lstat && lstat.isSymbolicLink()) { - // If it's a symlink, then treat it as the target, unless - // the target does not exist, then treat it as a file. - return fs.stat(abs, function (er, stat) { - if (er) - self._stat2(f, abs, null, lstat, cb); - else - self._stat2(f, abs, er, stat, cb); - }) - } else { - self._stat2(f, abs, er, lstat, cb); - } - } -}; - -Glob.prototype._stat2 = function (f, abs, er, stat, cb) { - if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) { - this.statCache[abs] = false; - return cb() - } - - var needDir = f.slice(-1) === '/'; - this.statCache[abs] = stat; - - if (abs.slice(-1) === '/' && stat && !stat.isDirectory()) - return cb(null, false, stat) - - var c = true; - if (stat) - c = stat.isDirectory() ? 'DIR' : 'FILE'; - this.cache[abs] = this.cache[abs] || c; - - if (needDir && c === 'FILE') - return cb() - - return cb(null, c, stat) -}; - -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -var isBuffer = function isBuffer (obj) { - return obj != null && obj.constructor != null && - typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -}; - -var own$b = {}.hasOwnProperty; - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - */ - -/** - * Stringify one point, a position (start and end points), or a node’s - * positional information. - * - * @param {Node|Position|Point} [value] - * @returns {string} - */ -function stringifyPosition$1(value) { - // Nothing. - if (!value || typeof value !== 'object') { - return '' - } - - // Node. - if (own$b.call(value, 'position') || own$b.call(value, 'type')) { - // @ts-ignore looks like a node. - return position(value.position) - } - - // Position. - if (own$b.call(value, 'start') || own$b.call(value, 'end')) { - // @ts-ignore looks like a position. - return position(value) - } - - // Point. - if (own$b.call(value, 'line') || own$b.call(value, 'column')) { - // @ts-ignore looks like a point. - return point$1(value) - } - - // ? - return '' -} - -/** - * @param {Point} point - * @returns {string} - */ -function point$1(point) { - return index$1(point && point.line) + ':' + index$1(point && point.column) -} - -/** - * @param {Position} pos - * @returns {string} - */ -function position(pos) { - return point$1(pos && pos.start) + '-' + point$1(pos && pos.end) -} - -/** - * @param {number} value - * @returns {number} - */ -function index$1(value) { - return value && typeof value === 'number' ? value : 1 -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - */ - -class VFileMessage extends Error { - /** - * Constructor of a message for `reason` at `place` from `origin`. - * When an error is passed in as `reason`, copies the `stack`. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - */ - constructor(reason, place, origin) { - /** @type {[string?, string?]} */ - var parts = [null, null]; - /** @type {Position} */ - var position = { - start: {line: null, column: null}, - end: {line: null, column: null} - }; - /** @type {number} */ - var index; - - super(); - - if (typeof place === 'string') { - origin = place; - place = null; - } - - if (typeof origin === 'string') { - index = origin.indexOf(':'); - - if (index === -1) { - parts[1] = origin; - } else { - parts[0] = origin.slice(0, index); - parts[1] = origin.slice(index + 1); - } - } - - if (place) { - // Node. - if ('type' in place || 'position' in place) { - if (place.position) { - position = place.position; - } - } - // Position. - else if ('start' in place || 'end' in place) { - // @ts-ignore Looks like a position. - position = place; - } - // Point. - else if ('line' in place || 'column' in place) { - // @ts-ignore Looks like a point. - position.start = place; - } - } - - // Fields from `Error` - this.name = stringifyPosition$1(place) || '1:1'; - this.message = typeof reason === 'object' ? reason.message : reason; - this.stack = typeof reason === 'object' ? reason.stack : ''; - - /** - * Reason for message. - * @type {string} - */ - this.reason = this.message; - /** - * Starting line of error. - * @type {number?} - */ - this.line = position.start.line; - /** - * Starting column of error. - * @type {number?} - */ - this.column = position.start.column; - /** - * Namespace of warning. - * @type {string?} - */ - this.source = parts[0]; - /** - * Category of message. - * @type {string?} - */ - this.ruleId = parts[1]; - /** - * Full range information, when available. - * Has start and end properties, both set to an object with line and column, set to number?. - * @type {Position?} - */ - this.position = position; - - // The following fields are “well known”. - // Not standard. - // Feel free to add other non-standard fields to your messages. - - /* eslint-disable no-unused-expressions */ - /** - * You may add a file property with a path of a file (used throughout the VFile ecosystem). - * @type {string?} - */ - this.file; - /** - * If true, marks associated file as no longer processable. - * @type {boolean?} - */ - this.fatal; - /** - * You may add a url property with a link to documentation for the message. - * @type {string?} - */ - this.url; - /** - * You may add a note property with a long form description of the message (supported by vfile-reporter). - * @type {string?} - */ - this.note; - /* eslint-enable no-unused-expressions */ - } -} - -VFileMessage.prototype.file = ''; -VFileMessage.prototype.name = ''; -VFileMessage.prototype.reason = ''; -VFileMessage.prototype.message = ''; -VFileMessage.prototype.stack = ''; -VFileMessage.prototype.fatal = null; -VFileMessage.prototype.column = null; -VFileMessage.prototype.line = null; -VFileMessage.prototype.source = null; -VFileMessage.prototype.ruleId = null; -VFileMessage.prototype.position = null; - -const proc$1 = process$1; - -/** - * @typedef URL - * @property {string} hash - * @property {string} host - * @property {string} hostname - * @property {string} href - * @property {string} origin - * @property {string} password - * @property {string} pathname - * @property {string} port - * @property {string} protocol - * @property {string} search - * @property {any} searchParams - * @property {string} username - * @property {() => string} toString - * @property {() => string} toJSON - */ - -/** - * @param {unknown} fileURLOrPath - * @returns {fileURLOrPath is URL} - */ -// From: -function isUrl(fileURLOrPath) { - return ( - fileURLOrPath !== null && - typeof fileURLOrPath === 'object' && - // @ts-expect-error: indexable. - fileURLOrPath.href && - // @ts-expect-error: indexable. - fileURLOrPath.origin - ) -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - * @typedef {import('./minurl.shared.js').URL} URL - * - * @typedef {'ascii'|'utf8'|'utf-8'|'utf16le'|'ucs2'|'ucs-2'|'base64'|'latin1'|'binary'|'hex'} BufferEncoding - * Encodings supported by the buffer class. - * This is a copy of the typing from Node, copied to prevent Node globals from - * being needed. - * Copied from: - * - * @typedef {string|Uint8Array} VFileValue - * Contents of the file. - * Can either be text, or a Buffer like structure. - * This does not directly use type `Buffer`, because it can also be used in a - * browser context. - * Instead this leverages `Uint8Array` which is the base type for `Buffer`, - * and a native JavaScript construct. - * - * @typedef {VFileValue|VFileOptions|VFile|URL} VFileCompatible - * Things that can be passed to the constructor. - * - * @typedef VFileCoreOptions - * @property {VFileValue} [value] - * @property {string} [cwd] - * @property {Array.} [history] - * @property {string|URL} [path] - * @property {string} [basename] - * @property {string} [stem] - * @property {string} [extname] - * @property {string} [dirname] - * @property {Object.} [data] - * - * @typedef {{[key: string]: unknown} & VFileCoreOptions} VFileOptions - * Configuration: a bunch of keys that will be shallow copied over to the new - * file. - * - * @typedef {Object.} VFileReporterSettings - * @typedef {(files: VFile[], options: T) => string} VFileReporter - */ - -// Order of setting (least specific to most), we need this because otherwise -// `{stem: 'a', path: '~/b.js'}` would throw, as a path is needed before a -// stem can be set. -const order = ['history', 'path', 'basename', 'stem', 'extname', 'dirname']; - -class VFile { - /** - * Create a new virtual file. - * - * If `options` is `string` or `Buffer`, treats it as `{value: options}`. - * If `options` is a `VFile`, shallow copies its data over to the new file. - * All other given fields are set on the newly created `VFile`. - * - * Path related properties are set in the following order (least specific to - * most specific): `history`, `path`, `basename`, `stem`, `extname`, - * `dirname`. - * - * It’s not possible to set either `dirname` or `extname` without setting - * either `history`, `path`, `basename`, or `stem` as well. - * - * @param {VFileCompatible} [value] - */ - constructor(value) { - /** @type {VFileOptions} */ - let options; - - if (!value) { - options = {}; - } else if (typeof value === 'string' || isBuffer(value)) { - // @ts-expect-error Looks like a buffer. - options = {value}; - } else if (isUrl(value)) { - options = {path: value}; - } else { - // @ts-expect-error Looks like file or options. - options = value; - } - - /** - * Place to store custom information. - * It’s OK to store custom data directly on the file, moving it to `data` - * gives a little more privacy. - * @type {Object.} - */ - this.data = {}; - - /** - * List of messages associated with the file. - * @type {Array.} - */ - this.messages = []; - - /** - * List of file paths the file moved between. - * @type {Array.} - */ - this.history = []; - - /** - * Base of `path`. - * Defaults to `process.cwd()` (`/` in browsers). - * @type {string} - */ - this.cwd = proc$1.cwd(); - - /* eslint-disable no-unused-expressions */ - /** - * Raw value. - * @type {VFileValue} - */ - this.value; - - // The below are non-standard, they are “well-known”. - // As in, used in several tools. - - /** - * Whether a file was saved to disk. - * This is used by vfile reporters. - * @type {boolean} - */ - this.stored; - - /** - * Sometimes files have a non-string representation. - * This can be stored in the `result` field. - * One example is when turning markdown into React nodes. - * This is used by unified to store non-string results. - * @type {unknown} - */ - this.result; - - /** - * Sometimes files have a source map associated with them. - * This can be stored in the `map` field. - * This should be a `RawSourceMap` type from the `source-map` module. - * @type {unknown} - */ - this.map; - /* eslint-enable no-unused-expressions */ - - // Set path related properties in the correct order. - let index = -1; - - while (++index < order.length) { - const prop = order[index]; - - // Note: we specifically use `in` instead of `hasOwnProperty` to accept - // `vfile`s too. - if (prop in options && options[prop] !== undefined) { - // @ts-expect-error: TS is confused by the different types for `history`. - this[prop] = prop === 'history' ? [...options[prop]] : options[prop]; - } - } - - /** @type {string} */ - let prop; - - // Set non-path related properties. - for (prop in options) { - // @ts-expect-error: fine to set other things. - if (!order.includes(prop)) this[prop] = options[prop]; - } - } - - /** - * Access full path (`~/index.min.js`). - * - * @returns {string} - */ - get path() { - return this.history[this.history.length - 1] - } - - /** - * Set full path (`~/index.min.js`). - * Cannot be nullified. - * - * @param {string|URL} path - */ - set path(path) { - if (isUrl(path)) { - path = fileURLToPath(path); - } - - assertNonEmpty(path, 'path'); - - if (this.path !== path) { - this.history.push(path); - } - } - - /** - * Access parent path (`~`). - */ - get dirname() { - return typeof this.path === 'string' ? path$b.dirname(this.path) : undefined - } - - /** - * Set parent path (`~`). - * Cannot be set if there's no `path` yet. - */ - set dirname(dirname) { - assertPath(this.basename, 'dirname'); - this.path = path$b.join(dirname || '', this.basename); - } - - /** - * Access basename (including extname) (`index.min.js`). - */ - get basename() { - return typeof this.path === 'string' ? path$b.basename(this.path) : undefined - } - - /** - * Set basename (`index.min.js`). - * Cannot contain path separators. - * Cannot be nullified either (use `file.path = file.dirname` instead). - */ - set basename(basename) { - assertNonEmpty(basename, 'basename'); - assertPart(basename, 'basename'); - this.path = path$b.join(this.dirname || '', basename); - } - - /** - * Access extname (including dot) (`.js`). - */ - get extname() { - return typeof this.path === 'string' ? path$b.extname(this.path) : undefined - } - - /** - * Set extname (including dot) (`.js`). - * Cannot be set if there's no `path` yet and cannot contain path separators. - */ - set extname(extname) { - assertPart(extname, 'extname'); - assertPath(this.dirname, 'extname'); - - if (extname) { - if (extname.charCodeAt(0) !== 46 /* `.` */) { - throw new Error('`extname` must start with `.`') - } - - if (extname.includes('.', 1)) { - throw new Error('`extname` cannot contain multiple dots') - } - } - - this.path = path$b.join(this.dirname, this.stem + (extname || '')); - } - - /** - * Access stem (w/o extname) (`index.min`). - */ - get stem() { - return typeof this.path === 'string' - ? path$b.basename(this.path, this.extname) - : undefined - } - - /** - * Set stem (w/o extname) (`index.min`). - * Cannot be nullified, and cannot contain path separators. - */ - set stem(stem) { - assertNonEmpty(stem, 'stem'); - assertPart(stem, 'stem'); - this.path = path$b.join(this.dirname || '', stem + (this.extname || '')); - } - - /** - * Serialize the file. - * - * @param {BufferEncoding} [encoding='utf8'] If `file.value` is a buffer, `encoding` is used to serialize buffers. - * @returns {string} - */ - toString(encoding) { - // @ts-expect-error string’s don’t accept the parameter, but buffers do. - return (this.value || '').toString(encoding) - } - - /** - * Create a message and associates it w/ the file. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - * @returns {VFileMessage} - */ - message(reason, place, origin) { - const message = new VFileMessage(reason, place, origin); - - if (this.path) { - message.name = this.path + ':' + message.name; - message.file = this.path; - } - - message.fatal = false; - - this.messages.push(message); - - return message - } - - /** - * Info: create a message, associate it with the file, and mark the fatality - * as `null`. - * Calls `message()` internally. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - * @returns {VFileMessage} - */ - info(reason, place, origin) { - const message = this.message(reason, place, origin); - - message.fatal = null; - - return message - } - - /** - * Fail: create a message, associate it with the file, mark the fatality as - * `true`. - * Note: fatal errors mean a file is no longer processable. - * Calls `message()` internally. - * - * @param {string|Error} reason Reason for message (`string` or `Error`). Uses the stack and message of the error if given. - * @param {Node|Position|Point} [place] Place at which the message occurred in a file (`Node`, `Position`, or `Point`, optional). - * @param {string} [origin] Place in code the message originates from (`string`, optional). - * @returns {never} - */ - fail(reason, place, origin) { - const message = this.message(reason, place, origin); - - message.fatal = true; - - throw message - } -} - -/** - * Assert that `part` is not a path (as in, does not contain `path.sep`). - * - * @param {string|undefined} part - * @param {string} name - * @returns {void} - */ -function assertPart(part, name) { - if (part && part.includes(path$b.sep)) { - throw new Error( - '`' + name + '` cannot be a path: did not expect `' + path$b.sep + '`' - ) - } -} - -/** - * Assert that `part` is not empty. - * - * @param {string|undefined} part - * @param {string} name - * @returns {asserts part is string} - */ -function assertNonEmpty(part, name) { - if (!part) { - throw new Error('`' + name + '` cannot be empty') - } -} - -/** - * Assert `path` exists. - * - * @param {string|undefined} path - * @param {string} name - * @returns {asserts path is string} - */ -function assertPath(path, name) { - if (!path) { - throw new Error('Setting `' + name + '` requires `path` to be set too') - } -} - -/** - * @typedef {import('vfile').VFileValue} Value - * @typedef {import('vfile').VFileOptions} Options - * @typedef {import('vfile').BufferEncoding} BufferEncoding - * - * @typedef {number|string} Mode - * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, flag?: string}} ReadOptions - * @typedef {BufferEncoding|{encoding?: null|BufferEncoding, mode: Mode?, flag?: string}} WriteOptions - * - * @typedef {string|Uint8Array} Path Path of the file. - * @typedef {Path|URL|Options|VFile} Compatible Things that can be - * passed to the function. - */ - -/** - * Create a virtual file from a description. - * If `options` is a string or a buffer, it’s used as the path. - * If it’s a VFile itself, it’s returned instead. - * In all other cases, the options are passed through to `vfile()`. - * - * @param {Compatible} [options] - * @returns {VFile} - */ -function toVFile(options) { - if (typeof options === 'string' || options instanceof URL$1) { - options = {path: options}; - } else if (isBuffer(options)) { - options = {path: String(options)}; - } - - return looksLikeAVFile$1(options) ? options : new VFile(options) -} - -/** - * Create a virtual file and read it in, synchronously. - * - * @param {Compatible} description - * @param {ReadOptions} [options] - * @returns {VFile} - */ -function readSync(description, options) { - const file = toVFile(description); - file.value = require$$0$3.readFileSync(path$b.resolve(file.cwd, file.path), options); - return file -} - -/** - * Create a virtual file and write it in, synchronously. - * - * @param {Compatible} description - * @param {WriteOptions} [options] - * @returns {VFile} - */ -function writeSync(description, options) { - const file = toVFile(description); - require$$0$3.writeFileSync(path$b.resolve(file.cwd, file.path), file.value || '', options); - return file -} - -const read$2 = - /** - * @type {{ - * (description: Compatible, options: ReadOptions, callback: Callback): void - * (description: Compatible, callback: Callback): void - * (description: Compatible, options?: ReadOptions): Promise - * }} - */ - ( - /** - * Create a virtual file and read it in, asynchronously. - * - * @param {Compatible} description - * @param {ReadOptions} [options] - * @param {Callback} [callback] - */ - function (description, options, callback) { - const file = toVFile(description); - - if (!callback && typeof options === 'function') { - callback = options; - options = null; - } - - if (!callback) { - return new Promise(executor) - } - - executor(resolve, callback); - - /** - * @param {VFile} result - */ - function resolve(result) { - callback(null, result); - } - - /** - * @param {(x: VFile) => void} resolve - * @param {(x: Error, y?: VFile) => void} reject - */ - function executor(resolve, reject) { - /** @type {string} */ - let fp; - - try { - fp = path$b.resolve(file.cwd, file.path); - } catch (error) { - return reject(error) - } - - require$$0$3.readFile(fp, options, done); - - /** - * @param {Error} error - * @param {Value} result - */ - function done(error, result) { - if (error) { - reject(error); - } else { - file.value = result; - resolve(file); - } - } - } - } - ); - -const write = - /** - * @type {{ - * (description: Compatible, options: WriteOptions, callback: Callback): void - * (description: Compatible, callback: Callback): void - * (description: Compatible, options?: WriteOptions): Promise - * }} - */ - ( - /** - * Create a virtual file and write it in, asynchronously. - * - * @param {Compatible} description - * @param {WriteOptions} [options] - * @param {Callback} [callback] - */ - function (description, options, callback) { - const file = toVFile(description); - - // Weird, right? Otherwise `fs` doesn’t accept it. - if (!callback && typeof options === 'function') { - callback = options; - options = undefined; - } - - if (!callback) { - return new Promise(executor) - } - - executor(resolve, callback); - - /** - * @param {VFile} result - */ - function resolve(result) { - callback(null, result); - } - - /** - * @param {(x: VFile) => void} resolve - * @param {(x: Error, y?: VFile) => void} reject - */ - function executor(resolve, reject) { - /** @type {string} */ - let fp; - - try { - fp = path$b.resolve(file.cwd, file.path); - } catch (error) { - return reject(error) - } - - require$$0$3.writeFile(fp, file.value || '', options, done); - - /** - * @param {Error} error - */ - function done(error) { - if (error) { - reject(error); - } else { - resolve(file); - } - } - } - } - ); - -/** - * @param {Compatible} value - * @returns {value is VFile} - */ -function looksLikeAVFile$1(value) { - return ( - value && - typeof value === 'object' && - 'message' in value && - 'messages' in value - ) -} - -toVFile.readSync = readSync; -toVFile.writeSync = writeSync; -toVFile.read = read$2; -toVFile.write = write; - -/** - * @typedef {import('fs').Stats} Stats - * @typedef {import('vfile').VFile} VFile - * @typedef {import('./ignore.js').Ignore} Ignore - * @typedef {import('ignore').Ignore} GitIgnore - * - * @typedef Options - * @property {string} cwd - * @property {Array.} extensions - * @property {boolean|undefined} silentlyIgnore - * @property {Array.} ignorePatterns - * @property {Ignore} ignore - * - * @typedef SearchResults - * @property {fs.Stats|undefined} stats - * @property {boolean|undefined} ignored - * - * @typedef Result - * @property {Array.} input - * @property {VFile[]} output - * - * @typedef CleanResult - * @property {boolean} oneFileMode - * @property {VFile[]} files - * - * @callback Callback - * @param {Error|null} error - * @param {CleanResult} [result] - */ - -/** - * Search `patterns`, a mix of globs, paths, and files. - * - * @param {Array.} input - * @param {Options} options - * @param {Callback} callback - */ -function finder(input, options, callback) { - expand(input, options, (error, result) => { - // Glob errors are unusual. - // other errors are on the vfile results. - /* c8 ignore next 2 */ - if (error || !result) { - callback(error); - } else { - callback(null, {oneFileMode: oneFileMode(result), files: result.output}); - } - }); -} - -/** - * Expand the given glob patterns, search given and found directories, and map - * to vfiles. - * - * @param {Array.} input - * @param {Options} options - * @param {(error: Error|null, result?: Result) => void} next - */ -function expand(input, options, next) { - /** @type {Array.} */ - let paths = []; - let actual = 0; - let expected = 0; - let index = -1; - /** @type {boolean|undefined} */ - let failed; - - while (++index < input.length) { - let file = input[index]; - if (typeof file === 'string') { - if (glob_1.hasMagic(file)) { - expected++; - glob_1(file, {cwd: options.cwd}, (error, files) => { - // Glob errors are unusual. - /* c8 ignore next 3 */ - if (failed) { - return - } - - // Glob errors are unusual. - /* c8 ignore next 4 */ - if (error) { - failed = true; - done1(error); - } else { - actual++; - paths = paths.concat(files); - - if (actual === expected) { - search$1(paths, options, done1); - } - } - }); - } else { - // `relative` to make the paths canonical. - file = - path$c.relative(options.cwd, path$c.resolve(options.cwd, file)) || '.'; - paths.push(file); - } - } else { - const fp = file.path ? path$c.relative(options.cwd, file.path) : options.cwd; - file.cwd = options.cwd; - file.path = fp; - file.history = [fp]; - paths.push(file); - } - } - - if (!expected) { - search$1(paths, options, done1); - } - - /** - * @param {Error|null} error - * @param {Array} [files] - */ - function done1(error, files) { - // `search` currently does not give errors. - /* c8 ignore next 2 */ - if (error || !files) { - next(error); - } else { - next(null, {input: paths, output: files}); - } - } -} - -/** - * Search `paths`. - * - * @param {Array.} input - * @param {Options & {nested?: boolean}} options - * @param {(error: Error|null, files: Array.) => void} next - */ -function search$1(input, options, next) { - const extraIgnore = ignore().add(options.ignorePatterns); - let expected = 0; - let actual = 0; - let index = -1; - /** @type {Array.} */ - let files = []; - - while (++index < input.length) { - each(input[index]); - } - - if (!expected) { - next(null, files); - } - - /** - * @param {string|VFile} file - */ - function each(file) { - const ext = typeof file === 'string' ? path$c.extname(file) : file.extname; - - // Normalise globs. - if (typeof file === 'string') { - file = file.split('/').join(path$c.sep); - } - - const part = base$1(file); - - if ( - options.nested && - part && - (part.charAt(0) === '.' || part === 'node_modules') - ) { - return - } - - expected++; - - statAndIgnore( - file, - Object.assign({}, options, {extraIgnore}), - (error, result) => { - const ignored = result && result.ignored; - const dir = result && result.stats && result.stats.isDirectory(); - - if (ignored && (options.nested || options.silentlyIgnore)) { - return one(null, []) - } - - if (!ignored && dir) { - return fs$a.readdir( - path$c.resolve(options.cwd, filePath(file)), - (error, basenames) => { - // Should not happen often: the directory is `stat`ed first, which was ok, - // but reading it is not. - /* c8 ignore next 9 */ - if (error) { - const otherFile = toVFile(filePath(file)); - otherFile.cwd = options.cwd; - - try { - otherFile.fail('Cannot read directory'); - } catch {} - - one(null, [otherFile]); - } else { - search$1( - basenames.map((name) => path$c.join(filePath(file), name)), - Object.assign({}, options, {nested: true}), - one - ); - } - } - ) - } - - if ( - !dir && - options.nested && - options.extensions.length > 0 && - (!ext || !options.extensions.includes(ext)) - ) { - return one(null, []) - } - - file = toVFile(file); - file.cwd = options.cwd; - - if (ignored) { - try { - file.fail('Cannot process specified file: it’s ignored'); - // C8 bug on Node@12 - /* c8 ignore next 1 */ - } catch {} - } - - if (error && error.code === 'ENOENT') { - try { - file.fail( - error.syscall === 'stat' ? 'No such file or directory' : error - ); - // C8 bug on Node@12 - /* c8 ignore next 1 */ - } catch {} - } - - one(null, [file]); - } - ); - - /** - * Error is never given. Always given `results`. - * - * @param {Error|null} _ - * @param {Array.} results - */ - function one(_, results) { - /* istanbul ignore else - Always given. */ - if (results) { - files = files.concat(results); - } - - actual++; - - if (actual === expected) { - next(null, files); - } - } - } -} - -/** - * @param {VFile|string} file - * @param {Options & {extraIgnore: GitIgnore}} options - * @param {(error: NodeJS.ErrnoException|null, result?: SearchResults) => void} callback - */ -function statAndIgnore(file, options, callback) { - const fp = path$c.resolve(options.cwd, filePath(file)); - const normal = path$c.relative(options.cwd, fp); - let expected = 1; - let actual = 0; - /** @type {Stats|undefined} */ - let stats; - /** @type {boolean|undefined} */ - let ignored; - - if (typeof file === 'string' || !file.value) { - expected++; - fs$a.stat(fp, (error, value) => { - stats = value; - onStartOrCheck(error); - }); - } - - options.ignore.check(fp, (error, value) => { - ignored = value; - onStartOrCheck(error); - }); - - /** - * @param {Error|null} error - */ - function onStartOrCheck(error) { - actual++; - - if (error) { - callback(error); - actual = -1; - } else if (actual === expected) { - callback(null, { - stats, - ignored: - ignored || - (normal === '' || - normal === '..' || - normal.charAt(0) === path$c.sep || - normal.slice(0, 3) === '..' + path$c.sep - ? false - : options.extraIgnore.ignores(normal)) - }); - } - } -} - -/** - * @param {string|VFile} file - * @returns {string|undefined} - */ -function base$1(file) { - return typeof file === 'string' ? path$c.basename(file) : file.basename -} - -/** - * @param {string|VFile} file - * @returns {string} - */ -function filePath(file) { - return typeof file === 'string' ? file : file.path -} - -/** - * @param {Result} result - * @returns {boolean} - */ -function oneFileMode(result) { - return ( - result.output.length === 1 && - result.input.length === 1 && - result.output[0].path === result.input[0] - ) -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Settings} Settings - * @typedef {import('./index.js').Configuration} Configuration - */ - -/** - * @param {Context} context - * @param {Settings} settings - * @param {Callback} next - */ -function fileSystem$1(context, settings, next) { - if (context.files.length === 0) { - next(); - } else { - finder( - context.files, - { - cwd: settings.cwd, - extensions: settings.extensions, - silentlyIgnore: settings.silentlyIgnore, - ignorePatterns: settings.ignorePatterns, - ignore: new Ignore({ - cwd: settings.cwd, - detectIgnore: settings.detectIgnore, - ignoreName: settings.ignoreName, - ignorePath: settings.ignorePath, - ignorePathResolveFrom: settings.ignorePathResolveFrom - }) - }, - (error, result) => { - // Glob errors typically don’t occur. - /* c8 ignore next 4 */ - if (!result) { - next(error); - return - } - - const output = result.files; - - // Sort alphabetically. - // Everything is unique so we do not care about cases where left and right - // are equal. - output.sort(sortAlphabetically); - - // Mark as given. - // This allows outputting files, which can be pretty dangerous, so it’s - // “hidden”. - let index = -1; - while (++index < output.length) { - output[index].data.unifiedEngineGiven = true; - } - - context.files = output; - - // If `out` was not set, detect it based on whether one file was given. - if (settings.out === null || settings.out === undefined) { - settings.out = result.oneFileMode; - } - - next(error); - } - ); - } - - /** - * @param {VFile} left - * @param {VFile} right - * @returns {number} - */ - function sortAlphabetically(left, right) { - return left.path < right.path ? -1 : 1 - } -} - -/* eslint-disable node/no-deprecated-api */ - -var toString$2 = Object.prototype.toString; - -var isModern = ( - typeof Buffer !== 'undefined' && - typeof Buffer.alloc === 'function' && - typeof Buffer.allocUnsafe === 'function' && - typeof Buffer.from === 'function' -); - -function isArrayBuffer (input) { - return toString$2.call(input).slice(8, -1) === 'ArrayBuffer' -} - -function fromArrayBuffer (obj, byteOffset, length) { - byteOffset >>>= 0; - - var maxLength = obj.byteLength - byteOffset; - - if (maxLength < 0) { - throw new RangeError("'offset' is out of bounds") - } - - if (length === undefined) { - length = maxLength; - } else { - length >>>= 0; - - if (length > maxLength) { - throw new RangeError("'length' is out of bounds") - } - } - - return isModern - ? Buffer.from(obj.slice(byteOffset, byteOffset + length)) - : new Buffer(new Uint8Array(obj.slice(byteOffset, byteOffset + length))) -} - -function fromString (string, encoding) { - if (typeof encoding !== 'string' || encoding === '') { - encoding = 'utf8'; - } - - if (!Buffer.isEncoding(encoding)) { - throw new TypeError('"encoding" must be a valid string encoding') - } - - return isModern - ? Buffer.from(string, encoding) - : new Buffer(string, encoding) -} - -function bufferFrom$1 (value, encodingOrOffset, length) { - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number') - } - - if (isArrayBuffer(value)) { - return fromArrayBuffer(value, encodingOrOffset, length) - } - - if (typeof value === 'string') { - return fromString(value, encodingOrOffset) - } - - return isModern - ? Buffer.from(value) - : new Buffer(value) -} - -var bufferFrom_1 = bufferFrom$1; - -var typedarray = {}; - -(function (exports) { -var undefined$1 = (void 0); // Paranoia - -// Beyond this value, index getters/setters (i.e. array[0], array[1]) are so slow to -// create, and consume so much memory, that the browser appears frozen. -var MAX_ARRAY_LENGTH = 1e5; - -// Approximations of internal ECMAScript conversion functions -var ECMAScript = (function() { - // Stash a copy in case other scripts modify these - var opts = Object.prototype.toString, - ophop = Object.prototype.hasOwnProperty; - - return { - // Class returns internal [[Class]] property, used to avoid cross-frame instanceof issues: - Class: function(v) { return opts.call(v).replace(/^\[object *|\]$/g, ''); }, - HasProperty: function(o, p) { return p in o; }, - HasOwnProperty: function(o, p) { return ophop.call(o, p); }, - IsCallable: function(o) { return typeof o === 'function'; }, - ToInt32: function(v) { return v >> 0; }, - ToUint32: function(v) { return v >>> 0; } - }; -}()); - -// Snapshot intrinsics -var LN2 = Math.LN2, - abs = Math.abs, - floor = Math.floor, - log = Math.log, - min = Math.min, - pow = Math.pow, - round = Math.round; - -// ES5: lock down object properties -function configureProperties(obj) { - if (getOwnPropNames && defineProp) { - var props = getOwnPropNames(obj), i; - for (i = 0; i < props.length; i += 1) { - defineProp(obj, props[i], { - value: obj[props[i]], - writable: false, - enumerable: false, - configurable: false - }); - } - } -} - -// emulate ES5 getter/setter API using legacy APIs -// http://blogs.msdn.com/b/ie/archive/2010/09/07/transitioning-existing-code-to-the-es5-getter-setter-apis.aspx -// (second clause tests for Object.defineProperty() in IE<9 that only supports extending DOM prototypes, but -// note that IE<9 does not support __defineGetter__ or __defineSetter__ so it just renders the method harmless) -var defineProp; -if (Object.defineProperty && (function() { - try { - Object.defineProperty({}, 'x', {}); - return true; - } catch (e) { - return false; - } - })()) { - defineProp = Object.defineProperty; -} else { - defineProp = function(o, p, desc) { - if (!o === Object(o)) throw new TypeError("Object.defineProperty called on non-object"); - if (ECMAScript.HasProperty(desc, 'get') && Object.prototype.__defineGetter__) { Object.prototype.__defineGetter__.call(o, p, desc.get); } - if (ECMAScript.HasProperty(desc, 'set') && Object.prototype.__defineSetter__) { Object.prototype.__defineSetter__.call(o, p, desc.set); } - if (ECMAScript.HasProperty(desc, 'value')) { o[p] = desc.value; } - return o; - }; -} - -var getOwnPropNames = Object.getOwnPropertyNames || function (o) { - if (o !== Object(o)) throw new TypeError("Object.getOwnPropertyNames called on non-object"); - var props = [], p; - for (p in o) { - if (ECMAScript.HasOwnProperty(o, p)) { - props.push(p); - } - } - return props; -}; - -// ES5: Make obj[index] an alias for obj._getter(index)/obj._setter(index, value) -// for index in 0 ... obj.length -function makeArrayAccessors(obj) { - if (!defineProp) { return; } - - if (obj.length > MAX_ARRAY_LENGTH) throw new RangeError("Array too large for polyfill"); - - function makeArrayAccessor(index) { - defineProp(obj, index, { - 'get': function() { return obj._getter(index); }, - 'set': function(v) { obj._setter(index, v); }, - enumerable: true, - configurable: false - }); - } - - var i; - for (i = 0; i < obj.length; i += 1) { - makeArrayAccessor(i); - } -} - -// Internal conversion functions: -// pack() - take a number (interpreted as Type), output a byte array -// unpack() - take a byte array, output a Type-like number - -function as_signed(value, bits) { var s = 32 - bits; return (value << s) >> s; } -function as_unsigned(value, bits) { var s = 32 - bits; return (value << s) >>> s; } - -function packI8(n) { return [n & 0xff]; } -function unpackI8(bytes) { return as_signed(bytes[0], 8); } - -function packU8(n) { return [n & 0xff]; } -function unpackU8(bytes) { return as_unsigned(bytes[0], 8); } - -function packU8Clamped(n) { n = round(Number(n)); return [n < 0 ? 0 : n > 0xff ? 0xff : n & 0xff]; } - -function packI16(n) { return [(n >> 8) & 0xff, n & 0xff]; } -function unpackI16(bytes) { return as_signed(bytes[0] << 8 | bytes[1], 16); } - -function packU16(n) { return [(n >> 8) & 0xff, n & 0xff]; } -function unpackU16(bytes) { return as_unsigned(bytes[0] << 8 | bytes[1], 16); } - -function packI32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } -function unpackI32(bytes) { return as_signed(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } - -function packU32(n) { return [(n >> 24) & 0xff, (n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff]; } -function unpackU32(bytes) { return as_unsigned(bytes[0] << 24 | bytes[1] << 16 | bytes[2] << 8 | bytes[3], 32); } - -function packIEEE754(v, ebits, fbits) { - - var bias = (1 << (ebits - 1)) - 1, - s, e, f, i, bits, str, bytes; - - function roundToEven(n) { - var w = floor(n), f = n - w; - if (f < 0.5) - return w; - if (f > 0.5) - return w + 1; - return w % 2 ? w + 1 : w; - } - - // Compute sign, exponent, fraction - if (v !== v) { - // NaN - // http://dev.w3.org/2006/webapi/WebIDL/#es-type-mapping - e = (1 << ebits) - 1; f = pow(2, fbits - 1); s = 0; - } else if (v === Infinity || v === -Infinity) { - e = (1 << ebits) - 1; f = 0; s = (v < 0) ? 1 : 0; - } else if (v === 0) { - e = 0; f = 0; s = (1 / v === -Infinity) ? 1 : 0; - } else { - s = v < 0; - v = abs(v); - - if (v >= pow(2, 1 - bias)) { - e = min(floor(log(v) / LN2), 1023); - f = roundToEven(v / pow(2, e) * pow(2, fbits)); - if (f / pow(2, fbits) >= 2) { - e = e + 1; - f = 1; - } - if (e > bias) { - // Overflow - e = (1 << ebits) - 1; - f = 0; - } else { - // Normalized - e = e + bias; - f = f - pow(2, fbits); - } - } else { - // Denormalized - e = 0; - f = roundToEven(v / pow(2, 1 - bias - fbits)); - } - } - - // Pack sign, exponent, fraction - bits = []; - for (i = fbits; i; i -= 1) { bits.push(f % 2 ? 1 : 0); f = floor(f / 2); } - for (i = ebits; i; i -= 1) { bits.push(e % 2 ? 1 : 0); e = floor(e / 2); } - bits.push(s ? 1 : 0); - bits.reverse(); - str = bits.join(''); - - // Bits to bytes - bytes = []; - while (str.length) { - bytes.push(parseInt(str.substring(0, 8), 2)); - str = str.substring(8); - } - return bytes; -} - -function unpackIEEE754(bytes, ebits, fbits) { - - // Bytes to bits - var bits = [], i, j, b, str, - bias, s, e, f; - - for (i = bytes.length; i; i -= 1) { - b = bytes[i - 1]; - for (j = 8; j; j -= 1) { - bits.push(b % 2 ? 1 : 0); b = b >> 1; - } - } - bits.reverse(); - str = bits.join(''); - - // Unpack sign, exponent, fraction - bias = (1 << (ebits - 1)) - 1; - s = parseInt(str.substring(0, 1), 2) ? -1 : 1; - e = parseInt(str.substring(1, 1 + ebits), 2); - f = parseInt(str.substring(1 + ebits), 2); - - // Produce number - if (e === (1 << ebits) - 1) { - return f !== 0 ? NaN : s * Infinity; - } else if (e > 0) { - // Normalized - return s * pow(2, e - bias) * (1 + f / pow(2, fbits)); - } else if (f !== 0) { - // Denormalized - return s * pow(2, -(bias - 1)) * (f / pow(2, fbits)); - } else { - return s < 0 ? -0 : 0; - } -} - -function unpackF64(b) { return unpackIEEE754(b, 11, 52); } -function packF64(v) { return packIEEE754(v, 11, 52); } -function unpackF32(b) { return unpackIEEE754(b, 8, 23); } -function packF32(v) { return packIEEE754(v, 8, 23); } - - -// -// 3 The ArrayBuffer Type -// - -(function() { - - /** @constructor */ - var ArrayBuffer = function ArrayBuffer(length) { - length = ECMAScript.ToInt32(length); - if (length < 0) throw new RangeError('ArrayBuffer size is not a small enough positive integer'); - - this.byteLength = length; - this._bytes = []; - this._bytes.length = length; - - var i; - for (i = 0; i < this.byteLength; i += 1) { - this._bytes[i] = 0; - } - - configureProperties(this); - }; - - exports.ArrayBuffer = exports.ArrayBuffer || ArrayBuffer; - - // - // 4 The ArrayBufferView Type - // - - // NOTE: this constructor is not exported - /** @constructor */ - var ArrayBufferView = function ArrayBufferView() { - //this.buffer = null; - //this.byteOffset = 0; - //this.byteLength = 0; - }; - - // - // 5 The Typed Array View Types - // - - function makeConstructor(bytesPerElement, pack, unpack) { - // Each TypedArray type requires a distinct constructor instance with - // identical logic, which this produces. - - var ctor; - ctor = function(buffer, byteOffset, length) { - var array, sequence, i, s; - - if (!arguments.length || typeof arguments[0] === 'number') { - // Constructor(unsigned long length) - this.length = ECMAScript.ToInt32(arguments[0]); - if (length < 0) throw new RangeError('ArrayBufferView size is not a small enough positive integer'); - - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - this.buffer = new ArrayBuffer(this.byteLength); - this.byteOffset = 0; - } else if (typeof arguments[0] === 'object' && arguments[0].constructor === ctor) { - // Constructor(TypedArray array) - array = arguments[0]; - - this.length = array.length; - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - this.buffer = new ArrayBuffer(this.byteLength); - this.byteOffset = 0; - - for (i = 0; i < this.length; i += 1) { - this._setter(i, array._getter(i)); - } - } else if (typeof arguments[0] === 'object' && - !(arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) { - // Constructor(sequence array) - sequence = arguments[0]; - - this.length = ECMAScript.ToUint32(sequence.length); - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - this.buffer = new ArrayBuffer(this.byteLength); - this.byteOffset = 0; - - for (i = 0; i < this.length; i += 1) { - s = sequence[i]; - this._setter(i, Number(s)); - } - } else if (typeof arguments[0] === 'object' && - (arguments[0] instanceof ArrayBuffer || ECMAScript.Class(arguments[0]) === 'ArrayBuffer')) { - // Constructor(ArrayBuffer buffer, - // optional unsigned long byteOffset, optional unsigned long length) - this.buffer = buffer; - - this.byteOffset = ECMAScript.ToUint32(byteOffset); - if (this.byteOffset > this.buffer.byteLength) { - throw new RangeError("byteOffset out of range"); - } - - if (this.byteOffset % this.BYTES_PER_ELEMENT) { - // The given byteOffset must be a multiple of the element - // size of the specific type, otherwise an exception is raised. - throw new RangeError("ArrayBuffer length minus the byteOffset is not a multiple of the element size."); - } - - if (arguments.length < 3) { - this.byteLength = this.buffer.byteLength - this.byteOffset; - - if (this.byteLength % this.BYTES_PER_ELEMENT) { - throw new RangeError("length of buffer minus byteOffset not a multiple of the element size"); - } - this.length = this.byteLength / this.BYTES_PER_ELEMENT; - } else { - this.length = ECMAScript.ToUint32(length); - this.byteLength = this.length * this.BYTES_PER_ELEMENT; - } - - if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { - throw new RangeError("byteOffset and length reference an area beyond the end of the buffer"); - } - } else { - throw new TypeError("Unexpected argument type(s)"); - } - - this.constructor = ctor; - - configureProperties(this); - makeArrayAccessors(this); - }; - - ctor.prototype = new ArrayBufferView(); - ctor.prototype.BYTES_PER_ELEMENT = bytesPerElement; - ctor.prototype._pack = pack; - ctor.prototype._unpack = unpack; - ctor.BYTES_PER_ELEMENT = bytesPerElement; - - // getter type (unsigned long index); - ctor.prototype._getter = function(index) { - if (arguments.length < 1) throw new SyntaxError("Not enough arguments"); - - index = ECMAScript.ToUint32(index); - if (index >= this.length) { - return undefined$1; - } - - var bytes = [], i, o; - for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; - i < this.BYTES_PER_ELEMENT; - i += 1, o += 1) { - bytes.push(this.buffer._bytes[o]); - } - return this._unpack(bytes); - }; - - // NONSTANDARD: convenience alias for getter: type get(unsigned long index); - ctor.prototype.get = ctor.prototype._getter; - - // setter void (unsigned long index, type value); - ctor.prototype._setter = function(index, value) { - if (arguments.length < 2) throw new SyntaxError("Not enough arguments"); - - index = ECMAScript.ToUint32(index); - if (index >= this.length) { - return undefined$1; - } - - var bytes = this._pack(value), i, o; - for (i = 0, o = this.byteOffset + index * this.BYTES_PER_ELEMENT; - i < this.BYTES_PER_ELEMENT; - i += 1, o += 1) { - this.buffer._bytes[o] = bytes[i]; - } - }; - - // void set(TypedArray array, optional unsigned long offset); - // void set(sequence array, optional unsigned long offset); - ctor.prototype.set = function(index, value) { - if (arguments.length < 1) throw new SyntaxError("Not enough arguments"); - var array, sequence, offset, len, - i, s, d, - byteOffset, byteLength, tmp; - - if (typeof arguments[0] === 'object' && arguments[0].constructor === this.constructor) { - // void set(TypedArray array, optional unsigned long offset); - array = arguments[0]; - offset = ECMAScript.ToUint32(arguments[1]); - - if (offset + array.length > this.length) { - throw new RangeError("Offset plus length of array is out of range"); - } - - byteOffset = this.byteOffset + offset * this.BYTES_PER_ELEMENT; - byteLength = array.length * this.BYTES_PER_ELEMENT; - - if (array.buffer === this.buffer) { - tmp = []; - for (i = 0, s = array.byteOffset; i < byteLength; i += 1, s += 1) { - tmp[i] = array.buffer._bytes[s]; - } - for (i = 0, d = byteOffset; i < byteLength; i += 1, d += 1) { - this.buffer._bytes[d] = tmp[i]; - } - } else { - for (i = 0, s = array.byteOffset, d = byteOffset; - i < byteLength; i += 1, s += 1, d += 1) { - this.buffer._bytes[d] = array.buffer._bytes[s]; - } - } - } else if (typeof arguments[0] === 'object' && typeof arguments[0].length !== 'undefined') { - // void set(sequence array, optional unsigned long offset); - sequence = arguments[0]; - len = ECMAScript.ToUint32(sequence.length); - offset = ECMAScript.ToUint32(arguments[1]); - - if (offset + len > this.length) { - throw new RangeError("Offset plus length of array is out of range"); - } - - for (i = 0; i < len; i += 1) { - s = sequence[i]; - this._setter(offset + i, Number(s)); - } - } else { - throw new TypeError("Unexpected argument type(s)"); - } - }; - - // TypedArray subarray(long begin, optional long end); - ctor.prototype.subarray = function(start, end) { - function clamp(v, min, max) { return v < min ? min : v > max ? max : v; } - - start = ECMAScript.ToInt32(start); - end = ECMAScript.ToInt32(end); - - if (arguments.length < 1) { start = 0; } - if (arguments.length < 2) { end = this.length; } - - if (start < 0) { start = this.length + start; } - if (end < 0) { end = this.length + end; } - - start = clamp(start, 0, this.length); - end = clamp(end, 0, this.length); - - var len = end - start; - if (len < 0) { - len = 0; - } - - return new this.constructor( - this.buffer, this.byteOffset + start * this.BYTES_PER_ELEMENT, len); - }; - - return ctor; - } - - var Int8Array = makeConstructor(1, packI8, unpackI8); - var Uint8Array = makeConstructor(1, packU8, unpackU8); - var Uint8ClampedArray = makeConstructor(1, packU8Clamped, unpackU8); - var Int16Array = makeConstructor(2, packI16, unpackI16); - var Uint16Array = makeConstructor(2, packU16, unpackU16); - var Int32Array = makeConstructor(4, packI32, unpackI32); - var Uint32Array = makeConstructor(4, packU32, unpackU32); - var Float32Array = makeConstructor(4, packF32, unpackF32); - var Float64Array = makeConstructor(8, packF64, unpackF64); - - exports.Int8Array = exports.Int8Array || Int8Array; - exports.Uint8Array = exports.Uint8Array || Uint8Array; - exports.Uint8ClampedArray = exports.Uint8ClampedArray || Uint8ClampedArray; - exports.Int16Array = exports.Int16Array || Int16Array; - exports.Uint16Array = exports.Uint16Array || Uint16Array; - exports.Int32Array = exports.Int32Array || Int32Array; - exports.Uint32Array = exports.Uint32Array || Uint32Array; - exports.Float32Array = exports.Float32Array || Float32Array; - exports.Float64Array = exports.Float64Array || Float64Array; -}()); - -// -// 6 The DataView View Type -// - -(function() { - function r(array, index) { - return ECMAScript.IsCallable(array.get) ? array.get(index) : array[index]; - } - - var IS_BIG_ENDIAN = (function() { - var u16array = new(exports.Uint16Array)([0x1234]), - u8array = new(exports.Uint8Array)(u16array.buffer); - return r(u8array, 0) === 0x12; - }()); - - // Constructor(ArrayBuffer buffer, - // optional unsigned long byteOffset, - // optional unsigned long byteLength) - /** @constructor */ - var DataView = function DataView(buffer, byteOffset, byteLength) { - if (arguments.length === 0) { - buffer = new exports.ArrayBuffer(0); - } else if (!(buffer instanceof exports.ArrayBuffer || ECMAScript.Class(buffer) === 'ArrayBuffer')) { - throw new TypeError("TypeError"); - } - - this.buffer = buffer || new exports.ArrayBuffer(0); - - this.byteOffset = ECMAScript.ToUint32(byteOffset); - if (this.byteOffset > this.buffer.byteLength) { - throw new RangeError("byteOffset out of range"); - } - - if (arguments.length < 3) { - this.byteLength = this.buffer.byteLength - this.byteOffset; - } else { - this.byteLength = ECMAScript.ToUint32(byteLength); - } - - if ((this.byteOffset + this.byteLength) > this.buffer.byteLength) { - throw new RangeError("byteOffset and length reference an area beyond the end of the buffer"); - } - - configureProperties(this); - }; - - function makeGetter(arrayType) { - return function(byteOffset, littleEndian) { - - byteOffset = ECMAScript.ToUint32(byteOffset); - - if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { - throw new RangeError("Array index out of range"); - } - byteOffset += this.byteOffset; - - var uint8Array = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT), - bytes = [], i; - for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { - bytes.push(r(uint8Array, i)); - } - - if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { - bytes.reverse(); - } - - return r(new arrayType(new exports.Uint8Array(bytes).buffer), 0); - }; - } - - DataView.prototype.getUint8 = makeGetter(exports.Uint8Array); - DataView.prototype.getInt8 = makeGetter(exports.Int8Array); - DataView.prototype.getUint16 = makeGetter(exports.Uint16Array); - DataView.prototype.getInt16 = makeGetter(exports.Int16Array); - DataView.prototype.getUint32 = makeGetter(exports.Uint32Array); - DataView.prototype.getInt32 = makeGetter(exports.Int32Array); - DataView.prototype.getFloat32 = makeGetter(exports.Float32Array); - DataView.prototype.getFloat64 = makeGetter(exports.Float64Array); - - function makeSetter(arrayType) { - return function(byteOffset, value, littleEndian) { - - byteOffset = ECMAScript.ToUint32(byteOffset); - if (byteOffset + arrayType.BYTES_PER_ELEMENT > this.byteLength) { - throw new RangeError("Array index out of range"); - } - - // Get bytes - var typeArray = new arrayType([value]), - byteArray = new exports.Uint8Array(typeArray.buffer), - bytes = [], i, byteView; - - for (i = 0; i < arrayType.BYTES_PER_ELEMENT; i += 1) { - bytes.push(r(byteArray, i)); - } - - // Flip if necessary - if (Boolean(littleEndian) === Boolean(IS_BIG_ENDIAN)) { - bytes.reverse(); - } - - // Write them - byteView = new exports.Uint8Array(this.buffer, byteOffset, arrayType.BYTES_PER_ELEMENT); - byteView.set(bytes); - }; - } - - DataView.prototype.setUint8 = makeSetter(exports.Uint8Array); - DataView.prototype.setInt8 = makeSetter(exports.Int8Array); - DataView.prototype.setUint16 = makeSetter(exports.Uint16Array); - DataView.prototype.setInt16 = makeSetter(exports.Int16Array); - DataView.prototype.setUint32 = makeSetter(exports.Uint32Array); - DataView.prototype.setInt32 = makeSetter(exports.Int32Array); - DataView.prototype.setFloat32 = makeSetter(exports.Float32Array); - DataView.prototype.setFloat64 = makeSetter(exports.Float64Array); - - exports.DataView = exports.DataView || DataView; - -}()); -}(typedarray)); - -var Writable = require$$1.Writable; -var inherits = inherits$2.exports; -var bufferFrom = bufferFrom_1; - -if (typeof Uint8Array === 'undefined') { - var U8 = typedarray.Uint8Array; -} else { - var U8 = Uint8Array; -} - -function ConcatStream(opts, cb) { - if (!(this instanceof ConcatStream)) return new ConcatStream(opts, cb) - - if (typeof opts === 'function') { - cb = opts; - opts = {}; - } - if (!opts) opts = {}; - - var encoding = opts.encoding; - var shouldInferEncoding = false; - - if (!encoding) { - shouldInferEncoding = true; - } else { - encoding = String(encoding).toLowerCase(); - if (encoding === 'u8' || encoding === 'uint8') { - encoding = 'uint8array'; - } - } - - Writable.call(this, { objectMode: true }); - - this.encoding = encoding; - this.shouldInferEncoding = shouldInferEncoding; - - if (cb) this.on('finish', function () { cb(this.getBody()); }); - this.body = []; -} - -var concatStream = ConcatStream; -inherits(ConcatStream, Writable); - -ConcatStream.prototype._write = function(chunk, enc, next) { - this.body.push(chunk); - next(); -}; - -ConcatStream.prototype.inferEncoding = function (buff) { - var firstBuffer = buff === undefined ? this.body[0] : buff; - if (Buffer.isBuffer(firstBuffer)) return 'buffer' - if (typeof Uint8Array !== 'undefined' && firstBuffer instanceof Uint8Array) return 'uint8array' - if (Array.isArray(firstBuffer)) return 'array' - if (typeof firstBuffer === 'string') return 'string' - if (Object.prototype.toString.call(firstBuffer) === "[object Object]") return 'object' - return 'buffer' -}; - -ConcatStream.prototype.getBody = function () { - if (!this.encoding && this.body.length === 0) return [] - if (this.shouldInferEncoding) this.encoding = this.inferEncoding(); - if (this.encoding === 'array') return arrayConcat(this.body) - if (this.encoding === 'string') return stringConcat(this.body) - if (this.encoding === 'buffer') return bufferConcat(this.body) - if (this.encoding === 'uint8array') return u8Concat(this.body) - return this.body -}; - -function isArrayish (arr) { - return /Array\]$/.test(Object.prototype.toString.call(arr)) -} - -function isBufferish (p) { - return typeof p === 'string' || isArrayish(p) || (p && typeof p.subarray === 'function') -} - -function stringConcat (parts) { - var strings = []; - for (var i = 0; i < parts.length; i++) { - var p = parts[i]; - if (typeof p === 'string') { - strings.push(p); - } else if (Buffer.isBuffer(p)) { - strings.push(p); - } else if (isBufferish(p)) { - strings.push(bufferFrom(p)); - } else { - strings.push(bufferFrom(String(p))); - } - } - if (Buffer.isBuffer(parts[0])) { - strings = Buffer.concat(strings); - strings = strings.toString('utf8'); - } else { - strings = strings.join(''); - } - return strings -} - -function bufferConcat (parts) { - var bufs = []; - for (var i = 0; i < parts.length; i++) { - var p = parts[i]; - if (Buffer.isBuffer(p)) { - bufs.push(p); - } else if (isBufferish(p)) { - bufs.push(bufferFrom(p)); - } else { - bufs.push(bufferFrom(String(p))); - } - } - return Buffer.concat(bufs) -} - -function arrayConcat (parts) { - var res = []; - for (var i = 0; i < parts.length; i++) { - res.push.apply(res, parts[i]); - } - return res -} - -function u8Concat (parts) { - var len = 0; - for (var i = 0; i < parts.length; i++) { - if (typeof parts[i] === 'string') { - parts[i] = bufferFrom(parts[i]); - } - len += parts[i].length; - } - var u8 = new U8(len); - for (var i = 0, offset = 0; i < parts.length; i++) { - var part = parts[i]; - for (var j = 0; j < part.length; j++) { - u8[offset++] = part[j]; - } - } - return u8 -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Settings} Settings - */ - -const debug$9 = createDebug('unified-engine:file-set-pipeline:stdin'); - -/** - * @param {Context} context - * @param {Settings} settings - * @param {Callback} next - */ -function stdin(context, settings, next) { - if (settings.files && settings.files.length > 0) { - debug$9('Ignoring `streamIn`'); - - /** @type {Error|undefined} */ - let error; - - if (settings.filePath) { - error = new Error( - 'Do not pass both `--file-path` and real files.\nDid you mean to pass stdin instead of files?' - ); - } - - next(error); - - return - } - - // @ts-expect-error: does exist on `stdin`. - if (settings.streamIn.isTTY) { - debug$9('Cannot read from `tty` stream'); - next(new Error('No input')); - - return - } - - debug$9('Reading from `streamIn`'); - - settings.streamIn.pipe( - concatStream({encoding: 'string'}, (value) => { - const file = toVFile(settings.filePath); - - debug$9('Read from `streamIn`'); - - file.cwd = settings.cwd; - file.value = value; - file.data.unifiedEngineGiven = true; - file.data.unifiedEngineStreamIn = true; - - context.files = [file]; - - // If `out` was not set, set `out`. - settings.out = - settings.out === null || settings.out === undefined - ? true - : settings.out; - - next(); - }) - ); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Pipeline} Pipeline - */ - -class FileSet extends EventEmitter$1 { - /** - * FileSet constructor. - * A FileSet is created to process multiple files through unified processors. - * This set, containing all files, is exposed to plugins as an argument to the - * attacher. - */ - constructor() { - super(); - - /** @type {Array.} */ - this.files = []; - /** @type {string[]} */ - this.origins = []; - /** @type {Completer[]} */ - this.plugins = []; - /** @type {number} */ - this.expected = 0; - /** @type {number} */ - this.actual = 0; - /** @type {Pipeline} */ - this.pipeline = trough(); - - // Called when a single file has completed it’s pipeline, triggering `done` - // when all files are complete. - this.on('one', () => { - this.actual++; - - if (this.actual >= this.expected) { - this.emit('done'); - } - }); - } - - /** - * Access the files in a set. - */ - valueOf() { - return this.files - } - - /** - * Attach middleware to the pipeline on `fileSet`. - * - * @param {Completer} plugin - */ - use(plugin) { - const pipeline = this.pipeline; - let duplicate = false; - - if (plugin && plugin.pluginId) { - duplicate = this.plugins.some((fn) => fn.pluginId === plugin.pluginId); - } - - if (!duplicate && this.plugins.includes(plugin)) { - duplicate = true; - } - - if (!duplicate) { - this.plugins.push(plugin); - pipeline.use(plugin); - } - - return this - } - - /** - * Add a file to be processed. - * The given file is processed like other files with a few differences: - * - * * Ignored when their file path is already added - * * Never written to the file system or streamOut - * * Not reported for - * - * @param {string|VFile} file - */ - add(file) { - if (typeof file === 'string') { - file = toVFile(file); - } - - // Prevent files from being added multiple times. - if (this.origins.includes(file.history[0])) { - return this - } - - this.origins.push(file.history[0]); - - // Add. - this.valueOf().push(file); - this.expected++; - - // Force an asynchronous operation. - // This ensures that files which fall through the file pipeline immediately - // (such as, when already fatally failed) still queue up correctly. - setImmediate(() => { - this.emit('add', file); - }); - - return this - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$8 = createDebug('unified-engine:file-pipeline:read'); - -/** - * Fill a file with its value when not already filled. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function read$1(context, file, next) { - let filePath = file.path; - - if (file.value || file.data.unifiedEngineStreamIn) { - debug$8('Not reading file `%s` with `value`', filePath); - next(); - } else if (statistics(file).fatal) { - debug$8('Not reading failed file `%s`', filePath); - next(); - } else { - filePath = path$c.resolve(context.settings.cwd, filePath); - - debug$8('Reading `%s` in `%s`', filePath, 'utf8'); - fs$a.readFile(filePath, 'utf8', (error, value) => { - debug$8('Read `%s` (error: %s)', filePath, error); - - file.value = value || ''; - - next(error); - }); - } -} - -/** - * Has own property. - * - * @type {Function} - */ - -var has = Object.prototype.hasOwnProperty; - -/** - * To string. - * - * @type {Function} - */ - -var toString$1 = Object.prototype.toString; - -/** - * Test whether a value is "empty". - * - * @param {Mixed} val - * @return {Boolean} - */ - -function isEmpty(val) { - // Null and Undefined... - if (val == null) return true - - // Booleans... - if ('boolean' == typeof val) return false - - // Numbers... - if ('number' == typeof val) return val === 0 - - // Strings... - if ('string' == typeof val) return val.length === 0 - - // Functions... - if ('function' == typeof val) return val.length === 0 - - // Arrays... - if (Array.isArray(val)) return val.length === 0 - - // Errors... - if (val instanceof Error) return val.message === '' - - // Objects... - if (val.toString == toString$1) { - switch (val.toString()) { - - // Maps, Sets, Files and Errors... - case '[object File]': - case '[object Map]': - case '[object Set]': { - return val.size === 0 - } - - // Plain objects... - case '[object Object]': { - for (var key in val) { - if (has.call(val, key)) return false - } - - return true - } - } - } - - // Anything else... - return false -} - -/** - * Export `isEmpty`. - * - * @type {Function} - */ - -var lib$1 = isEmpty; - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$7 = createDebug('unified-engine:file-pipeline:configure'); - -/** - * Collect configuration for a file based on the context. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function configure$2(context, file, next) { - if (statistics(file).fatal) { - return next() - } - - context.configuration.load(file.path, (error, configuration) => { - let index = -1; - - if (!configuration) { - return next(error) - } - - // Could be missing if a `configTransform` returns weird things. - /* c8 ignore next 1 */ - const plugins = configuration.plugins || []; - - // Store configuration on the context object. - debug$7('Using settings `%j`', configuration.settings); - context.processor.data('settings', configuration.settings); - - debug$7('Using `%d` plugins', plugins.length); - - while (++index < plugins.length) { - const plugin = plugins[index][0]; - let options = plugins[index][1]; - - if (options === false) { - continue - } - - // Allow for default arguments in es2020. - /* c8 ignore next 6 */ - if ( - options === null || - (typeof options === 'object' && lib$1(options)) - ) { - options = undefined; - } - - debug$7( - 'Using plugin `%s`, with options `%j`', - // @ts-expect-error: `displayName` sure can exist on functions. - plugin.displayName || plugin.name || 'function', - options - ); - - try { - context.processor.use(plugin, options, context.fileSet); - /* Should not happen anymore! */ - /* c8 ignore next 3 */ - } catch (error_) { - return next(error_) - } - } - - next(); - }); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('./index.js').Context} Context - */ - -const debug$6 = createDebug('unified-engine:file-pipeline:parse'); - -/** - * Fill a file with a tree. - * - * @param {Context} context - * @param {VFile} file - */ -function parse$2(context, file) { - if (statistics(file).fatal) { - return - } - - if (context.settings.treeIn) { - debug$6('Not parsing already parsed document'); - - try { - context.tree = parseJson_1(file.toString()); - } catch (error) { - const message = file.message( - new Error('Cannot read file as JSON\n' + error.message) - ); - message.fatal = true; - } - - // Add the preferred extension to ensure the file, when serialized, is - // correctly recognised. - // Only add it if there is a path — not if the file is for example stdin. - if (file.path) { - file.extname = context.settings.extensions[0]; - } - - file.value = ''; - - return - } - - debug$6('Parsing `%s`', file.path); - - context.tree = context.processor.parse(file); - - debug$6('Parsed document'); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$5 = createDebug('unified-engine:file-pipeline:transform'); - -/** - * Transform the tree associated with a file with configured plugins. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function transform$2(context, file, next) { - if (statistics(file).fatal) { - next(); - } else { - debug$5('Transforming document `%s`', file.path); - // @ts-expect-error: `tree` is defined at this point. - context.processor.run(context.tree, file, (error, node) => { - debug$5('Transformed document (error: %s)', error); - context.tree = node; - next(error); - }); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$4 = createDebug('unified-engine:file-pipeline:queue'); - -const own$a = {}.hasOwnProperty; - -/** - * Queue all files which came this far. - * When the last file gets here, run the file-set pipeline and flush the queue. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function queue(context, file, next) { - let origin = file.history[0]; - // @ts-expect-error: store a completion map on the `fileSet`. - let map = context.fileSet.complete; - let complete = true; - - if (!map) { - map = {}; - // @ts-expect-error: store a completion map on the `fileSet`. - context.fileSet.complete = map; - } - - debug$4('Queueing `%s`', origin); - - map[origin] = next; - - const files = context.fileSet.valueOf(); - let index = -1; - while (++index < files.length) { - each(files[index]); - } - - if (!complete) { - debug$4('Not flushing: some files cannot be flushed'); - return - } - - // @ts-expect-error: Reset map. - context.fileSet.complete = {}; - context.fileSet.pipeline.run(context.fileSet, done); - - /** - * @param {VFile} file - */ - function each(file) { - const key = file.history[0]; - - if (statistics(file).fatal) { - return - } - - if (typeof map[key] === 'function') { - debug$4('`%s` can be flushed', key); - } else { - debug$4('Interupting flush: `%s` is not finished', key); - complete = false; - } - } - - /** - * @param {Error|Null} error - */ - function done(error) { - debug$4('Flushing: all files can be flushed'); - - // Flush. - for (origin in map) { - if (own$a.call(map, origin)) { - map[origin](error); - } - } - } -} - -var own$9 = {}.hasOwnProperty; - -var bold = ansiColor(1, 22); -var dim = ansiColor(2, 22); -var yellow = ansiColor(33, 39); -var green = ansiColor(32, 39); - -// ANSI color regex. -/* eslint-disable-next-line no-control-regex */ -var colorExpression = /(?:(?:\u001B\[)|\u009B)(?:\d{1,3})?(?:(?:;\d{0,3})*)?[A-M|f-m]|\u001B[A-M]/g; - -/** - * Inspects a node, without using color. - * - * @param {unknown} node - * @param {InspectOptions} [options] - * @returns {string} - */ -function inspectNoColor(node, options) { - return inspectColor(node, options).replace(colorExpression, '') -} - -/** - * Inspects a node, using color. - * - * @param {unknown} tree - * @param {InspectOptions} [options] - * @returns {string} - */ -function inspectColor(tree, options) { - var positions = - !options || - options.showPositions === null || - options.showPositions === undefined - ? true - : options.showPositions; - - return inspectValue(tree) - - /** - * @param {unknown} node - * @returns {string} - */ - function inspectValue(node) { - if (node && typeof node === 'object' && 'length' in node) { - // @ts-ignore looks like a list of nodes. - return inspectNodes(node) - } - - // @ts-ignore looks like a single node. - if (node && node.type) { - // @ts-ignore looks like a single node. - return inspectTree(node) - } - - return inspectNonTree(node) - } - - /** - * @param {unknown} value - * @returns {string} - */ - function inspectNonTree(value) { - return JSON.stringify(value) - } - - /** - * @param {Node[]} nodes - * @returns {string} - */ - function inspectNodes(nodes) { - /** @type {Array.} */ - var result = []; - var index = -1; - - while (++index < nodes.length) { - result.push( - dim((index < nodes.length - 1 ? '├' : '└') + '─' + index) + - ' ' + - indent( - inspectValue(nodes[index]), - (index < nodes.length - 1 ? dim('│') : ' ') + ' ', - true - ) - ); - } - - return result.join('\n') - } - - /** - * @param {Object.} object - * @returns {string} - */ - function inspectFields(object) { - /** @type {Array.} */ - var result = []; - /** @type {string} */ - var key; - /** @type {unknown} */ - var value; - /** @type {string} */ - var formatted; - - for (key in object) { - /* c8 ignore next 1 */ - if (!own$9.call(object, key)) continue - - value = object[key]; - - if ( - value === undefined || - // Standard keys defined by unist that we format differently. - // - key === 'type' || - key === 'value' || - key === 'children' || - key === 'position' || - // Ignore `name` (from xast) and `tagName` (from `hast`) when string. - (typeof value === 'string' && (key === 'name' || key === 'tagName')) - ) { - continue - } - - // A single node. - if ( - value && - typeof value === 'object' && - // @ts-ignore looks like a node. - value.type && - key !== 'data' && - key !== 'attributes' && - key !== 'properties' - ) { - // @ts-ignore looks like a node. - formatted = inspectTree(value); - } - // A list of nodes. - else if ( - value && - typeof value === 'object' && - 'length' in value && - value[0] && - value[0].type - ) { - // @ts-ignore looks like a list of nodes. - formatted = '\n' + inspectNodes(value); - } else { - formatted = inspectNonTree(value); - } - - result.push( - key + dim(':') + (/\s/.test(formatted.charAt(0)) ? '' : ' ') + formatted - ); - } - - return indent( - result.join('\n'), - // @ts-ignore looks like a parent node. - (object.children && object.children.length > 0 ? dim('│') : ' ') + ' ' - ) - } - - /** - * @param {Node} node - * @returns {string} - */ - function inspectTree(node) { - var result = [formatNode(node)]; - var fields = inspectFields(node); - // @ts-ignore looks like a parent. - var content = inspectNodes(node.children || []); - if (fields) result.push(fields); - if (content) result.push(content); - return result.join('\n') - } - - /** - * Colored node formatter. - * - * @param {Node} node - * @returns {string} - */ - function formatNode(node) { - var result = [bold(node.type)]; - var kind = node.tagName || node.name; - var position = positions ? stringifyPosition(node.position) : ''; - - if (typeof kind === 'string') { - result.push('<', kind, '>'); - } - - if (node.children) { - // @ts-ignore looks like a parent. - result.push(dim('['), yellow(node.children.length), dim(']')); - } else if (typeof node.value === 'string') { - result.push(' ', green(inspectNonTree(node.value))); - } - - if (position) { - result.push(' ', dim('('), position, dim(')')); - } - - return result.join('') - } -} - -/** - * @param {string} value - * @param {string} indentation - * @param {boolean} [ignoreFirst=false] - * @returns {string} - */ -function indent(value, indentation, ignoreFirst) { - var lines = value.split('\n'); - var index = ignoreFirst ? 0 : -1; - - if (!value) return value - - while (++index < lines.length) { - lines[index] = indentation + lines[index]; - } - - return lines.join('\n') -} - -/** - * @param {Position} value - * @returns {string} - */ -function stringifyPosition(value) { - /** @type {Position} */ - // @ts-ignore - var position = value || {}; - /** @type {Array.} */ - var result = []; - /** @type {Array.} */ - var positions = []; - /** @type {Array.} */ - var offsets = []; - - point(position.start); - point(position.end); - - if (positions.length > 0) result.push(positions.join('-')); - if (offsets.length > 0) result.push(offsets.join('-')); - - return result.join(', ') - - /** - * @param {Point} value - */ - function point(value) { - if (value) { - positions.push((value.line || 1) + ':' + (value.column || 1)); - - if ('offset' in value) { - offsets.push(String(value.offset || 0)); - } - } - } -} - -/** - * Factory to wrap values in ANSI colours. - * - * @param {number} open - * @param {number} close - * @returns {function(string): string} - */ -function ansiColor(open, close) { - return color - - /** - * @param {string} value - * @returns {string} - */ - function color(value) { - return '\u001B[' + open + 'm' + value + '\u001B[' + close + 'm' - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('./index.js').Context} Context - */ - -const debug$3 = createDebug('unified-engine:file-pipeline:stringify'); - -/** - * Stringify a tree. - * - * @param {Context} context - * @param {VFile} file - */ -function stringify$1(context, file) { - /** @type {unknown} */ - let value; - - if (statistics(file).fatal) { - debug$3('Not compiling failed document'); - return - } - - if ( - !context.settings.output && - !context.settings.out && - !context.settings.alwaysStringify - ) { - debug$3('Not compiling document without output settings'); - return - } - - debug$3('Compiling `%s`', file.path); - - if (context.settings.inspect) { - // Add a `txt` extension if there is a path. - if (file.path) { - file.extname = '.txt'; - } - - value = - (context.settings.color ? inspectColor : inspectNoColor)(context.tree) + - '\n'; - } else if (context.settings.treeOut) { - // Add a `json` extension to ensure the file is correctly seen as JSON. - // Only add it if there is a path — not if the file is for example stdin. - if (file.path) { - file.extname = '.json'; - } - - // Add the line feed to create a valid UNIX file. - value = JSON.stringify(context.tree, null, 2) + '\n'; - } else { - // @ts-expect-error: `tree` is defined if we came this far. - value = context.processor.stringify(context.tree, file); - } - - if (value === undefined || value === null) ; else if (typeof value === 'string' || isBuffer(value)) { - // @ts-expect-error: `isBuffer` checks buffer. - file.value = value; - } else { - file.result = value; - } - - debug$3('Serialized document'); -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$2 = createDebug('unified-engine:file-pipeline:copy'); - -/** - * Move a file. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function copy(context, file, next) { - const output = context.settings.output; - const currentPath = file.path; - - if (typeof output !== 'string') { - debug$2('Not copying'); - next(); - return - } - - const outpath = path$c.resolve(context.settings.cwd, output); - - debug$2('Copying `%s`', currentPath); - - fs$a.stat(outpath, (error, stats) => { - if (error) { - if ( - error.code !== 'ENOENT' || - output.charAt(output.length - 1) === path$c.sep - ) { - return next( - new Error('Cannot read output directory. Error:\n' + error.message) - ) - } - - // This is either given an error, or the parent exists which is a directory, - // but we should keep the basename of the given file. - fs$a.stat(path$c.dirname(outpath), (error) => { - if (error) { - next( - new Error('Cannot read parent directory. Error:\n' + error.message) - ); - } else { - done(false); - } - }); - } else { - done(stats.isDirectory()); - } - }); - - /** - * @param {boolean} directory - */ - function done(directory) { - if (!directory && context.fileSet.expected > 1) { - return next( - new Error('Cannot write multiple files to single output: ' + outpath) - ) - } - - file[directory ? 'dirname' : 'path'] = path$c.relative(file.cwd, outpath); - - debug$2('Copying document from %s to %s', currentPath, file.path); - - next(); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug$1 = createDebug('unified-engine:file-pipeline:stdout'); - -/** - * Write a virtual file to `streamOut`. - * Ignored when `output` is given, more than one file was processed, or `out` - * is false. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function stdout(context, file, next) { - if (!file.data.unifiedEngineGiven) { - debug$1('Ignoring programmatically added file'); - next(); - } else if ( - statistics(file).fatal || - context.settings.output || - !context.settings.out - ) { - debug$1('Ignoring writing to `streamOut`'); - next(); - } else { - debug$1('Writing document to `streamOut`'); - context.settings.streamOut.write(file.toString(), next); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Context} Context - */ - -const debug = createDebug('unified-engine:file-pipeline:file-system'); - -/** - * Write a virtual file to the file-system. - * Ignored when `output` is not given. - * - * @param {Context} context - * @param {VFile} file - * @param {Callback} next - */ -function fileSystem(context, file, next) { - if (!context.settings.output) { - debug('Ignoring writing to file-system'); - return next() - } - - if (!file.data.unifiedEngineGiven) { - debug('Ignoring programmatically added file'); - return next() - } - - let destinationPath = file.path; - - if (!destinationPath) { - debug('Cannot write file without a `destinationPath`'); - return next(new Error('Cannot write file without an output path')) - } - - if (statistics(file).fatal) { - debug('Cannot write file with a fatal error'); - return next() - } - - destinationPath = path$c.resolve(context.settings.cwd, destinationPath); - debug('Writing document to `%s`', destinationPath); - - file.stored = true; - fs$a.writeFile(destinationPath, file.toString(), next); -} - -/** - * @typedef {import('trough').Pipeline} Pipeline - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * @typedef {import('unist').Node} Node - * @typedef {import('unified').Processor} Processor - * @typedef {import('../file-set.js').FileSet} FileSet - * @typedef {import('../configuration.js').Configuration} Configuration - * @typedef {import('../index.js').Settings} Settings - */ - -// This pipeline ensures each of the pipes always runs: even if the read pipe -// fails, queue and write run. -const filePipeline = trough() - .use(chunk(trough().use(read$1).use(configure$2).use(parse$2).use(transform$2))) - .use(chunk(trough().use(queue))) - .use(chunk(trough().use(stringify$1).use(copy).use(stdout).use(fileSystem))); - -/** - * Factory to run a pipe. - * Wraps a pipe to trigger an error on the `file` in `context`, but still call - * `next`. - * - * @param {Pipeline} pipe - */ -function chunk(pipe) { - return run - - /** - * Run the bound pipe and handle any errors. - * - * @param {Context} context - * @param {VFile} file - * @param {() => void} next - */ - function run(context, file, next) { - pipe.run(context, file, (/** @type {VFileMessage|null} */ error) => { - const messages = file.messages; - - if (error) { - const index = messages.indexOf(error); - - if (index === -1) { - Object.assign(file.message(error), {fatal: true}); - } else { - messages[index].fatal = true; - } - } - - next(); - }); - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('trough').Callback} Callback - * @typedef {import('./index.js').Settings} Settings - * @typedef {import('./index.js').Configuration} Configuration - */ - -/** - * Transform all files. - * - * @param {Context} context - * @param {Settings} settings - * @param {Callback} next - */ -function transform$1(context, settings, next) { - const fileSet = new FileSet(); - - context.fileSet = fileSet; - - fileSet.on('add', (/** @type {VFile} */ file) => { - filePipeline.run( - { - configuration: context.configuration, - // Needed `any`s - // type-coverage:ignore-next-line - processor: settings.processor(), - fileSet, - settings - }, - file, - (/** @type {Error|null} */ error) => { - // Does not occur as all failures in `filePipeLine` are failed on each - // file. - // Still, just to ensure things work in the future, we add an extra check. - /* c8 ignore next 4 */ - if (error) { - Object.assign(file.message(error), {fatal: true}); - } - - fileSet.emit('one', file); - } - ); - }); - - fileSet.on('done', next); - - if (context.files.length === 0) { - next(); - } else { - let index = -1; - while (++index < context.files.length) { - fileSet.add(context.files[index]); - } - } -} - -function hasFlag(flag, argv = process$1.argv) { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); -} - -const {env} = process$1; - -let flagForceColor; -if (hasFlag('no-color') || - hasFlag('no-colors') || - hasFlag('color=false') || - hasFlag('color=never')) { - flagForceColor = 0; -} else if (hasFlag('color') || - hasFlag('colors') || - hasFlag('color=true') || - hasFlag('color=always')) { - flagForceColor = 1; -} - -function envForceColor() { - if ('FORCE_COLOR' in env) { - if (env.FORCE_COLOR === 'true') { - return 1; - } - - if (env.FORCE_COLOR === 'false') { - return 0; - } - - return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); - } -} - -function translateLevel(level) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3 - }; -} - -function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) { - const noFlagForceColor = envForceColor(); - if (noFlagForceColor !== undefined) { - flagForceColor = noFlagForceColor; - } - - const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; - - if (forceColor === 0) { - return 0; - } - - if (sniffFlags) { - if (hasFlag('color=16m') || - hasFlag('color=full') || - hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - } - - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } - - const min = forceColor || 0; - - if (env.TERM === 'dumb') { - return min; - } - - if (process$1.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = require$$0$2.release().split('.'); - if ( - Number(osRelease[0]) >= 10 && - Number(osRelease[2]) >= 10586 - ) { - return Number(osRelease[2]) >= 14931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'GITHUB_ACTIONS', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': - return version >= 3 ? 3 : 2; - case 'Apple_Terminal': - return 2; - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - return min; -} - -function createSupportsColor(stream, options = {}) { - const level = _supportsColor(stream, { - streamIsTTY: stream && stream.isTTY, - ...options - }); - - return translateLevel(level); -} - -const supportsColor = { - stdout: createSupportsColor({isTTY: tty$1.isatty(1)}), - stderr: createSupportsColor({isTTY: tty$1.isatty(2)}) -}; - -function ansiRegex({onlyFirst = false} = {}) { - const pattern = [ - '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)', - '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))' - ].join('|'); - - return new RegExp(pattern, onlyFirst ? undefined : 'g'); -} - -function stripAnsi(string) { - if (typeof string !== 'string') { - throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``); - } - - return string.replace(ansiRegex(), ''); -} - -/* eslint-disable yoda */ - -function isFullwidthCodePoint(codePoint) { - if (!Number.isInteger(codePoint)) { - return false; - } - - // Code points are derived from: - // https://unicode.org/Public/UNIDATA/EastAsianWidth.txt - return codePoint >= 0x1100 && ( - codePoint <= 0x115F || // Hangul Jamo - codePoint === 0x2329 || // LEFT-POINTING ANGLE BRACKET - codePoint === 0x232A || // RIGHT-POINTING ANGLE BRACKET - // CJK Radicals Supplement .. Enclosed CJK Letters and Months - (0x2E80 <= codePoint && codePoint <= 0x3247 && codePoint !== 0x303F) || - // Enclosed CJK Letters and Months .. CJK Unified Ideographs Extension A - (0x3250 <= codePoint && codePoint <= 0x4DBF) || - // CJK Unified Ideographs .. Yi Radicals - (0x4E00 <= codePoint && codePoint <= 0xA4C6) || - // Hangul Jamo Extended-A - (0xA960 <= codePoint && codePoint <= 0xA97C) || - // Hangul Syllables - (0xAC00 <= codePoint && codePoint <= 0xD7A3) || - // CJK Compatibility Ideographs - (0xF900 <= codePoint && codePoint <= 0xFAFF) || - // Vertical Forms - (0xFE10 <= codePoint && codePoint <= 0xFE19) || - // CJK Compatibility Forms .. Small Form Variants - (0xFE30 <= codePoint && codePoint <= 0xFE6B) || - // Halfwidth and Fullwidth Forms - (0xFF01 <= codePoint && codePoint <= 0xFF60) || - (0xFFE0 <= codePoint && codePoint <= 0xFFE6) || - // Kana Supplement - (0x1B000 <= codePoint && codePoint <= 0x1B001) || - // Enclosed Ideographic Supplement - (0x1F200 <= codePoint && codePoint <= 0x1F251) || - // CJK Unified Ideographs Extension B .. Tertiary Ideographic Plane - (0x20000 <= codePoint && codePoint <= 0x3FFFD) - ); -} - -var emojiRegex = function () { - // https://mths.be/emoji - return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g; -}; - -function stringWidth(string) { - if (typeof string !== 'string' || string.length === 0) { - return 0; - } - - string = stripAnsi(string); - - if (string.length === 0) { - return 0; - } - - string = string.replace(emojiRegex(), ' '); - - let width = 0; - - for (let index = 0; index < string.length; index++) { - const codePoint = string.codePointAt(index); - - // Ignore control characters - if (codePoint <= 0x1F || (codePoint >= 0x7F && codePoint <= 0x9F)) { - continue; - } - - // Ignore combining characters - if (codePoint >= 0x300 && codePoint <= 0x36F) { - continue; - } - - // Surrogates - if (codePoint > 0xFFFF) { - index++; - } - - width += isFullwidthCodePoint(codePoint) ? 2 : 1; - } - - return width; -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - */ - -var severities = {true: 2, false: 1, null: 0, undefined: 0}; - -/** - * @template {VFile} F - * @param {F} file - * @returns {F} - */ -function sort(file) { - file.messages.sort(comparator); - return file -} - -/** - * @param {VFileMessage} a - * @param {VFileMessage} b - * @returns {number} - */ -function comparator(a, b) { - return ( - check$1(a, b, 'line') || - check$1(a, b, 'column') || - severities[b.fatal] - severities[a.fatal] || - compare(a, b, 'source') || - compare(a, b, 'ruleId') || - compare(a, b, 'reason') || - 0 - ) -} - -/** - * @param {VFileMessage} a - * @param {VFileMessage} b - * @param {string} property - * @returns {number} - */ -function check$1(a, b, property) { - return (a[property] || 0) - (b[property] || 0) -} - -/** - * @param {VFileMessage} a - * @param {VFileMessage} b - * @param {string} property - * @returns {number} - */ -function compare(a, b, property) { - return String(a[property] || '').localeCompare(b[property] || '') -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * @typedef {import('vfile-statistics').Statistics} Statistics - * - * @typedef Options - * @property {boolean} [color] - * @property {boolean} [silent=false] - * @property {boolean} [quiet=false] - * @property {boolean} [verbose=false] - * @property {string} [defaultName=''] - * - * @typedef _Row - * @property {string} place - * @property {string} label - * @property {string} reason - * @property {string} ruleId - * @property {string} source - * - * @typedef _FileRow - * @property {'file'} type - * @property {VFile} file - * @property {Statistics} stats - * - * @typedef {{[x: string]: number}} _Sizes - * - * @typedef _Info - * @property {Array.<_FileRow|_Row>} rows - * @property {Statistics} stats - * @property {_Sizes} sizes - */ - -const own$8 = {}.hasOwnProperty; - -// @ts-expect-error Types are incorrect. -const supported = supportsColor.stderr.hasBasic; - -// `log-symbols` without chalk, ignored for Windows: -/* c8 ignore next 4 */ -const chars = - process.platform === 'win32' - ? {error: '×', warning: '‼'} - : {error: '✖', warning: '⚠'}; - -const labels = { - true: 'error', - false: 'warning', - null: 'info', - undefined: 'info' -}; - -/** - * Report a file’s messages. - * - * @param {Error|VFile|Array.} [files] - * @param {Options} [options] - * @returns {string} - */ -function reporter$1(files, options = {}) { - /** @type {boolean|undefined} */ - let one; - - if (!files) { - return '' - } - - // Error. - if ('name' in files && 'message' in files) { - return String(files.stack || files) - } - - // One file. - if (!Array.isArray(files)) { - one = true; - files = [files]; - } - - return format(transform(files, options), one, options) -} - -/** - * @param {Array.} files - * @param {Options} options - * @returns {_Info} - */ -function transform(files, options) { - /** @type {Array.<_FileRow|_Row>} */ - const rows = []; - /** @type {Array.} */ - const all = []; - /** @type {_Sizes} */ - const sizes = {}; - let index = -1; - - while (++index < files.length) { - // @ts-expect-error it works fine. - const messages = sort({messages: [...files[index].messages]}).messages; - /** @type {Array.<_Row>} */ - const messageRows = []; - let offset = -1; - - while (++offset < messages.length) { - const message = messages[offset]; - - if (!options.silent || message.fatal) { - all.push(message); - - const row = { - place: stringifyPosition$1( - message.position - ? message.position.end.line && message.position.end.column - ? message.position - : message.position.start - : undefined - ), - label: labels[/** @type {keyof labels} */ (String(message.fatal))], - reason: - (message.stack || message.message) + - (options.verbose && message.note ? '\n' + message.note : ''), - ruleId: message.ruleId || '', - source: message.source || '' - }; - - /** @type {keyof row} */ - let key; - - for (key in row) { - // eslint-disable-next-line max-depth - if (own$8.call(row, key)) { - sizes[key] = Math.max(size$1(row[key]), sizes[key] || 0); - } - } - - messageRows.push(row); - } - } - - if ((!options.quiet && !options.silent) || messageRows.length > 0) { - rows.push( - {type: 'file', file: files[index], stats: statistics(messages)}, - ...messageRows - ); - } - } - - return {rows, stats: statistics(all), sizes} -} - -/** - * @param {_Info} map - * @param {boolean|undefined} one - * @param {Options} options - */ -// eslint-disable-next-line complexity -function format(map, one, options) { - /** @type {boolean} */ - const enabled = - options.color === undefined || options.color === null - ? supported - : options.color; - /** @type {Array.} */ - const lines = []; - let index = -1; - - while (++index < map.rows.length) { - const row = map.rows[index]; - - if ('type' in row) { - const stats = row.stats; - let line = row.file.history[0] || options.defaultName || ''; - - line = - one && !options.defaultName && !row.file.history[0] - ? '' - : (enabled - ? '\u001B[4m' /* Underline. */ + - (stats.fatal - ? '\u001B[31m' /* Red. */ - : stats.total - ? '\u001B[33m' /* Yellow. */ - : '\u001B[32m') /* Green. */ + - line + - '\u001B[39m\u001B[24m' - : line) + - (row.file.stored && row.file.path !== row.file.history[0] - ? ' > ' + row.file.path - : ''); - - if (!stats.total) { - line = - (line ? line + ': ' : '') + - (row.file.stored - ? enabled - ? '\u001B[33mwritten\u001B[39m' /* Yellow. */ - : 'written' - : 'no issues found'); - } - - if (line) { - if (index && !('type' in map.rows[index - 1])) { - lines.push(''); - } - - lines.push(line); - } - } else { - let reason = row.reason; - const match = /\r?\n|\r/.exec(reason); - /** @type {string} */ - let rest; - - if (match) { - rest = reason.slice(match.index); - reason = reason.slice(0, match.index); - } else { - rest = ''; - } - - lines.push( - ( - ' ' + - ' '.repeat(map.sizes.place - size$1(row.place)) + - row.place + - ' ' + - (enabled - ? (row.label === 'error' - ? '\u001B[31m' /* Red. */ - : '\u001B[33m') /* Yellow. */ + - row.label + - '\u001B[39m' - : row.label) + - ' '.repeat(map.sizes.label - size$1(row.label)) + - ' ' + - reason + - ' '.repeat(map.sizes.reason - size$1(reason)) + - ' ' + - row.ruleId + - ' '.repeat(map.sizes.ruleId - size$1(row.ruleId)) + - ' ' + - (row.source || '') - ).replace(/ +$/, '') + rest - ); - } - } - - const stats = map.stats; - - if (stats.fatal || stats.warn) { - let line = ''; - - if (stats.fatal) { - line = - (enabled - ? '\u001B[31m' /* Red. */ + chars.error + '\u001B[39m' - : chars.error) + - ' ' + - stats.fatal + - ' ' + - (labels.true + (stats.fatal === 1 ? '' : 's')); - } - - if (stats.warn) { - line = - (line ? line + ', ' : '') + - (enabled - ? '\u001B[33m' /* Yellow. */ + chars.warning + '\u001B[39m' - : chars.warning) + - ' ' + - stats.warn + - ' ' + - (labels.false + (stats.warn === 1 ? '' : 's')); - } - - if (stats.total !== stats.fatal && stats.total !== stats.warn) { - line = stats.total + ' messages (' + line + ')'; - } - - lines.push('', line); - } - - return lines.join('\n') -} - -/** - * Get the length of `value`, ignoring ANSI sequences. - * - * @param {string} value - * @returns {number} - */ -function size$1(value) { - const match = /\r?\n|\r/.exec(value); - return stringWidth(match ? value.slice(0, match.index) : value) -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('../index.js').VFileReporter} VFileReporter - * @typedef {import('./index.js').Settings} Settings - * @typedef {import('./index.js').Configuration} Configuration - */ - -/** - * @typedef Context - * @property {Array.} files - * @property {Configuration} [configuration] - */ - -/** - * @param {Context} context - * @param {Settings} settings - */ -async function log(context, settings) { - /** @type {VFileReporter} */ - let func = reporter$1; - - if (typeof settings.reporter === 'string') { - try { - // @ts-expect-error: Assume loaded value is a vfile reporter. - func = await loadPlugin(settings.reporter, { - cwd: settings.cwd, - prefix: 'vfile-reporter' - }); - } catch { - throw new Error('Could not find reporter `' + settings.reporter + '`') - } - } else if (settings.reporter) { - func = settings.reporter; - } - - let diagnostics = func( - context.files.filter((file) => file.data.unifiedEngineGiven), - Object.assign({}, settings.reporterOptions, { - quiet: settings.quiet, - silent: settings.silent, - color: settings.color - }) - ); - - if (diagnostics) { - if (diagnostics.charAt(diagnostics.length - 1) !== '\n') { - diagnostics += '\n'; - } - - return new Promise((resolve) => { - settings.streamError.write(diagnostics, resolve); - }) - } -} - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('../configuration.js').Configuration} Configuration - * @typedef {import('../index.js').Settings} Settings - */ - -const fileSetPipeline = trough() - .use(configure$3) - .use(fileSystem$1) - .use(stdin) - .use(transform$1) - .use(log); - -/** - * @typedef {import('vfile').VFile} VFile - * @typedef {import('unified').Processor} Processor - * @typedef {import('./file-set.js').FileSet} FileSet - * @typedef {import('./file-set.js').Completer} Completer - * @typedef {import('./ignore.js').ResolveFrom} ResolveFrom - * @typedef {import('./configuration.js').ConfigTransform} ConfigTransform - * @typedef {import('./configuration.js').Preset} Preset - * - * @typedef VFileReporterFields - * @property {boolean} [color] - * @property {boolean} [quiet] - * @property {boolean} [silent] - * - * @typedef {{[key: string]: unknown} & VFileReporterFields} VFileReporterOptions - * - * @callback VFileReporter - * @param {VFile[]} files - * @param {VFileReporterOptions} options - * @returns {string} - * - * @typedef Settings - * @property {Options['processor']} processor - * @property {Exclude} cwd - * @property {Exclude} files - * @property {Exclude} extensions - * @property {Exclude} streamIn - * @property {Options['filePath']} filePath - * @property {Exclude} streamOut - * @property {Exclude} streamError - * @property {Options['out']} out - * @property {Options['output']} output - * @property {Options['alwaysStringify']} alwaysStringify - * @property {Options['tree']} tree - * @property {Options['treeIn']} treeIn - * @property {Options['treeOut']} treeOut - * @property {Options['inspect']} inspect - * @property {Options['rcName']} rcName - * @property {Options['packageField']} packageField - * @property {Options['detectConfig']} detectConfig - * @property {Options['rcPath']} rcPath - * @property {Exclude} settings - * @property {Options['ignoreName']} ignoreName - * @property {Options['detectIgnore']} detectIgnore - * @property {Options['ignorePath']} ignorePath - * @property {Options['ignorePathResolveFrom']} ignorePathResolveFrom - * @property {Exclude} ignorePatterns - * @property {Options['silentlyIgnore']} silentlyIgnore - * @property {Options['plugins']} plugins - * @property {Options['pluginPrefix']} pluginPrefix - * @property {Options['configTransform']} configTransform - * @property {Options['defaultConfig']} defaultConfig - * @property {Options['reporter']} reporter - * @property {Options['reporterOptions']} reporterOptions - * @property {Options['color']} color - * @property {Options['silent']} silent - * @property {Options['quiet']} quiet - * @property {Options['frail']} frail - * - * @typedef Options - * Options for unified engine - * @property {() => Processor} processor - * Unified processor to transform files - * @property {string} [cwd] - * Directory to search files in, load plugins from, and more. - * Defaults to `process.cwd()`. - * @property {Array} [files] - * Paths or globs to files and directories, or virtual files, to process. - * @property {string[]} [extensions] - * If `files` matches directories, include `files` with `extensions` - * @property {NodeJS.ReadableStream} [streamIn] - * Stream to read from if no files are found or given. - * Defaults to `process.stdin`. - * @property {string} [filePath] - * File path to process the given file on `streamIn` as. - * @property {NodeJS.WritableStream} [streamOut] - * Stream to write processed files to. - * Defaults to `process.stdout`. - * @property {NodeJS.WritableStream} [streamError] - * Stream to write the report (if any) to. - * Defaults to `process.stderr`. - * @property {boolean} [out=false] - * Whether to write the processed file to `streamOut` - * @property {boolean|string} [output=false] - * Whether to write successfully processed files, and where to. - * - * * When `true`, overwrites the given files - * * When `false`, does not write to the file system - * * When pointing to an existing directory, files are written to that - * directory and keep their original basenames - * * When the parent directory of the given path exists and one file is - * processed, the file is written to the given path - * @property {boolean} [alwaysStringify=false] - * Whether to always serialize successfully processed files. - * @property {boolean} [tree=false] - * Whether to treat both input and output as a syntax tree. - * @property {boolean} [treeIn] - * Whether to treat input as a syntax tree. - * Defaults to `options.tree`. - * @property {boolean} [treeOut] - * Whether to treat output as a syntax tree. - * Defaults to `options.tree`. - * @property {boolean} [inspect=false] - * Whether to output a formatted syntax tree. - * @property {string} [rcName] - * Name of configuration files to load. - * @property {string} [packageField] - * Property at which configuration can be found in `package.json` files - * @property {boolean} [detectConfig] - * Whether to search for configuration files. - * Defaults to `true` if `rcName` or `packageField` are given - * @property {string} [rcPath] - * Filepath to a configuration file to load. - * @property {Preset['settings']} [settings] - * Configuration for the parser and compiler of the processor. - * @property {string} [ignoreName] - * Name of ignore files to load. - * @property {boolean} [detectIgnore] - * Whether to search for ignore files. - * Defaults to `true` if `ignoreName` is given. - * @property {string} [ignorePath] - * Filepath to an ignore file to load. - * @property {ResolveFrom} [ignorePathResolveFrom] - * Resolve patterns in `ignorePath` from the current working - * directory (`'cwd'`) or the ignore file’s directory (`'dir'`, default). - * @property {string[]} [ignorePatterns] - * Patterns to ignore in addition to ignore files - * @property {boolean} [silentlyIgnore=false] - * Skip given files if they are ignored. - * @property {Preset['plugins']} [plugins] - * Plugins to use. - * @property {string} [pluginPrefix] - * Prefix to use when searching for plugins - * @property {ConfigTransform} [configTransform] - * Transform config files from a different schema. - * @property {Preset} [defaultConfig] - * Default configuration to use if no config file is given or found. - * @property {VFileReporter|string} [reporter] - * Reporter to use - * Defaults to `vfile-reporter` - * @property {VFileReporterOptions} [reporterOptions] - * Config to pass to the used reporter. - * @property {VFileReporterOptions['color']} [color=false] - * Whether to report with ANSI color sequences. - * @property {VFileReporterOptions['silent']} [silent=false] - * Report only fatal errors - * @property {VFileReporterOptions['quiet']} [quiet=false] - * Do not report successful files - * @property {boolean} [frail=false] - * Call back with an unsuccessful (`1`) code on warnings as well as errors - * - * @typedef Context - * Processing context. - * @property {VFile[]} [files] - * Processed files. - * @property {FileSet} [fileSet] - * Internally used information - * - * @callback Callback - * Callback called when processing according to options is complete. - * Invoked with either a fatal error if processing went horribly wrong - * (probably due to incorrect configuration), or a status code and the - * processing context. - * @param {Error|null} error - * @param {0|1} [status] - * @param {Context} [context] - * @returns {void} - */ - -/** - * Run the file set pipeline once. - * `callback` is called with a fatal error, or with a status code (`0` on - * success, `1` on failure). - * - * @param {Options} options - * @param {Callback} callback - */ -function engine(options, callback) { - /** @type {Settings} */ - const settings = {}; - /** @type {NodeJS.ReadStream} */ - // @ts-expect-error: `PassThrough` sure is readable. - let stdin = new PassThrough(); - - try { - stdin = process$2.stdin; - // Obscure bug in Node (seen on Windows). - // See: , - // . - /* c8 ignore next 1 */ - } catch {} - - if (!callback) { - throw new Error('Missing `callback`') - } - - // Needed `any`s - // type-coverage:ignore-next-line - if (!options || !options.processor) { - return next(new Error('Missing `processor`')) - } - - // Processor. - // Needed `any`s - // type-coverage:ignore-next-line - settings.processor = options.processor; - - // Path to run as. - settings.cwd = options.cwd || process$2.cwd(); - - // Input. - settings.files = options.files || []; - settings.extensions = (options.extensions || []).map((ext) => - ext.charAt(0) === '.' ? ext : '.' + ext - ); - - settings.filePath = options.filePath; - settings.streamIn = options.streamIn || stdin; - - // Output. - settings.streamOut = options.streamOut || process$2.stdout; - settings.streamError = options.streamError || process$2.stderr; - settings.alwaysStringify = options.alwaysStringify; - settings.output = options.output; - settings.out = options.out; - - // Null overwrites config settings, `undefined` does not. - if (settings.output === null || settings.output === undefined) { - settings.output = undefined; - } - - if (settings.output && settings.out) { - return next(new Error('Cannot accept both `output` and `out`')) - } - - // Process phase management. - const tree = options.tree || false; - - settings.treeIn = options.treeIn; - settings.treeOut = options.treeOut; - settings.inspect = options.inspect; - - if (settings.treeIn === null || settings.treeIn === undefined) { - settings.treeIn = tree; - } - - if (settings.treeOut === null || settings.treeOut === undefined) { - settings.treeOut = tree; - } - - // Configuration. - const detectConfig = options.detectConfig; - const hasConfig = Boolean(options.rcName || options.packageField); - - if (detectConfig && !hasConfig) { - return next( - new Error('Missing `rcName` or `packageField` with `detectConfig`') - ) - } - - settings.detectConfig = - detectConfig === null || detectConfig === undefined - ? hasConfig - : detectConfig; - settings.rcName = options.rcName; - settings.rcPath = options.rcPath; - settings.packageField = options.packageField; - settings.settings = options.settings || {}; - settings.configTransform = options.configTransform; - settings.defaultConfig = options.defaultConfig; - - // Ignore. - const detectIgnore = options.detectIgnore; - const hasIgnore = Boolean(options.ignoreName); - - settings.detectIgnore = - detectIgnore === null || detectIgnore === undefined - ? hasIgnore - : detectIgnore; - settings.ignoreName = options.ignoreName; - settings.ignorePath = options.ignorePath; - settings.ignorePathResolveFrom = options.ignorePathResolveFrom || 'dir'; - settings.ignorePatterns = options.ignorePatterns || []; - settings.silentlyIgnore = Boolean(options.silentlyIgnore); - - if (detectIgnore && !hasIgnore) { - return next(new Error('Missing `ignoreName` with `detectIgnore`')) - } - - // Plugins. - settings.pluginPrefix = options.pluginPrefix; - settings.plugins = options.plugins || []; - - // Reporting. - settings.reporter = options.reporter; - settings.reporterOptions = options.reporterOptions; - settings.color = options.color || false; - settings.silent = options.silent; - settings.quiet = options.quiet; - settings.frail = options.frail; - - // Process. - fileSetPipeline.run({files: options.files || []}, settings, next); - - /** - * @param {Error|null} error - * @param {Context} [context] - */ - function next(error, context) { - const stats = statistics((context || {}).files); - const failed = Boolean( - settings.frail ? stats.fatal || stats.warn : stats.fatal - ); - - if (error) { - callback(error); - } else { - callback(null, failed ? 1 : 0, context); - } - } -} - -var textTable = function (rows_, opts) { - if (!opts) opts = {}; - var hsep = opts.hsep === undefined ? ' ' : opts.hsep; - var align = opts.align || []; - var stringLength = opts.stringLength - || function (s) { return String(s).length; } - ; - - var dotsizes = reduce(rows_, function (acc, row) { - forEach(row, function (c, ix) { - var n = dotindex(c); - if (!acc[ix] || n > acc[ix]) acc[ix] = n; - }); - return acc; - }, []); - - var rows = map$2(rows_, function (row) { - return map$2(row, function (c_, ix) { - var c = String(c_); - if (align[ix] === '.') { - var index = dotindex(c); - var size = dotsizes[ix] + (/\./.test(c) ? 1 : 2) - - (stringLength(c) - index) - ; - return c + Array(size).join(' '); - } - else return c; - }); - }); - - var sizes = reduce(rows, function (acc, row) { - forEach(row, function (c, ix) { - var n = stringLength(c); - if (!acc[ix] || n > acc[ix]) acc[ix] = n; - }); - return acc; - }, []); - - return map$2(rows, function (row) { - return map$2(row, function (c, ix) { - var n = (sizes[ix] - stringLength(c)) || 0; - var s = Array(Math.max(n + 1, 1)).join(' '); - if (align[ix] === 'r' || align[ix] === '.') { - return s + c; - } - if (align[ix] === 'c') { - return Array(Math.ceil(n / 2 + 1)).join(' ') - + c + Array(Math.floor(n / 2 + 1)).join(' ') - ; - } - - return c + s; - }).join(hsep).replace(/\s+$/, ''); - }).join('\n'); -}; - -function dotindex (c) { - var m = /\.[^.]*$/.exec(c); - return m ? m.index + 1 : c.length; -} - -function reduce (xs, f, init) { - if (xs.reduce) return xs.reduce(f, init); - var i = 0; - var acc = arguments.length >= 3 ? init : xs[i++]; - for (; i < xs.length; i++) { - f(acc, xs[i], i); - } - return acc; -} - -function forEach (xs, f) { - if (xs.forEach) return xs.forEach(f); - for (var i = 0; i < xs.length; i++) { - f.call(xs, xs[i], i); - } -} - -function map$2 (xs, f) { - if (xs.map) return xs.map(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - res.push(f.call(xs, xs[i], i)); - } - return res; -} - -var camelcase$1 = {exports: {}}; - -const preserveCamelCase = (string, locale) => { - let isLastCharLower = false; - let isLastCharUpper = false; - let isLastLastCharUpper = false; - - for (let i = 0; i < string.length; i++) { - const character = string[i]; - - if (isLastCharLower && /[\p{Lu}]/u.test(character)) { - string = string.slice(0, i) + '-' + string.slice(i); - isLastCharLower = false; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = true; - i++; - } else if (isLastCharUpper && isLastLastCharUpper && /[\p{Ll}]/u.test(character)) { - string = string.slice(0, i - 1) + '-' + string.slice(i - 1); - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = false; - isLastCharLower = true; - } else { - isLastCharLower = character.toLocaleLowerCase(locale) === character && character.toLocaleUpperCase(locale) !== character; - isLastLastCharUpper = isLastCharUpper; - isLastCharUpper = character.toLocaleUpperCase(locale) === character && character.toLocaleLowerCase(locale) !== character; - } - } - - return string; -}; - -const preserveConsecutiveUppercase = input => { - return input.replace(/^[\p{Lu}](?![\p{Lu}])/gu, m1 => m1.toLowerCase()); -}; - -const postProcess = (input, options) => { - return input.replace(/[_.\- ]+([\p{Alpha}\p{N}_]|$)/gu, (_, p1) => p1.toLocaleUpperCase(options.locale)) - .replace(/\d+([\p{Alpha}\p{N}_]|$)/gu, m => m.toLocaleUpperCase(options.locale)); -}; - -const camelCase = (input, options) => { - if (!(typeof input === 'string' || Array.isArray(input))) { - throw new TypeError('Expected the input to be `string | string[]`'); - } - - options = { - pascalCase: false, - preserveConsecutiveUppercase: false, - ...options - }; - - if (Array.isArray(input)) { - input = input.map(x => x.trim()) - .filter(x => x.length) - .join('-'); - } else { - input = input.trim(); - } - - if (input.length === 0) { - return ''; - } - - if (input.length === 1) { - return options.pascalCase ? input.toLocaleUpperCase(options.locale) : input.toLocaleLowerCase(options.locale); - } - - const hasUpperCase = input !== input.toLocaleLowerCase(options.locale); - - if (hasUpperCase) { - input = preserveCamelCase(input, options.locale); - } - - input = input.replace(/^[_.\- ]+/, ''); - - if (options.preserveConsecutiveUppercase) { - input = preserveConsecutiveUppercase(input); - } else { - input = input.toLocaleLowerCase(); - } - - if (options.pascalCase) { - input = input.charAt(0).toLocaleUpperCase(options.locale) + input.slice(1); - } - - return postProcess(input, options); -}; - -camelcase$1.exports = camelCase; -// TODO: Remove this for the next major release -camelcase$1.exports.default = camelCase; - -var camelcase = camelcase$1.exports; - -var minimist = function (args, opts) { - if (!opts) opts = {}; - - var flags = { bools : {}, strings : {}, unknownFn: null }; - - if (typeof opts['unknown'] === 'function') { - flags.unknownFn = opts['unknown']; - } - - if (typeof opts['boolean'] === 'boolean' && opts['boolean']) { - flags.allBools = true; - } else { - [].concat(opts['boolean']).filter(Boolean).forEach(function (key) { - flags.bools[key] = true; - }); - } - - var aliases = {}; - Object.keys(opts.alias || {}).forEach(function (key) { - aliases[key] = [].concat(opts.alias[key]); - aliases[key].forEach(function (x) { - aliases[x] = [key].concat(aliases[key].filter(function (y) { - return x !== y; - })); - }); - }); - - [].concat(opts.string).filter(Boolean).forEach(function (key) { - flags.strings[key] = true; - if (aliases[key]) { - flags.strings[aliases[key]] = true; - } - }); - - var defaults = opts['default'] || {}; - - var argv = { _ : [] }; - Object.keys(flags.bools).forEach(function (key) { - setArg(key, defaults[key] === undefined ? false : defaults[key]); - }); - - var notFlags = []; - - if (args.indexOf('--') !== -1) { - notFlags = args.slice(args.indexOf('--')+1); - args = args.slice(0, args.indexOf('--')); - } - - function argDefined(key, arg) { - return (flags.allBools && /^--[^=]+$/.test(arg)) || - flags.strings[key] || flags.bools[key] || aliases[key]; - } - - function setArg (key, val, arg) { - if (arg && flags.unknownFn && !argDefined(key, arg)) { - if (flags.unknownFn(arg) === false) return; - } - - var value = !flags.strings[key] && isNumber(val) - ? Number(val) : val - ; - setKey(argv, key.split('.'), value); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), value); - }); - } - - function setKey (obj, keys, value) { - var o = obj; - for (var i = 0; i < keys.length-1; i++) { - var key = keys[i]; - if (key === '__proto__') return; - if (o[key] === undefined) o[key] = {}; - if (o[key] === Object.prototype || o[key] === Number.prototype - || o[key] === String.prototype) o[key] = {}; - if (o[key] === Array.prototype) o[key] = []; - o = o[key]; - } - - var key = keys[keys.length - 1]; - if (key === '__proto__') return; - if (o === Object.prototype || o === Number.prototype - || o === String.prototype) o = {}; - if (o === Array.prototype) o = []; - if (o[key] === undefined || flags.bools[key] || typeof o[key] === 'boolean') { - o[key] = value; - } - else if (Array.isArray(o[key])) { - o[key].push(value); - } - else { - o[key] = [ o[key], value ]; - } - } - - function aliasIsBoolean(key) { - return aliases[key].some(function (x) { - return flags.bools[x]; - }); - } - - for (var i = 0; i < args.length; i++) { - var arg = args[i]; - - if (/^--.+=/.test(arg)) { - // Using [\s\S] instead of . because js doesn't support the - // 'dotall' regex modifier. See: - // http://stackoverflow.com/a/1068308/13216 - var m = arg.match(/^--([^=]+)=([\s\S]*)$/); - var key = m[1]; - var value = m[2]; - if (flags.bools[key]) { - value = value !== 'false'; - } - setArg(key, value, arg); - } - else if (/^--no-.+/.test(arg)) { - var key = arg.match(/^--no-(.+)/)[1]; - setArg(key, false, arg); - } - else if (/^--.+/.test(arg)) { - var key = arg.match(/^--(.+)/)[1]; - var next = args[i + 1]; - if (next !== undefined && !/^-/.test(next) - && !flags.bools[key] - && !flags.allBools - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, next, arg); - i++; - } - else if (/^(true|false)$/.test(next)) { - setArg(key, next === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - else if (/^-[^-]+/.test(arg)) { - var letters = arg.slice(1,-1).split(''); - - var broken = false; - for (var j = 0; j < letters.length; j++) { - var next = arg.slice(j+2); - - if (next === '-') { - setArg(letters[j], next, arg); - continue; - } - - if (/[A-Za-z]/.test(letters[j]) && /=/.test(next)) { - setArg(letters[j], next.split('=')[1], arg); - broken = true; - break; - } - - if (/[A-Za-z]/.test(letters[j]) - && /-?\d+(\.\d*)?(e-?\d+)?$/.test(next)) { - setArg(letters[j], next, arg); - broken = true; - break; - } - - if (letters[j+1] && letters[j+1].match(/\W/)) { - setArg(letters[j], arg.slice(j+2), arg); - broken = true; - break; - } - else { - setArg(letters[j], flags.strings[letters[j]] ? '' : true, arg); - } - } - - var key = arg.slice(-1)[0]; - if (!broken && key !== '-') { - if (args[i+1] && !/^(-|--)[^-]/.test(args[i+1]) - && !flags.bools[key] - && (aliases[key] ? !aliasIsBoolean(key) : true)) { - setArg(key, args[i+1], arg); - i++; - } - else if (args[i+1] && /^(true|false)$/.test(args[i+1])) { - setArg(key, args[i+1] === 'true', arg); - i++; - } - else { - setArg(key, flags.strings[key] ? '' : true, arg); - } - } - } - else { - if (!flags.unknownFn || flags.unknownFn(arg) !== false) { - argv._.push( - flags.strings['_'] || !isNumber(arg) ? arg : Number(arg) - ); - } - if (opts.stopEarly) { - argv._.push.apply(argv._, args.slice(i + 1)); - break; - } - } - } - - Object.keys(defaults).forEach(function (key) { - if (!hasKey(argv, key.split('.'))) { - setKey(argv, key.split('.'), defaults[key]); - - (aliases[key] || []).forEach(function (x) { - setKey(argv, x.split('.'), defaults[key]); - }); - } - }); - - if (opts['--']) { - argv['--'] = new Array(); - notFlags.forEach(function(key) { - argv['--'].push(key); - }); - } - else { - notFlags.forEach(function(key) { - argv._.push(key); - }); - } - - return argv; -}; - -function hasKey (obj, keys) { - var o = obj; - keys.slice(0,-1).forEach(function (key) { - o = (o[key] || {}); - }); - - var key = keys[keys.length - 1]; - return key in o; -} - -function isNumber (x) { - if (typeof x === 'number') return true; - if (/^0x[0-9a-f]+$/i.test(x)) return true; - return /^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(x); -} - -// This is a generated file. Do not edit. -var Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/; -var ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/; -var ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/; - -var unicode = { - Space_Separator: Space_Separator, - ID_Start: ID_Start, - ID_Continue: ID_Continue -}; - -var util = { - isSpaceSeparator (c) { - return typeof c === 'string' && unicode.Space_Separator.test(c) - }, - - isIdStartChar (c) { - return typeof c === 'string' && ( - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c === '$') || (c === '_') || - unicode.ID_Start.test(c) - ) - }, - - isIdContinueChar (c) { - return typeof c === 'string' && ( - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || - (c === '$') || (c === '_') || - (c === '\u200C') || (c === '\u200D') || - unicode.ID_Continue.test(c) - ) - }, - - isDigit (c) { - return typeof c === 'string' && /[0-9]/.test(c) - }, - - isHexDigit (c) { - return typeof c === 'string' && /[0-9A-Fa-f]/.test(c) - }, -}; - -let source; -let parseState; -let stack; -let pos; -let line; -let column; -let token; -let key; -let root$1; - -var parse$1 = function parse (text, reviver) { - source = String(text); - parseState = 'start'; - stack = []; - pos = 0; - line = 1; - column = 0; - token = undefined; - key = undefined; - root$1 = undefined; - - do { - token = lex(); - - // This code is unreachable. - // if (!parseStates[parseState]) { - // throw invalidParseState() - // } - - parseStates[parseState](); - } while (token.type !== 'eof') - - if (typeof reviver === 'function') { - return internalize({'': root$1}, '', reviver) - } - - return root$1 -}; - -function internalize (holder, name, reviver) { - const value = holder[name]; - if (value != null && typeof value === 'object') { - for (const key in value) { - const replacement = internalize(value, key, reviver); - if (replacement === undefined) { - delete value[key]; - } else { - value[key] = replacement; - } - } - } - - return reviver.call(holder, name, value) -} - -let lexState; -let buffer; -let doubleQuote; -let sign; -let c; - -function lex () { - lexState = 'default'; - buffer = ''; - doubleQuote = false; - sign = 1; - - for (;;) { - c = peek(); - - // This code is unreachable. - // if (!lexStates[lexState]) { - // throw invalidLexState(lexState) - // } - - const token = lexStates[lexState](); - if (token) { - return token - } - } -} - -function peek () { - if (source[pos]) { - return String.fromCodePoint(source.codePointAt(pos)) - } -} - -function read () { - const c = peek(); - - if (c === '\n') { - line++; - column = 0; - } else if (c) { - column += c.length; - } else { - column++; - } - - if (c) { - pos += c.length; - } - - return c -} - -const lexStates = { - default () { - switch (c) { - case '\t': - case '\v': - case '\f': - case ' ': - case '\u00A0': - case '\uFEFF': - case '\n': - case '\r': - case '\u2028': - case '\u2029': - read(); - return - - case '/': - read(); - lexState = 'comment'; - return - - case undefined: - read(); - return newToken('eof') - } - - if (util.isSpaceSeparator(c)) { - read(); - return - } - - // This code is unreachable. - // if (!lexStates[parseState]) { - // throw invalidLexState(parseState) - // } - - return lexStates[parseState]() - }, - - comment () { - switch (c) { - case '*': - read(); - lexState = 'multiLineComment'; - return - - case '/': - read(); - lexState = 'singleLineComment'; - return - } - - throw invalidChar(read()) - }, - - multiLineComment () { - switch (c) { - case '*': - read(); - lexState = 'multiLineCommentAsterisk'; - return - - case undefined: - throw invalidChar(read()) - } - - read(); - }, - - multiLineCommentAsterisk () { - switch (c) { - case '*': - read(); - return - - case '/': - read(); - lexState = 'default'; - return - - case undefined: - throw invalidChar(read()) - } - - read(); - lexState = 'multiLineComment'; - }, - - singleLineComment () { - switch (c) { - case '\n': - case '\r': - case '\u2028': - case '\u2029': - read(); - lexState = 'default'; - return - - case undefined: - read(); - return newToken('eof') - } - - read(); - }, - - value () { - switch (c) { - case '{': - case '[': - return newToken('punctuator', read()) - - case 'n': - read(); - literal('ull'); - return newToken('null', null) - - case 't': - read(); - literal('rue'); - return newToken('boolean', true) - - case 'f': - read(); - literal('alse'); - return newToken('boolean', false) - - case '-': - case '+': - if (read() === '-') { - sign = -1; - } - - lexState = 'sign'; - return - - case '.': - buffer = read(); - lexState = 'decimalPointLeading'; - return - - case '0': - buffer = read(); - lexState = 'zero'; - return - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - buffer = read(); - lexState = 'decimalInteger'; - return - - case 'I': - read(); - literal('nfinity'); - return newToken('numeric', Infinity) - - case 'N': - read(); - literal('aN'); - return newToken('numeric', NaN) - - case '"': - case "'": - doubleQuote = (read() === '"'); - buffer = ''; - lexState = 'string'; - return - } - - throw invalidChar(read()) - }, - - identifierNameStartEscape () { - if (c !== 'u') { - throw invalidChar(read()) - } - - read(); - const u = unicodeEscape(); - switch (u) { - case '$': - case '_': - break - - default: - if (!util.isIdStartChar(u)) { - throw invalidIdentifier() - } - - break - } - - buffer += u; - lexState = 'identifierName'; - }, - - identifierName () { - switch (c) { - case '$': - case '_': - case '\u200C': - case '\u200D': - buffer += read(); - return - - case '\\': - read(); - lexState = 'identifierNameEscape'; - return - } - - if (util.isIdContinueChar(c)) { - buffer += read(); - return - } - - return newToken('identifier', buffer) - }, - - identifierNameEscape () { - if (c !== 'u') { - throw invalidChar(read()) - } - - read(); - const u = unicodeEscape(); - switch (u) { - case '$': - case '_': - case '\u200C': - case '\u200D': - break - - default: - if (!util.isIdContinueChar(u)) { - throw invalidIdentifier() - } - - break - } - - buffer += u; - lexState = 'identifierName'; - }, - - sign () { - switch (c) { - case '.': - buffer = read(); - lexState = 'decimalPointLeading'; - return - - case '0': - buffer = read(); - lexState = 'zero'; - return - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - buffer = read(); - lexState = 'decimalInteger'; - return - - case 'I': - read(); - literal('nfinity'); - return newToken('numeric', sign * Infinity) - - case 'N': - read(); - literal('aN'); - return newToken('numeric', NaN) - } - - throw invalidChar(read()) - }, - - zero () { - switch (c) { - case '.': - buffer += read(); - lexState = 'decimalPoint'; - return - - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - - case 'x': - case 'X': - buffer += read(); - lexState = 'hexadecimal'; - return - } - - return newToken('numeric', sign * 0) - }, - - decimalInteger () { - switch (c) { - case '.': - buffer += read(); - lexState = 'decimalPoint'; - return - - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - decimalPointLeading () { - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalFraction'; - return - } - - throw invalidChar(read()) - }, - - decimalPoint () { - switch (c) { - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalFraction'; - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - decimalFraction () { - switch (c) { - case 'e': - case 'E': - buffer += read(); - lexState = 'decimalExponent'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - decimalExponent () { - switch (c) { - case '+': - case '-': - buffer += read(); - lexState = 'decimalExponentSign'; - return - } - - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalExponentInteger'; - return - } - - throw invalidChar(read()) - }, - - decimalExponentSign () { - if (util.isDigit(c)) { - buffer += read(); - lexState = 'decimalExponentInteger'; - return - } - - throw invalidChar(read()) - }, - - decimalExponentInteger () { - if (util.isDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - hexadecimal () { - if (util.isHexDigit(c)) { - buffer += read(); - lexState = 'hexadecimalInteger'; - return - } - - throw invalidChar(read()) - }, - - hexadecimalInteger () { - if (util.isHexDigit(c)) { - buffer += read(); - return - } - - return newToken('numeric', sign * Number(buffer)) - }, - - string () { - switch (c) { - case '\\': - read(); - buffer += escape(); - return - - case '"': - if (doubleQuote) { - read(); - return newToken('string', buffer) - } - - buffer += read(); - return - - case "'": - if (!doubleQuote) { - read(); - return newToken('string', buffer) - } - - buffer += read(); - return - - case '\n': - case '\r': - throw invalidChar(read()) - - case '\u2028': - case '\u2029': - separatorChar(c); - break - - case undefined: - throw invalidChar(read()) - } - - buffer += read(); - }, - - start () { - switch (c) { - case '{': - case '[': - return newToken('punctuator', read()) - - // This code is unreachable since the default lexState handles eof. - // case undefined: - // return newToken('eof') - } - - lexState = 'value'; - }, - - beforePropertyName () { - switch (c) { - case '$': - case '_': - buffer = read(); - lexState = 'identifierName'; - return - - case '\\': - read(); - lexState = 'identifierNameStartEscape'; - return - - case '}': - return newToken('punctuator', read()) - - case '"': - case "'": - doubleQuote = (read() === '"'); - lexState = 'string'; - return - } - - if (util.isIdStartChar(c)) { - buffer += read(); - lexState = 'identifierName'; - return - } - - throw invalidChar(read()) - }, - - afterPropertyName () { - if (c === ':') { - return newToken('punctuator', read()) - } - - throw invalidChar(read()) - }, - - beforePropertyValue () { - lexState = 'value'; - }, - - afterPropertyValue () { - switch (c) { - case ',': - case '}': - return newToken('punctuator', read()) - } - - throw invalidChar(read()) - }, - - beforeArrayValue () { - if (c === ']') { - return newToken('punctuator', read()) - } - - lexState = 'value'; - }, - - afterArrayValue () { - switch (c) { - case ',': - case ']': - return newToken('punctuator', read()) - } - - throw invalidChar(read()) - }, - - end () { - // This code is unreachable since it's handled by the default lexState. - // if (c === undefined) { - // read() - // return newToken('eof') - // } - - throw invalidChar(read()) - }, -}; - -function newToken (type, value) { - return { - type, - value, - line, - column, - } -} - -function literal (s) { - for (const c of s) { - const p = peek(); - - if (p !== c) { - throw invalidChar(read()) - } - - read(); - } -} - -function escape () { - const c = peek(); - switch (c) { - case 'b': - read(); - return '\b' - - case 'f': - read(); - return '\f' - - case 'n': - read(); - return '\n' - - case 'r': - read(); - return '\r' - - case 't': - read(); - return '\t' - - case 'v': - read(); - return '\v' - - case '0': - read(); - if (util.isDigit(peek())) { - throw invalidChar(read()) - } - - return '\0' - - case 'x': - read(); - return hexEscape() - - case 'u': - read(); - return unicodeEscape() - - case '\n': - case '\u2028': - case '\u2029': - read(); - return '' - - case '\r': - read(); - if (peek() === '\n') { - read(); - } - - return '' - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - throw invalidChar(read()) - - case undefined: - throw invalidChar(read()) - } - - return read() -} - -function hexEscape () { - let buffer = ''; - let c = peek(); - - if (!util.isHexDigit(c)) { - throw invalidChar(read()) - } - - buffer += read(); - - c = peek(); - if (!util.isHexDigit(c)) { - throw invalidChar(read()) - } - - buffer += read(); - - return String.fromCodePoint(parseInt(buffer, 16)) -} - -function unicodeEscape () { - let buffer = ''; - let count = 4; - - while (count-- > 0) { - const c = peek(); - if (!util.isHexDigit(c)) { - throw invalidChar(read()) - } - - buffer += read(); - } - - return String.fromCodePoint(parseInt(buffer, 16)) -} - -const parseStates = { - start () { - if (token.type === 'eof') { - throw invalidEOF() - } - - push$1(); - }, - - beforePropertyName () { - switch (token.type) { - case 'identifier': - case 'string': - key = token.value; - parseState = 'afterPropertyName'; - return - - case 'punctuator': - // This code is unreachable since it's handled by the lexState. - // if (token.value !== '}') { - // throw invalidToken() - // } - - pop(); - return - - case 'eof': - throw invalidEOF() - } - - // This code is unreachable since it's handled by the lexState. - // throw invalidToken() - }, - - afterPropertyName () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'punctuator' || token.value !== ':') { - // throw invalidToken() - // } - - if (token.type === 'eof') { - throw invalidEOF() - } - - parseState = 'beforePropertyValue'; - }, - - beforePropertyValue () { - if (token.type === 'eof') { - throw invalidEOF() - } - - push$1(); - }, - - beforeArrayValue () { - if (token.type === 'eof') { - throw invalidEOF() - } - - if (token.type === 'punctuator' && token.value === ']') { - pop(); - return - } - - push$1(); - }, - - afterPropertyValue () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'punctuator') { - // throw invalidToken() - // } - - if (token.type === 'eof') { - throw invalidEOF() - } - - switch (token.value) { - case ',': - parseState = 'beforePropertyName'; - return - - case '}': - pop(); - } - - // This code is unreachable since it's handled by the lexState. - // throw invalidToken() - }, - - afterArrayValue () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'punctuator') { - // throw invalidToken() - // } - - if (token.type === 'eof') { - throw invalidEOF() - } - - switch (token.value) { - case ',': - parseState = 'beforeArrayValue'; - return - - case ']': - pop(); - } - - // This code is unreachable since it's handled by the lexState. - // throw invalidToken() - }, - - end () { - // This code is unreachable since it's handled by the lexState. - // if (token.type !== 'eof') { - // throw invalidToken() - // } - }, -}; - -function push$1 () { - let value; - - switch (token.type) { - case 'punctuator': - switch (token.value) { - case '{': - value = {}; - break - - case '[': - value = []; - break - } - - break - - case 'null': - case 'boolean': - case 'numeric': - case 'string': - value = token.value; - break - - // This code is unreachable. - // default: - // throw invalidToken() - } - - if (root$1 === undefined) { - root$1 = value; - } else { - const parent = stack[stack.length - 1]; - if (Array.isArray(parent)) { - parent.push(value); - } else { - parent[key] = value; - } - } - - if (value !== null && typeof value === 'object') { - stack.push(value); - - if (Array.isArray(value)) { - parseState = 'beforeArrayValue'; - } else { - parseState = 'beforePropertyName'; - } - } else { - const current = stack[stack.length - 1]; - if (current == null) { - parseState = 'end'; - } else if (Array.isArray(current)) { - parseState = 'afterArrayValue'; - } else { - parseState = 'afterPropertyValue'; - } - } -} - -function pop () { - stack.pop(); - - const current = stack[stack.length - 1]; - if (current == null) { - parseState = 'end'; - } else if (Array.isArray(current)) { - parseState = 'afterArrayValue'; - } else { - parseState = 'afterPropertyValue'; - } -} - -// This code is unreachable. -// function invalidParseState () { -// return new Error(`JSON5: invalid parse state '${parseState}'`) -// } - -// This code is unreachable. -// function invalidLexState (state) { -// return new Error(`JSON5: invalid lex state '${state}'`) -// } - -function invalidChar (c) { - if (c === undefined) { - return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) - } - - return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) -} - -function invalidEOF () { - return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) -} - -// This code is unreachable. -// function invalidToken () { -// if (token.type === 'eof') { -// return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) -// } - -// const c = String.fromCodePoint(token.value.codePointAt(0)) -// return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`) -// } - -function invalidIdentifier () { - column -= 5; - return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`) -} - -function separatorChar (c) { - console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`); -} - -function formatChar (c) { - const replacements = { - "'": "\\'", - '"': '\\"', - '\\': '\\\\', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', - '\v': '\\v', - '\0': '\\0', - '\u2028': '\\u2028', - '\u2029': '\\u2029', - }; - - if (replacements[c]) { - return replacements[c] - } - - if (c < ' ') { - const hexString = c.charCodeAt(0).toString(16); - return '\\x' + ('00' + hexString).substring(hexString.length) - } - - return c -} - -function syntaxError (message) { - const err = new SyntaxError(message); - err.lineNumber = line; - err.columnNumber = column; - return err -} - -var stringify = function stringify (value, replacer, space) { - const stack = []; - let indent = ''; - let propertyList; - let replacerFunc; - let gap = ''; - let quote; - - if ( - replacer != null && - typeof replacer === 'object' && - !Array.isArray(replacer) - ) { - space = replacer.space; - quote = replacer.quote; - replacer = replacer.replacer; - } - - if (typeof replacer === 'function') { - replacerFunc = replacer; - } else if (Array.isArray(replacer)) { - propertyList = []; - for (const v of replacer) { - let item; - - if (typeof v === 'string') { - item = v; - } else if ( - typeof v === 'number' || - v instanceof String || - v instanceof Number - ) { - item = String(v); - } - - if (item !== undefined && propertyList.indexOf(item) < 0) { - propertyList.push(item); - } - } - } - - if (space instanceof Number) { - space = Number(space); - } else if (space instanceof String) { - space = String(space); - } - - if (typeof space === 'number') { - if (space > 0) { - space = Math.min(10, Math.floor(space)); - gap = ' '.substr(0, space); - } - } else if (typeof space === 'string') { - gap = space.substr(0, 10); - } - - return serializeProperty('', {'': value}) - - function serializeProperty (key, holder) { - let value = holder[key]; - if (value != null) { - if (typeof value.toJSON5 === 'function') { - value = value.toJSON5(key); - } else if (typeof value.toJSON === 'function') { - value = value.toJSON(key); - } - } - - if (replacerFunc) { - value = replacerFunc.call(holder, key, value); - } - - if (value instanceof Number) { - value = Number(value); - } else if (value instanceof String) { - value = String(value); - } else if (value instanceof Boolean) { - value = value.valueOf(); - } - - switch (value) { - case null: return 'null' - case true: return 'true' - case false: return 'false' - } - - if (typeof value === 'string') { - return quoteString(value) - } - - if (typeof value === 'number') { - return String(value) - } - - if (typeof value === 'object') { - return Array.isArray(value) ? serializeArray(value) : serializeObject(value) - } - - return undefined - } - - function quoteString (value) { - const quotes = { - "'": 0.1, - '"': 0.2, - }; - - const replacements = { - "'": "\\'", - '"': '\\"', - '\\': '\\\\', - '\b': '\\b', - '\f': '\\f', - '\n': '\\n', - '\r': '\\r', - '\t': '\\t', - '\v': '\\v', - '\0': '\\0', - '\u2028': '\\u2028', - '\u2029': '\\u2029', - }; - - let product = ''; - - for (let i = 0; i < value.length; i++) { - const c = value[i]; - switch (c) { - case "'": - case '"': - quotes[c]++; - product += c; - continue - - case '\0': - if (util.isDigit(value[i + 1])) { - product += '\\x00'; - continue - } - } - - if (replacements[c]) { - product += replacements[c]; - continue - } - - if (c < ' ') { - let hexString = c.charCodeAt(0).toString(16); - product += '\\x' + ('00' + hexString).substring(hexString.length); - continue - } - - product += c; - } - - const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b); - - product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]); - - return quoteChar + product + quoteChar - } - - function serializeObject (value) { - if (stack.indexOf(value) >= 0) { - throw TypeError('Converting circular structure to JSON5') - } - - stack.push(value); - - let stepback = indent; - indent = indent + gap; - - let keys = propertyList || Object.keys(value); - let partial = []; - for (const key of keys) { - const propertyString = serializeProperty(key, value); - if (propertyString !== undefined) { - let member = serializeKey(key) + ':'; - if (gap !== '') { - member += ' '; - } - member += propertyString; - partial.push(member); - } - } - - let final; - if (partial.length === 0) { - final = '{}'; - } else { - let properties; - if (gap === '') { - properties = partial.join(','); - final = '{' + properties + '}'; - } else { - let separator = ',\n' + indent; - properties = partial.join(separator); - final = '{\n' + indent + properties + ',\n' + stepback + '}'; - } - } - - stack.pop(); - indent = stepback; - return final - } - - function serializeKey (key) { - if (key.length === 0) { - return quoteString(key) - } - - const firstChar = String.fromCodePoint(key.codePointAt(0)); - if (!util.isIdStartChar(firstChar)) { - return quoteString(key) - } - - for (let i = firstChar.length; i < key.length; i++) { - if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) { - return quoteString(key) - } - } - - return key - } - - function serializeArray (value) { - if (stack.indexOf(value) >= 0) { - throw TypeError('Converting circular structure to JSON5') - } - - stack.push(value); - - let stepback = indent; - indent = indent + gap; - - let partial = []; - for (let i = 0; i < value.length; i++) { - const propertyString = serializeProperty(String(i), value); - partial.push((propertyString !== undefined) ? propertyString : 'null'); - } - - let final; - if (partial.length === 0) { - final = '[]'; - } else { - if (gap === '') { - let properties = partial.join(','); - final = '[' + properties + ']'; - } else { - let separator = ',\n' + indent; - let properties = partial.join(separator); - final = '[\n' + indent + properties + ',\n' + stepback + ']'; - } - } - - stack.pop(); - indent = stepback; - return final - } -}; - -const JSON5 = { - parse: parse$1, - stringify, -}; - -var lib = JSON5; - -/** - * @typedef Option - * @property {'boolean'|'string'} [type='string'] - * @property {string} long - * @property {string} description - * @property {string} [value] - * @property {string} [short] - * @property {boolean|string} [default=''] - * @property {boolean} [truelike=false] - */ - -/** @type {Option[]} */ -const schema = [ - { - long: 'help', - description: 'output usage information', - short: 'h', - type: 'boolean', - default: false - }, - { - long: 'version', - description: 'output version number', - short: 'v', - type: 'boolean', - default: false - }, - { - long: 'output', - description: 'specify output location', - short: 'o', - value: '[path]' - }, - { - long: 'rc-path', - description: 'specify configuration file', - short: 'r', - type: 'string', - value: '' - }, - { - long: 'ignore-path', - description: 'specify ignore file', - short: 'i', - type: 'string', - value: '' - }, - { - long: 'setting', - description: 'specify settings', - short: 's', - type: 'string', - value: '' - }, - { - long: 'ext', - description: 'specify extensions', - short: 'e', - type: 'string', - value: '' - }, - { - long: 'use', - description: 'use plugins', - short: 'u', - type: 'string', - value: '' - }, - { - long: 'watch', - description: 'watch for changes and reprocess', - short: 'w', - type: 'boolean', - default: false - }, - { - long: 'quiet', - description: 'output only warnings and errors', - short: 'q', - type: 'boolean', - default: false - }, - { - long: 'silent', - description: 'output only errors', - short: 'S', - type: 'boolean', - default: false - }, - { - long: 'frail', - description: 'exit with 1 on warnings', - short: 'f', - type: 'boolean', - default: false - }, - { - long: 'tree', - description: 'specify input and output as syntax tree', - short: 't', - type: 'boolean', - default: false - }, - { - long: 'report', - description: 'specify reporter', - type: 'string', - value: '' - }, - { - long: 'file-path', - description: 'specify path to process as', - type: 'string', - value: '' - }, - { - long: 'ignore-path-resolve-from', - description: 'resolve patterns in `ignore-path` from its directory or cwd', - type: 'string', - value: 'dir|cwd', - default: 'dir' - }, - { - long: 'ignore-pattern', - description: 'specify ignore patterns', - type: 'string', - value: '' - }, - { - long: 'silently-ignore', - description: 'do not fail when given ignored files', - type: 'boolean' - }, - { - long: 'tree-in', - description: 'specify input as syntax tree', - type: 'boolean' - }, - { - long: 'tree-out', - description: 'output syntax tree', - type: 'boolean' - }, - { - long: 'inspect', - description: 'output formatted syntax tree', - type: 'boolean' - }, - { - long: 'stdout', - description: 'specify writing to stdout', - type: 'boolean', - truelike: true - }, - { - long: 'color', - description: 'specify color in report', - type: 'boolean', - default: true - }, - { - long: 'config', - description: 'search for configuration files', - type: 'boolean', - default: true - }, - { - long: 'ignore', - description: 'search for ignore files', - type: 'boolean', - default: true - } -]; - -/** - * @typedef {import('unified-engine').Options} EngineOptions - * @typedef {import('./schema.js').Option} Option - * - * @typedef {Required< - * Pick< - * EngineOptions, - * | 'extensions' - * | 'ignoreName' - * | 'packageField' - * | 'pluginPrefix' - * | 'processor' - * | 'rcName' - * > - * >} RequiredEngineOptions - * - * @typedef ArgsOptionsFields - * @property {string} name - * Name of executable - * @property {string} description - * Description of executable - * @property {string} version - * Version (semver) of executable - * - * @typedef {RequiredEngineOptions & Pick & ArgsOptionsFields} Options - */ - -const own$7 = {}.hasOwnProperty; - -/** - * Schema for `minimist`. - */ -const minischema = { - unknown: handleUnknownArgument, - /** @type {Record} */ - default: {}, - /** @type {Record} */ - alias: {}, - /** @type {string[]} */ - string: [], - /** @type {string[]} */ - boolean: [] -}; - -let index = -1; -while (++index < schema.length) { - addEach(schema[index]); -} - -/** - * Parse CLI options. - * - * @param {string[]} flags - * @param {Options} configuration - */ -function options(flags, configuration) { - const extension = configuration.extensions[0]; - const name = configuration.name; - const config = toCamelCase(minimist(flags, minischema)); - let index = -1; - - while (++index < schema.length) { - const option = schema[index]; - if (option.type === 'string' && config[option.long] === '') { - throw fault('Missing value:%s', inspect(option).join(' ')) - } - } - - const ext = commaSeparated(/** @type {string} */ (config.ext)); - const report = reporter(/** @type {string} */ (config.report)); - const help = [ - inspectAll(schema), - '', - 'Examples:', - '', - ' # Process `input.' + extension + '`', - ' $ ' + name + ' input.' + extension + ' -o output.' + extension, - '', - ' # Pipe', - ' $ ' + name + ' < input.' + extension + ' > output.' + extension, - '', - ' # Rewrite all applicable files', - ' $ ' + name + ' . -o' - ].join('\n'); - - return { - helpMessage: help, - cwd: configuration.cwd, - processor: configuration.processor, - help: config.help, - version: config.version, - files: config._, - filePath: config.filePath, - watch: config.watch, - extensions: ext.length === 0 ? configuration.extensions : ext, - output: config.output, - out: config.stdout, - tree: config.tree, - treeIn: config.treeIn, - treeOut: config.treeOut, - inspect: config.inspect, - rcName: configuration.rcName, - packageField: configuration.packageField, - rcPath: config.rcPath, - detectConfig: config.config, - settings: /** @type {Record} */ ( - settings(/** @type {string} */ (config.setting)) - ), - ignoreName: configuration.ignoreName, - ignorePath: config.ignorePath, - ignorePathResolveFrom: config.ignorePathResolveFrom, - ignorePatterns: commaSeparated( - /** @type {string} */ (config.ignorePattern) - ), - silentlyIgnore: config.silentlyIgnore, - detectIgnore: config.ignore, - pluginPrefix: configuration.pluginPrefix, - plugins: plugins$1(/** @type {string} */ (config.use)), - reporter: report[0], - reporterOptions: report[1], - color: config.color, - silent: config.silent, - quiet: config.quiet, - frail: config.frail - } -} - -/** - * @param {Option} option - */ -function addEach(option) { - const value = option.default; - - minischema.default[option.long] = value === undefined ? null : value; - - if (option.type && option.type in minischema) { - minischema[option.type].push(option.long); - } - - if (option.short) { - minischema.alias[option.short] = option.long; - } -} - -/** - * Parse `extensions`. - * - * @param {string[]|string|null|undefined} value - * @returns {string[]} - */ -function commaSeparated(value) { - return flatten(normalize(value).map((d) => splitList(d))) -} - -/** - * Parse `plugins`. - * - * @param {string[]|string|null|undefined} value - * @returns {Record|undefined>} - */ -function plugins$1(value) { - const normalized = normalize(value).map((d) => splitOptions(d)); - let index = -1; - /** @type {Record|undefined>} */ - const result = {}; - - while (++index < normalized.length) { - const value = normalized[index]; - result[value[0]] = value[1] ? parseConfig(value[1], {}) : undefined; - } - - return result -} - -/** - * Parse `reporter`: only one is accepted. - * - * @param {string[]|string|null|undefined} value - * @returns {[string|undefined, Record|undefined]} - */ -function reporter(value) { - const all = normalize(value) - .map((d) => splitOptions(d)) - .map( - /** - * @returns {[string, Record|undefined]} - */ - (value) => [value[0], value[1] ? parseConfig(value[1], {}) : undefined] - ); - - return all[all.length - 1] || [] -} - -/** - * Parse `settings`. - * - * @param {string[]|string|null|undefined} value - * @returns {Record} - */ -function settings(value) { - const normalized = normalize(value); - let index = -1; - /** @type {Record} */ - const cache = {}; - - while (++index < normalized.length) { - parseConfig(normalized[index], cache); - } - - return cache -} - -/** - * Parse configuration. - * - * @param {string} value - * @param {Record} cache - * @returns {Record} - */ -function parseConfig(value, cache) { - /** @type {Record} */ - let flags; - /** @type {string} */ - let flag; - - try { - flags = toCamelCase(parseJSON(value)); - } catch (error) { - throw fault( - 'Cannot parse `%s` as JSON: %s', - value, - // Fix position - error.message.replace(/at(?= position)/, 'around') - ) - } - - for (flag in flags) { - if (own$7.call(flags, flag)) { - cache[flag] = flags[flag]; - } - } - - return cache -} - -/** - * Handle an unknown flag. - * - * @param {string} flag - * @returns {boolean} - */ -function handleUnknownArgument(flag) { - // Not a glob. - if (flag.charAt(0) === '-') { - // Long options, always unknown. - if (flag.charAt(1) === '-') { - throw fault( - 'Unknown option `%s`, expected:\n%s', - flag, - inspectAll(schema) - ) - } - - // Short options, can be grouped. - const found = flag.slice(1).split(''); - const known = schema.filter((d) => d.short); - const knownKeys = new Set(known.map((d) => d.short)); - let index = -1; - - while (++index < found.length) { - const key = found[index]; - if (!knownKeys.has(key)) { - throw fault( - 'Unknown short option `-%s`, expected:\n%s', - key, - inspectAll(known) - ) - } - } - } - - return true -} - -/** - * Inspect all `options`. - * - * @param {Option[]} options - * @returns {string} - */ -function inspectAll(options) { - return textTable(options.map((d) => inspect(d))) -} - -/** - * Inspect one `option`. - * - * @param {Option} option - * @returns {string[]} - */ -function inspect(option) { - let description = option.description; - let long = option.long; - - if (option.default === true || option.truelike) { - description += ' (on by default)'; - long = '[no-]' + long; - } - - return [ - '', - option.short ? '-' + option.short : '', - '--' + long + (option.value ? ' ' + option.value : ''), - description - ] -} - -/** - * Normalize `value`. - * - * @param {string[]|string|null|undefined} value - * @returns {string[]} - */ -function normalize(value) { - if (!value) { - return [] - } - - if (typeof value === 'string') { - return [value] - } - - return flatten(value.map((d) => normalize(d))) -} - -/** - * Flatten `values`. - * - * @param {string|string[]|string[][]} values - * @returns {string[]} - */ -function flatten(values) { - // @ts-expect-error: TS is wrong. - return values.flat() -} - -/** - * @param {string} value - * @returns {string[]} - */ -function splitOptions(value) { - return value.split('=') -} - -/** - * @param {string} value - * @returns {string[]} - */ -function splitList(value) { - return value.split(',') -} - -/** - * Transform the keys on an object to camel-case, recursivly. - * - * @param {Record} object - * @returns {Record} - */ -function toCamelCase(object) { - /** @type {Record} */ - const result = {}; - /** @type {string} */ - let key; - - for (key in object) { - if (own$7.call(object, key)) { - let value = object[key]; - - if (value && typeof value === 'object' && !Array.isArray(value)) { - // @ts-expect-error: looks like an object. - value = toCamelCase(value); - } - - result[camelcase(key)] = value; - } - } - - return result -} - -/** - * Parse a (lazy?) JSON config. - * - * @param {string} value - * @returns {Record} - */ -function parseJSON(value) { - return lib.parse('{' + value + '}') -} - -/** - * @typedef {import('unified-engine').Options} EngineOptions - * @typedef {import('unified-engine').Context} EngineContext - * @typedef {import('unified-engine').Callback} EngineCallback - * @typedef {import('./options.js').Options} Options - */ - -// Fake TTY stream. -const ttyStream = Object.assign(new stream.Readable(), {isTTY: true}); - -// Exit, lazily, with the correct exit status code. -let exitStatus = 0; - -process$2.on('exit', onexit); - -// Handle uncaught errors, such as from unexpected async behaviour. -process$2.on('uncaughtException', fail); - -/** - * Start the CLI. - * - * @param {Options} cliConfig - */ -function args(cliConfig) { - /** @type {EngineOptions & {help: boolean, helpMessage: string, watch: boolean, version: boolean}} */ - let config; - /** @type {chokidar.FSWatcher|undefined} */ - let watcher; - /** @type {boolean|string|undefined} */ - let output; - - try { - // @ts-expect-error: Close enough. - config = options(process$2.argv.slice(2), cliConfig); - } catch (error) { - return fail(error, true) - } - - if (config.help) { - process$2.stdout.write( - [ - 'Usage: ' + cliConfig.name + ' [options] [path | glob ...]', - '', - ' ' + cliConfig.description, - '', - 'Options:', - '', - config.helpMessage, - '' - ].join('\n'), - noop$1 - ); - - return - } - - if (config.version) { - process$2.stdout.write(cliConfig.version + '\n', noop$1); - - return - } - - // Modify `config` for watching. - if (config.watch) { - output = config.output; - - // Do not read from stdin(4). - config.streamIn = ttyStream; - - // Do not write to stdout(4). - config.out = false; - - process$2.stderr.write( - source$1.bold('Watching...') + ' (press CTRL+C to exit)\n', - noop$1 - ); - - // Prevent infinite loop if set to regeneration. - if (output === true) { - config.output = false; - - process$2.stderr.write( - source$1.yellow('Note') + ': Ignoring `--output` until exit.\n', - noop$1 - ); - } - } - - // Initial run. - engine(config, done); - - /** - * Handle complete run. - * - * @type {EngineCallback} - */ - function done(error, code, context) { - if (error) { - clean(); - fail(error); - } else { - exitStatus = code || 0; - - if (config.watch && !watcher && context) { - subscribe(context); - } - } - } - - // Clean the watcher. - function clean() { - if (watcher) { - watcher.close(); - watcher = undefined; - } - } - - /** - * Subscribe a chokidar watcher to all processed files. - * - * @param {EngineContext} context - */ - function subscribe(context) { - watcher = chokidar - // @ts-expect-error: `fileSet` is available. - .watch(context.fileSet.origins, {cwd: config.cwd, ignoreInitial: true}) - .on('error', done) - .on('change', (filePath) => { - config.files = [filePath]; - engine(config, done); - }); - - process$2.on('SIGINT', onsigint); - - /** - * Handle a SIGINT. - */ - function onsigint() { - // Hide the `^C` in terminal. - process$2.stderr.write('\n', noop$1); - - clean(); - - // Do another process if `output` specified regeneration. - if (output === true) { - config.output = output; - config.watch = false; - engine(config, done); - } - } - } -} - -/** - * Print an error, optionally with stack. - * - * @param {Error} error - * @param {boolean} [pretty=false] - */ -function fail(error, pretty) { - // Old versions of Node - /* c8 ignore next 1 */ - const message = String((pretty ? error : error.stack) || error); - - exitStatus = 1; - - process$2.stderr.write(message.trim() + '\n', noop$1); -} - -function onexit() { - /* eslint-disable unicorn/no-process-exit */ - process$2.exit(exitStatus); - /* eslint-enable unicorn/no-process-exit */ -} - -function noop$1() {} - -var require$$0 = [ - "md", - "markdown", - "mdown", - "mkdn", - "mkd", - "mdwn", - "mkdown", - "ron" -]; - -var markdownExtensions = require$$0; - -/** - * Throw a given error. - * - * @param {Error | null | undefined} [error] - */ -function bail(error) { - if (error) { - throw error - } -} - -var hasOwn = Object.prototype.hasOwnProperty; -var toStr = Object.prototype.toString; -var defineProperty = Object.defineProperty; -var gOPD = Object.getOwnPropertyDescriptor; - -var isArray = function isArray(arr) { - if (typeof Array.isArray === 'function') { - return Array.isArray(arr); - } - - return toStr.call(arr) === '[object Array]'; -}; - -var isPlainObject = function isPlainObject(obj) { - if (!obj || toStr.call(obj) !== '[object Object]') { - return false; - } - - var hasOwnConstructor = hasOwn.call(obj, 'constructor'); - var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) { /**/ } - - return typeof key === 'undefined' || hasOwn.call(obj, key); -}; - -// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target -var setProperty = function setProperty(target, options) { - if (defineProperty && options.name === '__proto__') { - defineProperty(target, options.name, { - enumerable: true, - configurable: true, - value: options.newValue, - writable: true - }); - } else { - target[options.name] = options.newValue; - } -}; - -// Return undefined instead of __proto__ if '__proto__' is not an own property -var getProperty = function getProperty(obj, name) { - if (name === '__proto__') { - if (!hasOwn.call(obj, name)) { - return void 0; - } else if (gOPD) { - // In early versions of node, obj['__proto__'] is buggy when obj has - // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. - return gOPD(obj, name).value; - } - } - - return obj[name]; -}; - -var extend = function extend() { - var options, name, src, copy, copyIsArray, clone; - var target = arguments[0]; - var i = 1; - var length = arguments.length; - var deep = false; - - // Handle a deep copy situation - if (typeof target === 'boolean') { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { - target = {}; - } - - for (; i < length; ++i) { - options = arguments[i]; - // Only deal with non-null/undefined values - if (options != null) { - // Extend the base object - for (name in options) { - src = getProperty(target, name); - copy = getProperty(options, name); - - // Prevent never-ending loop - if (target !== copy) { - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); - - // Don't bring in undefined values - } else if (typeof copy !== 'undefined') { - setProperty(target, { name: name, newValue: copy }); - } - } - } - } - } - - // Return the modified object - return target; -}; - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('vfile').VFileCompatible} VFileCompatible - * @typedef {import('vfile').VFileValue} VFileValue - * @typedef {import('..').Processor} Processor - * @typedef {import('..').Plugin} Plugin - * @typedef {import('..').Preset} Preset - * @typedef {import('..').Pluggable} Pluggable - * @typedef {import('..').PluggableList} PluggableList - * @typedef {import('..').Transformer} Transformer - * @typedef {import('..').Parser} Parser - * @typedef {import('..').Compiler} Compiler - * @typedef {import('..').RunCallback} RunCallback - * @typedef {import('..').ProcessCallback} ProcessCallback - * - * @typedef Context - * @property {Node} tree - * @property {VFile} file - */ - -// Expose a frozen processor. -const unified = base().freeze(); - -const own$6 = {}.hasOwnProperty; - -// Function to create the first processor. -/** - * @returns {Processor} - */ -function base() { - const transformers = trough(); - /** @type {Processor['attachers']} */ - const attachers = []; - /** @type {Record} */ - let namespace = {}; - /** @type {boolean|undefined} */ - let frozen; - let freezeIndex = -1; - - // Data management. - // @ts-expect-error: overloads are handled. - processor.data = data; - processor.Parser = undefined; - processor.Compiler = undefined; - - // Lock. - processor.freeze = freeze; - - // Plugins. - processor.attachers = attachers; - // @ts-expect-error: overloads are handled. - processor.use = use; - - // API. - processor.parse = parse; - processor.stringify = stringify; - // @ts-expect-error: overloads are handled. - processor.run = run; - processor.runSync = runSync; - // @ts-expect-error: overloads are handled. - processor.process = process; - processor.processSync = processSync; - - // Expose. - return processor - - // Create a new processor based on the processor in the current scope. - /** @type {Processor} */ - function processor() { - const destination = base(); - let index = -1; - - while (++index < attachers.length) { - destination.use(...attachers[index]); - } - - destination.data(extend(true, {}, namespace)); - - return destination - } - - /** - * @param {string|Record} [key] - * @param {unknown} [value] - * @returns {unknown} - */ - function data(key, value) { - if (typeof key === 'string') { - // Set `key`. - if (arguments.length === 2) { - assertUnfrozen('data', frozen); - namespace[key] = value; - return processor - } - - // Get `key`. - return (own$6.call(namespace, key) && namespace[key]) || null - } - - // Set space. - if (key) { - assertUnfrozen('data', frozen); - namespace = key; - return processor - } - - // Get space. - return namespace - } - - /** @type {Processor['freeze']} */ - function freeze() { - if (frozen) { - return processor - } - - while (++freezeIndex < attachers.length) { - const [attacher, ...options] = attachers[freezeIndex]; - - if (options[0] === false) { - continue - } - - if (options[0] === true) { - options[1] = undefined; - } - - /** @type {Transformer|void} */ - const transformer = attacher.call(processor, ...options); - - if (typeof transformer === 'function') { - transformers.use(transformer); - } - } - - frozen = true; - freezeIndex = Number.POSITIVE_INFINITY; - - return processor - } - - /** - * @param {Pluggable|null|undefined} [value] - * @param {...unknown} options - * @returns {Processor} - */ - function use(value, ...options) { - /** @type {Record|undefined} */ - let settings; - - assertUnfrozen('use', frozen); - - if (value === null || value === undefined) ; else if (typeof value === 'function') { - addPlugin(value, ...options); - } else if (typeof value === 'object') { - if (Array.isArray(value)) { - addList(value); - } else { - addPreset(value); - } - } else { - throw new TypeError('Expected usable value, not `' + value + '`') - } - - if (settings) { - namespace.settings = Object.assign(namespace.settings || {}, settings); - } - - return processor - - /** - * @param {import('..').Pluggable} value - * @returns {void} - */ - function add(value) { - if (typeof value === 'function') { - addPlugin(value); - } else if (typeof value === 'object') { - if (Array.isArray(value)) { - const [plugin, ...options] = value; - addPlugin(plugin, ...options); - } else { - addPreset(value); - } - } else { - throw new TypeError('Expected usable value, not `' + value + '`') - } - } - - /** - * @param {Preset} result - * @returns {void} - */ - function addPreset(result) { - addList(result.plugins); - - if (result.settings) { - settings = Object.assign(settings || {}, result.settings); - } - } - - /** - * @param {PluggableList|null|undefined} [plugins] - * @returns {void} - */ - function addList(plugins) { - let index = -1; - - if (plugins === null || plugins === undefined) ; else if (Array.isArray(plugins)) { - while (++index < plugins.length) { - const thing = plugins[index]; - add(thing); - } - } else { - throw new TypeError('Expected a list of plugins, not `' + plugins + '`') - } - } - - /** - * @param {Plugin} plugin - * @param {...unknown} [value] - * @returns {void} - */ - function addPlugin(plugin, value) { - let index = -1; - /** @type {Processor['attachers'][number]|undefined} */ - let entry; - - while (++index < attachers.length) { - if (attachers[index][0] === plugin) { - entry = attachers[index]; - break - } - } - - if (entry) { - if (isPlainObject$1(entry[1]) && isPlainObject$1(value)) { - value = extend(true, entry[1], value); - } - - entry[1] = value; - } else { - // @ts-expect-error: fine. - attachers.push([...arguments]); - } - } - } - - /** @type {Processor['parse']} */ - function parse(doc) { - processor.freeze(); - const file = vfile(doc); - const Parser = processor.Parser; - assertParser('parse', Parser); - - if (newable(Parser, 'parse')) { - // @ts-expect-error: `newable` checks this. - return new Parser(String(file), file).parse() - } - - // @ts-expect-error: `newable` checks this. - return Parser(String(file), file) // eslint-disable-line new-cap - } - - /** @type {Processor['stringify']} */ - function stringify(node, doc) { - processor.freeze(); - const file = vfile(doc); - const Compiler = processor.Compiler; - assertCompiler('stringify', Compiler); - assertNode(node); - - if (newable(Compiler, 'compile')) { - // @ts-expect-error: `newable` checks this. - return new Compiler(node, file).compile() - } - - // @ts-expect-error: `newable` checks this. - return Compiler(node, file) // eslint-disable-line new-cap - } - - /** - * @param {Node} node - * @param {VFileCompatible|RunCallback} [doc] - * @param {RunCallback} [callback] - * @returns {Promise|void} - */ - function run(node, doc, callback) { - assertNode(node); - processor.freeze(); - - if (!callback && typeof doc === 'function') { - callback = doc; - doc = undefined; - } - - if (!callback) { - return new Promise(executor) - } - - executor(null, callback); - - /** - * @param {null|((node: Node) => void)} resolve - * @param {(error: Error) => void} reject - * @returns {void} - */ - function executor(resolve, reject) { - // @ts-expect-error: `doc` can’t be a callback anymore, we checked. - transformers.run(node, vfile(doc), done); - - /** - * @param {Error|null} error - * @param {Node} tree - * @param {VFile} file - * @returns {void} - */ - function done(error, tree, file) { - tree = tree || node; - if (error) { - reject(error); - } else if (resolve) { - resolve(tree); - } else { - // @ts-expect-error: `callback` is defined if `resolve` is not. - callback(null, tree, file); - } - } - } - } - - /** @type {Processor['runSync']} */ - function runSync(node, file) { - /** @type {Node|undefined} */ - let result; - /** @type {boolean|undefined} */ - let complete; - - processor.run(node, file, done); - - assertDone('runSync', 'run', complete); - - // @ts-expect-error: we either bailed on an error or have a tree. - return result - - /** - * @param {Error|null} [error] - * @param {Node} [tree] - * @returns {void} - */ - function done(error, tree) { - bail(error); - result = tree; - complete = true; - } - } - - /** - * @param {VFileCompatible} doc - * @param {ProcessCallback} [callback] - * @returns {Promise|undefined} - */ - function process(doc, callback) { - processor.freeze(); - assertParser('process', processor.Parser); - assertCompiler('process', processor.Compiler); - - if (!callback) { - return new Promise(executor) - } - - executor(null, callback); - - /** - * @param {null|((file: VFile) => void)} resolve - * @param {(error?: Error|null|undefined) => void} reject - * @returns {void} - */ - function executor(resolve, reject) { - const file = vfile(doc); - - processor.run(processor.parse(file), file, (error, tree, file) => { - if (error || !tree || !file) { - done(error); - } else { - /** @type {unknown} */ - const result = processor.stringify(tree, file); - - if (result === undefined || result === null) ; else if (looksLikeAVFileValue(result)) { - file.value = result; - } else { - file.result = result; - } - - done(error, file); - } - }); - - /** - * @param {Error|null|undefined} [error] - * @param {VFile|undefined} [file] - * @returns {void} - */ - function done(error, file) { - if (error || !file) { - reject(error); - } else if (resolve) { - resolve(file); - } else { - // @ts-expect-error: `callback` is defined if `resolve` is not. - callback(null, file); - } - } - } - } - - /** @type {Processor['processSync']} */ - function processSync(doc) { - /** @type {boolean|undefined} */ - let complete; - - processor.freeze(); - assertParser('processSync', processor.Parser); - assertCompiler('processSync', processor.Compiler); - - const file = vfile(doc); - - processor.process(file, done); - - assertDone('processSync', 'process', complete); - - return file - - /** - * @param {Error|null|undefined} [error] - * @returns {void} - */ - function done(error) { - complete = true; - bail(error); - } - } -} - -/** - * Check if `value` is a constructor. - * - * @param {unknown} value - * @param {string} name - * @returns {boolean} - */ -function newable(value, name) { - return ( - typeof value === 'function' && - // Prototypes do exist. - // type-coverage:ignore-next-line - value.prototype && - // A function with keys in its prototype is probably a constructor. - // Classes’ prototype methods are not enumerable, so we check if some value - // exists in the prototype. - // type-coverage:ignore-next-line - (keys(value.prototype) || name in value.prototype) - ) -} - -/** - * Check if `value` is an object with keys. - * - * @param {Record} value - * @returns {boolean} - */ -function keys(value) { - /** @type {string} */ - let key; - - for (key in value) { - if (own$6.call(value, key)) { - return true - } - } - - return false -} - -/** - * Assert a parser is available. - * - * @param {string} name - * @param {unknown} value - * @returns {asserts value is Parser} - */ -function assertParser(name, value) { - if (typeof value !== 'function') { - throw new TypeError('Cannot `' + name + '` without `Parser`') - } -} - -/** - * Assert a compiler is available. - * - * @param {string} name - * @param {unknown} value - * @returns {asserts value is Compiler} - */ -function assertCompiler(name, value) { - if (typeof value !== 'function') { - throw new TypeError('Cannot `' + name + '` without `Compiler`') - } -} - -/** - * Assert the processor is not frozen. - * - * @param {string} name - * @param {unknown} frozen - * @returns {asserts frozen is false} - */ -function assertUnfrozen(name, frozen) { - if (frozen) { - throw new Error( - 'Cannot call `' + - name + - '` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.' - ) - } -} - -/** - * Assert `node` is a unist node. - * - * @param {unknown} node - * @returns {asserts node is Node} - */ -function assertNode(node) { - // `isPlainObj` unfortunately uses `any` instead of `unknown`. - // type-coverage:ignore-next-line - if (!isPlainObject$1(node) || typeof node.type !== 'string') { - throw new TypeError('Expected node, got `' + node + '`') - // Fine. - } -} - -/** - * Assert that `complete` is `true`. - * - * @param {string} name - * @param {string} asyncName - * @param {unknown} complete - * @returns {asserts complete is true} - */ -function assertDone(name, asyncName, complete) { - if (!complete) { - throw new Error( - '`' + name + '` finished async. Use `' + asyncName + '` instead' - ) - } -} - -/** - * @param {VFileCompatible} [value] - * @returns {VFile} - */ -function vfile(value) { - return looksLikeAVFile(value) ? value : new VFile(value) -} - -/** - * @param {VFileCompatible} [value] - * @returns {value is VFile} - */ -function looksLikeAVFile(value) { - return Boolean( - value && - typeof value === 'object' && - 'message' in value && - 'messages' in value - ) -} - -/** - * @param {unknown} [value] - * @returns {value is VFileValue} - */ -function looksLikeAVFileValue(value) { - return typeof value === 'string' || isBuffer(value) -} - -/** - * @typedef Options - * @property {boolean} [includeImageAlt=true] - */ - -/** - * Get the text content of a node. - * Prefer the node’s plain-text fields, otherwise serialize its children, - * and if the given value is an array, serialize the nodes in it. - * - * @param {unknown} node - * @param {Options} [options] - * @returns {string} - */ -function toString(node, options) { - var {includeImageAlt = true} = options || {}; - return one(node, includeImageAlt) -} - -/** - * @param {unknown} node - * @param {boolean} includeImageAlt - * @returns {string} - */ -function one(node, includeImageAlt) { - return ( - (node && - typeof node === 'object' && - // @ts-ignore looks like a literal. - (node.value || - // @ts-ignore looks like an image. - (includeImageAlt ? node.alt : '') || - // @ts-ignore looks like a parent. - ('children' in node && all(node.children, includeImageAlt)) || - (Array.isArray(node) && all(node, includeImageAlt)))) || - '' - ) -} - -/** - * @param {Array.} values - * @param {boolean} includeImageAlt - * @returns {string} - */ -function all(values, includeImageAlt) { - /** @type {Array.} */ - var result = []; - var index = -1; - - while (++index < values.length) { - result[index] = one(values[index], includeImageAlt); - } - - return result.join('') -} - -/** - * Like `Array#splice`, but smarter for giant arrays. - * - * `Array#splice` takes all items to be inserted as individual argument which - * causes a stack overflow in V8 when trying to insert 100k items for instance. - * - * Otherwise, this does not return the removed items, and takes `items` as an - * array instead of rest parameters. - * - * @template {unknown} T - * @param {T[]} list - * @param {number} start - * @param {number} remove - * @param {T[]} items - * @returns {void} - */ -function splice(list, start, remove, items) { - const end = list.length; - let chunkStart = 0; - /** @type {unknown[]} */ - - let parameters; // Make start between zero and `end` (included). - - if (start < 0) { - start = -start > end ? 0 : end + start; - } else { - start = start > end ? end : start; - } - - remove = remove > 0 ? remove : 0; // No need to chunk the items if there’s only a couple (10k) items. - - if (items.length < 10000) { - parameters = Array.from(items); - parameters.unshift(start, remove) // @ts-expect-error Hush, it’s fine. - ;[].splice.apply(list, parameters); - } else { - // Delete `remove` items starting from `start` - if (remove) [].splice.apply(list, [start, remove]); // Insert the items in chunks to not cause stack overflows. - - while (chunkStart < items.length) { - parameters = items.slice(chunkStart, chunkStart + 10000); - parameters.unshift(start, 0) // @ts-expect-error Hush, it’s fine. - ;[].splice.apply(list, parameters); - chunkStart += 10000; - start += 10000; - } - } -} -/** - * Append `items` (an array) at the end of `list` (another array). - * When `list` was empty, returns `items` instead. - * - * This prevents a potentially expensive operation when `list` is empty, - * and adds items in batches to prevent V8 from hanging. - * - * @template {unknown} T - * @param {T[]} list - * @param {T[]} items - * @returns {T[]} - */ - -function push(list, items) { - if (list.length > 0) { - splice(list, list.length, 0, items); - return list - } - - return items -} - -/** - * @typedef {import('micromark-util-types').NormalizedExtension} NormalizedExtension - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -const hasOwnProperty = {}.hasOwnProperty; - -/** - * Combine several syntax extensions into one. - * - * @param {Extension[]} extensions List of syntax extensions. - * @returns {NormalizedExtension} A single combined extension. - */ -function combineExtensions(extensions) { - /** @type {NormalizedExtension} */ - const all = {}; - let index = -1; - - while (++index < extensions.length) { - syntaxExtension(all, extensions[index]); - } - - return all -} - -/** - * Merge `extension` into `all`. - * - * @param {NormalizedExtension} all Extension to merge into. - * @param {Extension} extension Extension to merge. - * @returns {void} - */ -function syntaxExtension(all, extension) { - /** @type {string} */ - let hook; - - for (hook in extension) { - const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; - const left = maybe || (all[hook] = {}); - const right = extension[hook]; - /** @type {string} */ - let code; - - for (code in right) { - if (!hasOwnProperty.call(left, code)) left[code] = []; - const value = right[code]; - constructs( - // @ts-expect-error Looks like a list. - left[code], - Array.isArray(value) ? value : value ? [value] : [] - ); - } - } -} - -/** - * Merge `list` into `existing` (both lists of constructs). - * Mutates `existing`. - * - * @param {unknown[]} existing - * @param {unknown[]} list - * @returns {void} - */ -function constructs(existing, list) { - let index = -1; - /** @type {unknown[]} */ - const before = []; - - while (++index < list.length) { -(list[index].add === 'after' ? existing : before).push(list[index]); - } - - splice(existing, 0, 0, before); -} - -/** - * Combine several HTML extensions into one. - * - * @param {HtmlExtension[]} htmlExtensions List of HTML extensions. - * @returns {HtmlExtension} A single combined extension. - */ -function combineHtmlExtensions(htmlExtensions) { - /** @type {HtmlExtension} */ - const handlers = {}; - let index = -1; - - while (++index < htmlExtensions.length) { - htmlExtension(handlers, htmlExtensions[index]); - } - - return handlers -} - -/** - * Merge `extension` into `all`. - * - * @param {HtmlExtension} all Extension to merge into. - * @param {HtmlExtension} extension Extension to merge. - * @returns {void} - */ -function htmlExtension(all, extension) { - /** @type {string} */ - let hook; - - for (hook in extension) { - const maybe = hasOwnProperty.call(all, hook) ? all[hook] : undefined; - const left = maybe || (all[hook] = {}); - const right = extension[hook]; - /** @type {string} */ - let type; - - if (right) { - for (type in right) { - left[type] = right[type]; - } - } - } -} - -// This module is generated by `script/`. -// -// CommonMark handles attention (emphasis, strong) markers based on what comes -// before or after them. -// One such difference is if those characters are Unicode punctuation. -// This script is generated from the Unicode data. -const unicodePunctuationRegex = - /[!-/:-@[-`{-~\u00A1\u00A7\u00AB\u00B6\u00B7\u00BB\u00BF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061E\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]/; - -/** - * @typedef {import('micromark-util-types').Code} Code - */ -/** - * Check whether the character code represents an ASCII alpha (`a` through `z`, - * case insensitive). - * - * An **ASCII alpha** is an ASCII upper alpha or ASCII lower alpha. - * - * An **ASCII upper alpha** is a character in the inclusive range U+0041 (`A`) - * to U+005A (`Z`). - * - * An **ASCII lower alpha** is a character in the inclusive range U+0061 (`a`) - * to U+007A (`z`). - */ - -const asciiAlpha = regexCheck(/[A-Za-z]/); -/** - * Check whether the character code represents an ASCII digit (`0` through `9`). - * - * An **ASCII digit** is a character in the inclusive range U+0030 (`0`) to - * U+0039 (`9`). - */ - -const asciiDigit = regexCheck(/\d/); -/** - * Check whether the character code represents an ASCII hex digit (`a` through - * `f`, case insensitive, or `0` through `9`). - * - * An **ASCII hex digit** is an ASCII digit (see `asciiDigit`), ASCII upper hex - * digit, or an ASCII lower hex digit. - * - * An **ASCII upper hex digit** is a character in the inclusive range U+0041 - * (`A`) to U+0046 (`F`). - * - * An **ASCII lower hex digit** is a character in the inclusive range U+0061 - * (`a`) to U+0066 (`f`). - */ - -const asciiHexDigit = regexCheck(/[\dA-Fa-f]/); -/** - * Check whether the character code represents an ASCII alphanumeric (`a` - * through `z`, case insensitive, or `0` through `9`). - * - * An **ASCII alphanumeric** is an ASCII digit (see `asciiDigit`) or ASCII alpha - * (see `asciiAlpha`). - */ - -const asciiAlphanumeric = regexCheck(/[\dA-Za-z]/); -/** - * Check whether the character code represents ASCII punctuation. - * - * An **ASCII punctuation** is a character in the inclusive ranges U+0021 - * EXCLAMATION MARK (`!`) to U+002F SLASH (`/`), U+003A COLON (`:`) to U+0040 AT - * SIGN (`@`), U+005B LEFT SQUARE BRACKET (`[`) to U+0060 GRAVE ACCENT - * (`` ` ``), or U+007B LEFT CURLY BRACE (`{`) to U+007E TILDE (`~`). - */ - -const asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/); -/** - * Check whether the character code represents an ASCII atext. - * - * atext is an ASCII alphanumeric (see `asciiAlphanumeric`), or a character in - * the inclusive ranges U+0023 NUMBER SIGN (`#`) to U+0027 APOSTROPHE (`'`), - * U+002A ASTERISK (`*`), U+002B PLUS SIGN (`+`), U+002D DASH (`-`), U+002F - * SLASH (`/`), U+003D EQUALS TO (`=`), U+003F QUESTION MARK (`?`), U+005E - * CARET (`^`) to U+0060 GRAVE ACCENT (`` ` ``), or U+007B LEFT CURLY BRACE - * (`{`) to U+007E TILDE (`~`). - * - * See: - * **\[RFC5322]**: - * [Internet Message Format](https://tools.ietf.org/html/rfc5322). - * P. Resnick. - * IETF. - */ - -const asciiAtext = regexCheck(/[#-'*+\--9=?A-Z^-~]/); -/** - * Check whether a character code is an ASCII control character. - * - * An **ASCII control** is a character in the inclusive range U+0000 NULL (NUL) - * to U+001F (US), or U+007F (DEL). - * - * @param {Code} code - * @returns {code is number} - */ - -function asciiControl(code) { - return ( - // Special whitespace codes (which have negative values), C0 and Control - // character DEL - code !== null && (code < 32 || code === 127) - ) -} -/** - * Check whether a character code is a markdown line ending (see - * `markdownLineEnding`) or markdown space (see `markdownSpace`). - * - * @param {Code} code - * @returns {code is number} - */ - -function markdownLineEndingOrSpace(code) { - return code !== null && (code < 0 || code === 32) -} -/** - * Check whether a character code is a markdown line ending. - * - * A **markdown line ending** is the virtual characters M-0003 CARRIAGE RETURN - * LINE FEED (CRLF), M-0004 LINE FEED (LF) and M-0005 CARRIAGE RETURN (CR). - * - * In micromark, the actual character U+000A LINE FEED (LF) and U+000D CARRIAGE - * RETURN (CR) are replaced by these virtual characters depending on whether - * they occurred together. - * - * @param {Code} code - * @returns {code is number} - */ - -function markdownLineEnding(code) { - return code !== null && code < -2 -} -/** - * Check whether a character code is a markdown space. - * - * A **markdown space** is the concrete character U+0020 SPACE (SP) and the - * virtual characters M-0001 VIRTUAL SPACE (VS) and M-0002 HORIZONTAL TAB (HT). - * - * In micromark, the actual character U+0009 CHARACTER TABULATION (HT) is - * replaced by one M-0002 HORIZONTAL TAB (HT) and between 0 and 3 M-0001 VIRTUAL - * SPACE (VS) characters, depending on the column at which the tab occurred. - * - * @param {Code} code - * @returns {code is number} - */ - -function markdownSpace(code) { - return code === -2 || code === -1 || code === 32 -} -/** - * Check whether the character code represents Unicode whitespace. - * - * Note that this does handle micromark specific markdown whitespace characters. - * See `markdownLineEndingOrSpace` to check that. - * - * A **Unicode whitespace** is a character in the Unicode `Zs` (Separator, - * Space) category, or U+0009 CHARACTER TABULATION (HT), U+000A LINE FEED (LF), - * U+000C (FF), or U+000D CARRIAGE RETURN (CR) (**\[UNICODE]**). - * - * See: - * **\[UNICODE]**: - * [The Unicode Standard](https://www.unicode.org/versions/). - * Unicode Consortium. - */ - -const unicodeWhitespace = regexCheck(/\s/); -/** - * Check whether the character code represents Unicode punctuation. - * - * A **Unicode punctuation** is a character in the Unicode `Pc` (Punctuation, - * Connector), `Pd` (Punctuation, Dash), `Pe` (Punctuation, Close), `Pf` - * (Punctuation, Final quote), `Pi` (Punctuation, Initial quote), `Po` - * (Punctuation, Other), or `Ps` (Punctuation, Open) categories, or an ASCII - * punctuation (see `asciiPunctuation`). - * - * See: - * **\[UNICODE]**: - * [The Unicode Standard](https://www.unicode.org/versions/). - * Unicode Consortium. - */ -// Size note: removing ASCII from the regex and using `asciiPunctuation` here -// In fact adds to the bundle size. - -const unicodePunctuation = regexCheck(unicodePunctuationRegex); -/** - * Create a code check from a regex. - * - * @param {RegExp} regex - * @returns {(code: Code) => code is number} - */ - -function regexCheck(regex) { - return check - /** - * Check whether a code matches the bound regex. - * - * @param {Code} code Character code - * @returns {code is number} Whether the character code matches the bound regex - */ - - function check(code) { - return code !== null && regex.test(String.fromCharCode(code)) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - */ -/** - * @param {Effects} effects - * @param {State} ok - * @param {string} type - * @param {number} [max=Infinity] - * @returns {State} - */ - -function factorySpace(effects, ok, type, max) { - const limit = max ? max - 1 : Number.POSITIVE_INFINITY; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - if (markdownSpace(code)) { - effects.enter(type); - return prefix(code) - } - - return ok(code) - } - /** @type {State} */ - - function prefix(code) { - if (markdownSpace(code) && size++ < limit) { - effects.consume(code); - return prefix - } - - effects.exit(type); - return ok(code) - } -} - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {InitialConstruct} */ -const content$1 = { - tokenize: initializeContent -}; -/** @type {Initializer} */ - -function initializeContent(effects) { - const contentStart = effects.attempt( - this.parser.constructs.contentInitial, - afterContentStartConstruct, - paragraphInitial - ); - /** @type {Token} */ - - let previous; - return contentStart - /** @type {State} */ - - function afterContentStartConstruct(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, contentStart, 'linePrefix') - } - /** @type {State} */ - - function paragraphInitial(code) { - effects.enter('paragraph'); - return lineStart(code) - } - /** @type {State} */ - - function lineStart(code) { - const token = effects.enter('chunkText', { - contentType: 'text', - previous - }); - - if (previous) { - previous.next = token; - } - - previous = token; - return data(code) - } - /** @type {State} */ - - function data(code) { - if (code === null) { - effects.exit('chunkText'); - effects.exit('paragraph'); - effects.consume(code); - return - } - - if (markdownLineEnding(code)) { - effects.consume(code); - effects.exit('chunkText'); - return lineStart - } // Data. - - effects.consume(code); - return data - } -} - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Point} Point - */ -/** @type {InitialConstruct} */ - -const document$2 = { - tokenize: initializeDocument -}; -/** @type {Construct} */ - -const containerConstruct = { - tokenize: tokenizeContainer -}; -/** @type {Initializer} */ - -function initializeDocument(effects) { - const self = this; - /** @type {StackItem[]} */ - - const stack = []; - let continued = 0; - /** @type {TokenizeContext|undefined} */ - - let childFlow; - /** @type {Token|undefined} */ - - let childToken; - /** @type {number} */ - - let lineStartOffset; - return start - /** @type {State} */ - - function start(code) { - // First we iterate through the open blocks, starting with the root - // document, and descending through last children down to the last open - // block. - // Each block imposes a condition that the line must satisfy if the block is - // to remain open. - // For example, a block quote requires a `>` character. - // A paragraph requires a non-blank line. - // In this phase we may match all or just some of the open blocks. - // But we cannot close unmatched blocks yet, because we may have a lazy - // continuation line. - if (continued < stack.length) { - const item = stack[continued]; - self.containerState = item[1]; - return effects.attempt( - item[0].continuation, - documentContinue, - checkNewContainers - )(code) - } // Done. - - return checkNewContainers(code) - } - /** @type {State} */ - - function documentContinue(code) { - continued++; // Note: this field is called `_closeFlow` but it also closes containers. - // Perhaps a good idea to rename it but it’s already used in the wild by - // extensions. - - if (self.containerState._closeFlow) { - self.containerState._closeFlow = undefined; - - if (childFlow) { - closeFlow(); - } // Note: this algorithm for moving events around is similar to the - // algorithm when dealing with lazy lines in `writeToChild`. - - const indexBeforeExits = self.events.length; - let indexBeforeFlow = indexBeforeExits; - /** @type {Point|undefined} */ - - let point; // Find the flow chunk. - - while (indexBeforeFlow--) { - if ( - self.events[indexBeforeFlow][0] === 'exit' && - self.events[indexBeforeFlow][1].type === 'chunkFlow' - ) { - point = self.events[indexBeforeFlow][1].end; - break - } - } - - exitContainers(continued); // Fix positions. - - let index = indexBeforeExits; - - while (index < self.events.length) { - self.events[index][1].end = Object.assign({}, point); - index++; - } // Inject the exits earlier (they’re still also at the end). - - splice( - self.events, - indexBeforeFlow + 1, - 0, - self.events.slice(indexBeforeExits) - ); // Discard the duplicate exits. - - self.events.length = index; - return checkNewContainers(code) - } - - return start(code) - } - /** @type {State} */ - - function checkNewContainers(code) { - // Next, after consuming the continuation markers for existing blocks, we - // look for new block starts (e.g. `>` for a block quote). - // If we encounter a new block start, we close any blocks unmatched in - // step 1 before creating the new block as a child of the last matched - // block. - if (continued === stack.length) { - // No need to `check` whether there’s a container, of `exitContainers` - // would be moot. - // We can instead immediately `attempt` to parse one. - if (!childFlow) { - return documentContinued(code) - } // If we have concrete content, such as block HTML or fenced code, - // we can’t have containers “pierce” into them, so we can immediately - // start. - - if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) { - return flowStart(code) - } // If we do have flow, it could still be a blank line, - // but we’d be interrupting it w/ a new container if there’s a current - // construct. - - self.interrupt = Boolean(childFlow.currentConstruct); - } // Check if there is a new container. - - self.containerState = {}; - return effects.check( - containerConstruct, - thereIsANewContainer, - thereIsNoNewContainer - )(code) - } - /** @type {State} */ - - function thereIsANewContainer(code) { - if (childFlow) closeFlow(); - exitContainers(continued); - return documentContinued(code) - } - /** @type {State} */ - - function thereIsNoNewContainer(code) { - self.parser.lazy[self.now().line] = continued !== stack.length; - lineStartOffset = self.now().offset; - return flowStart(code) - } - /** @type {State} */ - - function documentContinued(code) { - // Try new containers. - self.containerState = {}; - return effects.attempt( - containerConstruct, - containerContinue, - flowStart - )(code) - } - /** @type {State} */ - - function containerContinue(code) { - continued++; - stack.push([self.currentConstruct, self.containerState]); // Try another. - - return documentContinued(code) - } - /** @type {State} */ - - function flowStart(code) { - if (code === null) { - if (childFlow) closeFlow(); - exitContainers(0); - effects.consume(code); - return - } - - childFlow = childFlow || self.parser.flow(self.now()); - effects.enter('chunkFlow', { - contentType: 'flow', - previous: childToken, - _tokenizer: childFlow - }); - return flowContinue(code) - } - /** @type {State} */ - - function flowContinue(code) { - if (code === null) { - writeToChild(effects.exit('chunkFlow'), true); - exitContainers(0); - effects.consume(code); - return - } - - if (markdownLineEnding(code)) { - effects.consume(code); - writeToChild(effects.exit('chunkFlow')); // Get ready for the next line. - - continued = 0; - self.interrupt = undefined; - return start - } - - effects.consume(code); - return flowContinue - } - /** - * @param {Token} token - * @param {boolean} [eof] - * @returns {void} - */ - - function writeToChild(token, eof) { - const stream = self.sliceStream(token); - if (eof) stream.push(null); - token.previous = childToken; - if (childToken) childToken.next = token; - childToken = token; - childFlow.defineSkip(token.start); - childFlow.write(stream); // Alright, so we just added a lazy line: - // - // ```markdown - // > a - // b. - // - // Or: - // - // > ~~~c - // d - // - // Or: - // - // > | e | - // f - // ``` - // - // The construct in the second example (fenced code) does not accept lazy - // lines, so it marked itself as done at the end of its first line, and - // then the content construct parses `d`. - // Most constructs in markdown match on the first line: if the first line - // forms a construct, a non-lazy line can’t “unmake” it. - // - // The construct in the third example is potentially a GFM table, and - // those are *weird*. - // It *could* be a table, from the first line, if the following line - // matches a condition. - // In this case, that second line is lazy, which “unmakes” the first line - // and turns the whole into one content block. - // - // We’ve now parsed the non-lazy and the lazy line, and can figure out - // whether the lazy line started a new flow block. - // If it did, we exit the current containers between the two flow blocks. - - if (self.parser.lazy[token.start.line]) { - let index = childFlow.events.length; - - while (index--) { - if ( - // The token starts before the line ending… - childFlow.events[index][1].start.offset < lineStartOffset && - (!childFlow.events[index][1].end || // …or ends after it. - childFlow.events[index][1].end.offset > lineStartOffset) - ) { - // Exit: there’s still something open, which means it’s a lazy line - // part of something. - return - } - } // Note: this algorithm for moving events around is similar to the - // algorithm when closing flow in `documentContinue`. - - const indexBeforeExits = self.events.length; - let indexBeforeFlow = indexBeforeExits; - /** @type {boolean|undefined} */ - - let seen; - /** @type {Point|undefined} */ - - let point; // Find the previous chunk (the one before the lazy line). - - while (indexBeforeFlow--) { - if ( - self.events[indexBeforeFlow][0] === 'exit' && - self.events[indexBeforeFlow][1].type === 'chunkFlow' - ) { - if (seen) { - point = self.events[indexBeforeFlow][1].end; - break - } - - seen = true; - } - } - - exitContainers(continued); // Fix positions. - - index = indexBeforeExits; - - while (index < self.events.length) { - self.events[index][1].end = Object.assign({}, point); - index++; - } // Inject the exits earlier (they’re still also at the end). - - splice( - self.events, - indexBeforeFlow + 1, - 0, - self.events.slice(indexBeforeExits) - ); // Discard the duplicate exits. - - self.events.length = index; - } - } - /** - * @param {number} size - * @returns {void} - */ - - function exitContainers(size) { - let index = stack.length; // Exit open containers. - - while (index-- > size) { - const entry = stack[index]; - self.containerState = entry[1]; - entry[0].exit.call(self, effects); - } - - stack.length = size; - } - - function closeFlow() { - childFlow.write([null]); - childToken = undefined; - childFlow = undefined; - self.containerState._closeFlow = undefined; - } -} -/** @type {Tokenizer} */ - -function tokenizeContainer(effects, ok, nok) { - return factorySpace( - effects, - effects.attempt(this.parser.constructs.document, ok, nok), - 'linePrefix', - this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 - ) -} - -/** - * @typedef {import('micromark-util-types').Code} Code - */ - -/** - * Classify whether a character code represents whitespace, punctuation, or - * something else. - * - * Used for attention (emphasis, strong), whose sequences can open or close - * based on the class of surrounding characters. - * - * Note that eof (`null`) is seen as whitespace. - * - * @param {Code} code - * @returns {number|undefined} - */ -function classifyCharacter(code) { - if ( - code === null || - markdownLineEndingOrSpace(code) || - unicodeWhitespace(code) - ) { - return 1 - } - - if (unicodePunctuation(code)) { - return 2 - } -} - -/** - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Resolver} Resolver - */ - -/** - * Call all `resolveAll`s. - * - * @param {{resolveAll?: Resolver}[]} constructs - * @param {Event[]} events - * @param {TokenizeContext} context - * @returns {Event[]} - */ -function resolveAll(constructs, events, context) { - /** @type {Resolver[]} */ - const called = []; - let index = -1; - - while (++index < constructs.length) { - const resolve = constructs[index].resolveAll; - - if (resolve && !called.includes(resolve)) { - events = resolve(events, context); - called.push(resolve); - } - } - - return events -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Code} Code - * @typedef {import('micromark-util-types').Point} Point - */ - -/** @type {Construct} */ -const attention = { - name: 'attention', - tokenize: tokenizeAttention, - resolveAll: resolveAllAttention -}; -/** - * Take all events and resolve attention to emphasis or strong. - * - * @type {Resolver} - */ - -function resolveAllAttention(events, context) { - let index = -1; - /** @type {number} */ - - let open; - /** @type {Token} */ - - let group; - /** @type {Token} */ - - let text; - /** @type {Token} */ - - let openingSequence; - /** @type {Token} */ - - let closingSequence; - /** @type {number} */ - - let use; - /** @type {Event[]} */ - - let nextEvents; - /** @type {number} */ - - let offset; // Walk through all events. - // - // Note: performance of this is fine on an mb of normal markdown, but it’s - // a bottleneck for malicious stuff. - - while (++index < events.length) { - // Find a token that can close. - if ( - events[index][0] === 'enter' && - events[index][1].type === 'attentionSequence' && - events[index][1]._close - ) { - open = index; // Now walk back to find an opener. - - while (open--) { - // Find a token that can open the closer. - if ( - events[open][0] === 'exit' && - events[open][1].type === 'attentionSequence' && - events[open][1]._open && // If the markers are the same: - context.sliceSerialize(events[open][1]).charCodeAt(0) === - context.sliceSerialize(events[index][1]).charCodeAt(0) - ) { - // If the opening can close or the closing can open, - // and the close size *is not* a multiple of three, - // but the sum of the opening and closing size *is* multiple of three, - // then don’t match. - if ( - (events[open][1]._close || events[index][1]._open) && - (events[index][1].end.offset - events[index][1].start.offset) % 3 && - !( - (events[open][1].end.offset - - events[open][1].start.offset + - events[index][1].end.offset - - events[index][1].start.offset) % - 3 - ) - ) { - continue - } // Number of markers to use from the sequence. - - use = - events[open][1].end.offset - events[open][1].start.offset > 1 && - events[index][1].end.offset - events[index][1].start.offset > 1 - ? 2 - : 1; - const start = Object.assign({}, events[open][1].end); - const end = Object.assign({}, events[index][1].start); - movePoint(start, -use); - movePoint(end, use); - openingSequence = { - type: use > 1 ? 'strongSequence' : 'emphasisSequence', - start, - end: Object.assign({}, events[open][1].end) - }; - closingSequence = { - type: use > 1 ? 'strongSequence' : 'emphasisSequence', - start: Object.assign({}, events[index][1].start), - end - }; - text = { - type: use > 1 ? 'strongText' : 'emphasisText', - start: Object.assign({}, events[open][1].end), - end: Object.assign({}, events[index][1].start) - }; - group = { - type: use > 1 ? 'strong' : 'emphasis', - start: Object.assign({}, openingSequence.start), - end: Object.assign({}, closingSequence.end) - }; - events[open][1].end = Object.assign({}, openingSequence.start); - events[index][1].start = Object.assign({}, closingSequence.end); - nextEvents = []; // If there are more markers in the opening, add them before. - - if (events[open][1].end.offset - events[open][1].start.offset) { - nextEvents = push(nextEvents, [ - ['enter', events[open][1], context], - ['exit', events[open][1], context] - ]); - } // Opening. - - nextEvents = push(nextEvents, [ - ['enter', group, context], - ['enter', openingSequence, context], - ['exit', openingSequence, context], - ['enter', text, context] - ]); // Between. - - nextEvents = push( - nextEvents, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + 1, index), - context - ) - ); // Closing. - - nextEvents = push(nextEvents, [ - ['exit', text, context], - ['enter', closingSequence, context], - ['exit', closingSequence, context], - ['exit', group, context] - ]); // If there are more markers in the closing, add them after. - - if (events[index][1].end.offset - events[index][1].start.offset) { - offset = 2; - nextEvents = push(nextEvents, [ - ['enter', events[index][1], context], - ['exit', events[index][1], context] - ]); - } else { - offset = 0; - } - - splice(events, open - 1, index - open + 3, nextEvents); - index = open + nextEvents.length - offset - 2; - break - } - } - } - } // Remove remaining sequences. - - index = -1; - - while (++index < events.length) { - if (events[index][1].type === 'attentionSequence') { - events[index][1].type = 'data'; - } - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeAttention(effects, ok) { - const attentionMarkers = this.parser.constructs.attentionMarkers.null; - const previous = this.previous; - const before = classifyCharacter(previous); - /** @type {NonNullable} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('attentionSequence'); - marker = code; - return sequence(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === marker) { - effects.consume(code); - return sequence - } - - const token = effects.exit('attentionSequence'); - const after = classifyCharacter(code); - const open = - !after || (after === 2 && before) || attentionMarkers.includes(code); - const close = - !before || (before === 2 && after) || attentionMarkers.includes(previous); - token._open = Boolean(marker === 42 ? open : open && (before || !close)); - token._close = Boolean(marker === 42 ? close : close && (after || !open)); - return ok(code) - } -} -/** - * Move a point a bit. - * - * Note: `move` only works inside lines! It’s not possible to move past other - * chunks (replacement characters, tabs, or line endings). - * - * @param {Point} point - * @param {number} offset - * @returns {void} - */ - -function movePoint(point, offset) { - point.column += offset; - point.offset += offset; - point._bufferIndex += offset; -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const autolink = { - name: 'autolink', - tokenize: tokenizeAutolink -}; -/** @type {Tokenizer} */ - -function tokenizeAutolink(effects, ok, nok) { - let size = 1; - return start - /** @type {State} */ - - function start(code) { - effects.enter('autolink'); - effects.enter('autolinkMarker'); - effects.consume(code); - effects.exit('autolinkMarker'); - effects.enter('autolinkProtocol'); - return open - } - /** @type {State} */ - - function open(code) { - if (asciiAlpha(code)) { - effects.consume(code); - return schemeOrEmailAtext - } - - return asciiAtext(code) ? emailAtext(code) : nok(code) - } - /** @type {State} */ - - function schemeOrEmailAtext(code) { - return code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code) - ? schemeInsideOrEmailAtext(code) - : emailAtext(code) - } - /** @type {State} */ - - function schemeInsideOrEmailAtext(code) { - if (code === 58) { - effects.consume(code); - return urlInside - } - - if ( - (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && - size++ < 32 - ) { - effects.consume(code); - return schemeInsideOrEmailAtext - } - - return emailAtext(code) - } - /** @type {State} */ - - function urlInside(code) { - if (code === 62) { - effects.exit('autolinkProtocol'); - return end(code) - } - - if (code === null || code === 32 || code === 60 || asciiControl(code)) { - return nok(code) - } - - effects.consume(code); - return urlInside - } - /** @type {State} */ - - function emailAtext(code) { - if (code === 64) { - effects.consume(code); - size = 0; - return emailAtSignOrDot - } - - if (asciiAtext(code)) { - effects.consume(code); - return emailAtext - } - - return nok(code) - } - /** @type {State} */ - - function emailAtSignOrDot(code) { - return asciiAlphanumeric(code) ? emailLabel(code) : nok(code) - } - /** @type {State} */ - - function emailLabel(code) { - if (code === 46) { - effects.consume(code); - size = 0; - return emailAtSignOrDot - } - - if (code === 62) { - // Exit, then change the type. - effects.exit('autolinkProtocol').type = 'autolinkEmail'; - return end(code) - } - - return emailValue(code) - } - /** @type {State} */ - - function emailValue(code) { - if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) { - effects.consume(code); - return code === 45 ? emailValue : emailLabel - } - - return nok(code) - } - /** @type {State} */ - - function end(code) { - effects.enter('autolinkMarker'); - effects.consume(code); - effects.exit('autolinkMarker'); - effects.exit('autolink'); - return ok - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const blankLine = { - tokenize: tokenizeBlankLine, - partial: true -}; -/** @type {Tokenizer} */ - -function tokenizeBlankLine(effects, ok, nok) { - return factorySpace(effects, afterWhitespace, 'linePrefix') - /** @type {State} */ - - function afterWhitespace(code) { - return code === null || markdownLineEnding(code) ? ok(code) : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Exiter} Exiter - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const blockQuote = { - name: 'blockQuote', - tokenize: tokenizeBlockQuoteStart, - continuation: { - tokenize: tokenizeBlockQuoteContinuation - }, - exit: exit$1 -}; -/** @type {Tokenizer} */ - -function tokenizeBlockQuoteStart(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - if (code === 62) { - const state = self.containerState; - - if (!state.open) { - effects.enter('blockQuote', { - _container: true - }); - state.open = true; - } - - effects.enter('blockQuotePrefix'); - effects.enter('blockQuoteMarker'); - effects.consume(code); - effects.exit('blockQuoteMarker'); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - if (markdownSpace(code)) { - effects.enter('blockQuotePrefixWhitespace'); - effects.consume(code); - effects.exit('blockQuotePrefixWhitespace'); - effects.exit('blockQuotePrefix'); - return ok - } - - effects.exit('blockQuotePrefix'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeBlockQuoteContinuation(effects, ok, nok) { - return factorySpace( - effects, - effects.attempt(blockQuote, ok, nok), - 'linePrefix', - this.parser.constructs.disable.null.includes('codeIndented') ? undefined : 4 - ) -} -/** @type {Exiter} */ - -function exit$1(effects) { - effects.exit('blockQuote'); -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const characterEscape$1 = { - name: 'characterEscape', - tokenize: tokenizeCharacterEscape -}; -/** @type {Tokenizer} */ - -function tokenizeCharacterEscape(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('characterEscape'); - effects.enter('escapeMarker'); - effects.consume(code); - effects.exit('escapeMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (asciiPunctuation(code)) { - effects.enter('characterEscapeValue'); - effects.consume(code); - effects.exit('characterEscapeValue'); - effects.exit('characterEscape'); - return ok - } - - return nok(code) - } -} - -var characterEntities = { - AEli: 'Æ', - AElig: 'Æ', - AM: '&', - AMP: '&', - Aacut: 'Á', - Aacute: 'Á', - Abreve: 'Ă', - Acir: 'Â', - Acirc: 'Â', - Acy: 'А', - Afr: '𝔄', - Agrav: 'À', - Agrave: 'À', - Alpha: 'Α', - Amacr: 'Ā', - And: '⩓', - Aogon: 'Ą', - Aopf: '𝔸', - ApplyFunction: '⁡', - Arin: 'Å', - Aring: 'Å', - Ascr: '𝒜', - Assign: '≔', - Atild: 'Ã', - Atilde: 'Ã', - Aum: 'Ä', - Auml: 'Ä', - Backslash: '∖', - Barv: '⫧', - Barwed: '⌆', - Bcy: 'Б', - Because: '∵', - Bernoullis: 'ℬ', - Beta: 'Β', - Bfr: '𝔅', - Bopf: '𝔹', - Breve: '˘', - Bscr: 'ℬ', - Bumpeq: '≎', - CHcy: 'Ч', - COP: '©', - COPY: '©', - Cacute: 'Ć', - Cap: '⋒', - CapitalDifferentialD: 'ⅅ', - Cayleys: 'ℭ', - Ccaron: 'Č', - Ccedi: 'Ç', - Ccedil: 'Ç', - Ccirc: 'Ĉ', - Cconint: '∰', - Cdot: 'Ċ', - Cedilla: '¸', - CenterDot: '·', - Cfr: 'ℭ', - Chi: 'Χ', - CircleDot: '⊙', - CircleMinus: '⊖', - CirclePlus: '⊕', - CircleTimes: '⊗', - ClockwiseContourIntegral: '∲', - CloseCurlyDoubleQuote: '”', - CloseCurlyQuote: '’', - Colon: '∷', - Colone: '⩴', - Congruent: '≡', - Conint: '∯', - ContourIntegral: '∮', - Copf: 'ℂ', - Coproduct: '∐', - CounterClockwiseContourIntegral: '∳', - Cross: '⨯', - Cscr: '𝒞', - Cup: '⋓', - CupCap: '≍', - DD: 'ⅅ', - DDotrahd: '⤑', - DJcy: 'Ђ', - DScy: 'Ѕ', - DZcy: 'Џ', - Dagger: '‡', - Darr: '↡', - Dashv: '⫤', - Dcaron: 'Ď', - Dcy: 'Д', - Del: '∇', - Delta: 'Δ', - Dfr: '𝔇', - DiacriticalAcute: '´', - DiacriticalDot: '˙', - DiacriticalDoubleAcute: '˝', - DiacriticalGrave: '`', - DiacriticalTilde: '˜', - Diamond: '⋄', - DifferentialD: 'ⅆ', - Dopf: '𝔻', - Dot: '¨', - DotDot: '⃜', - DotEqual: '≐', - DoubleContourIntegral: '∯', - DoubleDot: '¨', - DoubleDownArrow: '⇓', - DoubleLeftArrow: '⇐', - DoubleLeftRightArrow: '⇔', - DoubleLeftTee: '⫤', - DoubleLongLeftArrow: '⟸', - DoubleLongLeftRightArrow: '⟺', - DoubleLongRightArrow: '⟹', - DoubleRightArrow: '⇒', - DoubleRightTee: '⊨', - DoubleUpArrow: '⇑', - DoubleUpDownArrow: '⇕', - DoubleVerticalBar: '∥', - DownArrow: '↓', - DownArrowBar: '⤓', - DownArrowUpArrow: '⇵', - DownBreve: '̑', - DownLeftRightVector: '⥐', - DownLeftTeeVector: '⥞', - DownLeftVector: '↽', - DownLeftVectorBar: '⥖', - DownRightTeeVector: '⥟', - DownRightVector: '⇁', - DownRightVectorBar: '⥗', - DownTee: '⊤', - DownTeeArrow: '↧', - Downarrow: '⇓', - Dscr: '𝒟', - Dstrok: 'Đ', - ENG: 'Ŋ', - ET: 'Ð', - ETH: 'Ð', - Eacut: 'É', - Eacute: 'É', - Ecaron: 'Ě', - Ecir: 'Ê', - Ecirc: 'Ê', - Ecy: 'Э', - Edot: 'Ė', - Efr: '𝔈', - Egrav: 'È', - Egrave: 'È', - Element: '∈', - Emacr: 'Ē', - EmptySmallSquare: '◻', - EmptyVerySmallSquare: '▫', - Eogon: 'Ę', - Eopf: '𝔼', - Epsilon: 'Ε', - Equal: '⩵', - EqualTilde: '≂', - Equilibrium: '⇌', - Escr: 'ℰ', - Esim: '⩳', - Eta: 'Η', - Eum: 'Ë', - Euml: 'Ë', - Exists: '∃', - ExponentialE: 'ⅇ', - Fcy: 'Ф', - Ffr: '𝔉', - FilledSmallSquare: '◼', - FilledVerySmallSquare: '▪', - Fopf: '𝔽', - ForAll: '∀', - Fouriertrf: 'ℱ', - Fscr: 'ℱ', - GJcy: 'Ѓ', - G: '>', - GT: '>', - Gamma: 'Γ', - Gammad: 'Ϝ', - Gbreve: 'Ğ', - Gcedil: 'Ģ', - Gcirc: 'Ĝ', - Gcy: 'Г', - Gdot: 'Ġ', - Gfr: '𝔊', - Gg: '⋙', - Gopf: '𝔾', - GreaterEqual: '≥', - GreaterEqualLess: '⋛', - GreaterFullEqual: '≧', - GreaterGreater: '⪢', - GreaterLess: '≷', - GreaterSlantEqual: '⩾', - GreaterTilde: '≳', - Gscr: '𝒢', - Gt: '≫', - HARDcy: 'Ъ', - Hacek: 'ˇ', - Hat: '^', - Hcirc: 'Ĥ', - Hfr: 'ℌ', - HilbertSpace: 'ℋ', - Hopf: 'ℍ', - HorizontalLine: '─', - Hscr: 'ℋ', - Hstrok: 'Ħ', - HumpDownHump: '≎', - HumpEqual: '≏', - IEcy: 'Е', - IJlig: 'IJ', - IOcy: 'Ё', - Iacut: 'Í', - Iacute: 'Í', - Icir: 'Î', - Icirc: 'Î', - Icy: 'И', - Idot: 'İ', - Ifr: 'ℑ', - Igrav: 'Ì', - Igrave: 'Ì', - Im: 'ℑ', - Imacr: 'Ī', - ImaginaryI: 'ⅈ', - Implies: '⇒', - Int: '∬', - Integral: '∫', - Intersection: '⋂', - InvisibleComma: '⁣', - InvisibleTimes: '⁢', - Iogon: 'Į', - Iopf: '𝕀', - Iota: 'Ι', - Iscr: 'ℐ', - Itilde: 'Ĩ', - Iukcy: 'І', - Ium: 'Ï', - Iuml: 'Ï', - Jcirc: 'Ĵ', - Jcy: 'Й', - Jfr: '𝔍', - Jopf: '𝕁', - Jscr: '𝒥', - Jsercy: 'Ј', - Jukcy: 'Є', - KHcy: 'Х', - KJcy: 'Ќ', - Kappa: 'Κ', - Kcedil: 'Ķ', - Kcy: 'К', - Kfr: '𝔎', - Kopf: '𝕂', - Kscr: '𝒦', - LJcy: 'Љ', - L: '<', - LT: '<', - Lacute: 'Ĺ', - Lambda: 'Λ', - Lang: '⟪', - Laplacetrf: 'ℒ', - Larr: '↞', - Lcaron: 'Ľ', - Lcedil: 'Ļ', - Lcy: 'Л', - LeftAngleBracket: '⟨', - LeftArrow: '←', - LeftArrowBar: '⇤', - LeftArrowRightArrow: '⇆', - LeftCeiling: '⌈', - LeftDoubleBracket: '⟦', - LeftDownTeeVector: '⥡', - LeftDownVector: '⇃', - LeftDownVectorBar: '⥙', - LeftFloor: '⌊', - LeftRightArrow: '↔', - LeftRightVector: '⥎', - LeftTee: '⊣', - LeftTeeArrow: '↤', - LeftTeeVector: '⥚', - LeftTriangle: '⊲', - LeftTriangleBar: '⧏', - LeftTriangleEqual: '⊴', - LeftUpDownVector: '⥑', - LeftUpTeeVector: '⥠', - LeftUpVector: '↿', - LeftUpVectorBar: '⥘', - LeftVector: '↼', - LeftVectorBar: '⥒', - Leftarrow: '⇐', - Leftrightarrow: '⇔', - LessEqualGreater: '⋚', - LessFullEqual: '≦', - LessGreater: '≶', - LessLess: '⪡', - LessSlantEqual: '⩽', - LessTilde: '≲', - Lfr: '𝔏', - Ll: '⋘', - Lleftarrow: '⇚', - Lmidot: 'Ŀ', - LongLeftArrow: '⟵', - LongLeftRightArrow: '⟷', - LongRightArrow: '⟶', - Longleftarrow: '⟸', - Longleftrightarrow: '⟺', - Longrightarrow: '⟹', - Lopf: '𝕃', - LowerLeftArrow: '↙', - LowerRightArrow: '↘', - Lscr: 'ℒ', - Lsh: '↰', - Lstrok: 'Ł', - Lt: '≪', - Map: '⤅', - Mcy: 'М', - MediumSpace: ' ', - Mellintrf: 'ℳ', - Mfr: '𝔐', - MinusPlus: '∓', - Mopf: '𝕄', - Mscr: 'ℳ', - Mu: 'Μ', - NJcy: 'Њ', - Nacute: 'Ń', - Ncaron: 'Ň', - Ncedil: 'Ņ', - Ncy: 'Н', - NegativeMediumSpace: '​', - NegativeThickSpace: '​', - NegativeThinSpace: '​', - NegativeVeryThinSpace: '​', - NestedGreaterGreater: '≫', - NestedLessLess: '≪', - NewLine: '\n', - Nfr: '𝔑', - NoBreak: '⁠', - NonBreakingSpace: ' ', - Nopf: 'ℕ', - Not: '⫬', - NotCongruent: '≢', - NotCupCap: '≭', - NotDoubleVerticalBar: '∦', - NotElement: '∉', - NotEqual: '≠', - NotEqualTilde: '≂̸', - NotExists: '∄', - NotGreater: '≯', - NotGreaterEqual: '≱', - NotGreaterFullEqual: '≧̸', - NotGreaterGreater: '≫̸', - NotGreaterLess: '≹', - NotGreaterSlantEqual: '⩾̸', - NotGreaterTilde: '≵', - NotHumpDownHump: '≎̸', - NotHumpEqual: '≏̸', - NotLeftTriangle: '⋪', - NotLeftTriangleBar: '⧏̸', - NotLeftTriangleEqual: '⋬', - NotLess: '≮', - NotLessEqual: '≰', - NotLessGreater: '≸', - NotLessLess: '≪̸', - NotLessSlantEqual: '⩽̸', - NotLessTilde: '≴', - NotNestedGreaterGreater: '⪢̸', - NotNestedLessLess: '⪡̸', - NotPrecedes: '⊀', - NotPrecedesEqual: '⪯̸', - NotPrecedesSlantEqual: '⋠', - NotReverseElement: '∌', - NotRightTriangle: '⋫', - NotRightTriangleBar: '⧐̸', - NotRightTriangleEqual: '⋭', - NotSquareSubset: '⊏̸', - NotSquareSubsetEqual: '⋢', - NotSquareSuperset: '⊐̸', - NotSquareSupersetEqual: '⋣', - NotSubset: '⊂⃒', - NotSubsetEqual: '⊈', - NotSucceeds: '⊁', - NotSucceedsEqual: '⪰̸', - NotSucceedsSlantEqual: '⋡', - NotSucceedsTilde: '≿̸', - NotSuperset: '⊃⃒', - NotSupersetEqual: '⊉', - NotTilde: '≁', - NotTildeEqual: '≄', - NotTildeFullEqual: '≇', - NotTildeTilde: '≉', - NotVerticalBar: '∤', - Nscr: '𝒩', - Ntild: 'Ñ', - Ntilde: 'Ñ', - Nu: 'Ν', - OElig: 'Œ', - Oacut: 'Ó', - Oacute: 'Ó', - Ocir: 'Ô', - Ocirc: 'Ô', - Ocy: 'О', - Odblac: 'Ő', - Ofr: '𝔒', - Ograv: 'Ò', - Ograve: 'Ò', - Omacr: 'Ō', - Omega: 'Ω', - Omicron: 'Ο', - Oopf: '𝕆', - OpenCurlyDoubleQuote: '“', - OpenCurlyQuote: '‘', - Or: '⩔', - Oscr: '𝒪', - Oslas: 'Ø', - Oslash: 'Ø', - Otild: 'Õ', - Otilde: 'Õ', - Otimes: '⨷', - Oum: 'Ö', - Ouml: 'Ö', - OverBar: '‾', - OverBrace: '⏞', - OverBracket: '⎴', - OverParenthesis: '⏜', - PartialD: '∂', - Pcy: 'П', - Pfr: '𝔓', - Phi: 'Φ', - Pi: 'Π', - PlusMinus: '±', - Poincareplane: 'ℌ', - Popf: 'ℙ', - Pr: '⪻', - Precedes: '≺', - PrecedesEqual: '⪯', - PrecedesSlantEqual: '≼', - PrecedesTilde: '≾', - Prime: '″', - Product: '∏', - Proportion: '∷', - Proportional: '∝', - Pscr: '𝒫', - Psi: 'Ψ', - QUO: '"', - QUOT: '"', - Qfr: '𝔔', - Qopf: 'ℚ', - Qscr: '𝒬', - RBarr: '⤐', - RE: '®', - REG: '®', - Racute: 'Ŕ', - Rang: '⟫', - Rarr: '↠', - Rarrtl: '⤖', - Rcaron: 'Ř', - Rcedil: 'Ŗ', - Rcy: 'Р', - Re: 'ℜ', - ReverseElement: '∋', - ReverseEquilibrium: '⇋', - ReverseUpEquilibrium: '⥯', - Rfr: 'ℜ', - Rho: 'Ρ', - RightAngleBracket: '⟩', - RightArrow: '→', - RightArrowBar: '⇥', - RightArrowLeftArrow: '⇄', - RightCeiling: '⌉', - RightDoubleBracket: '⟧', - RightDownTeeVector: '⥝', - RightDownVector: '⇂', - RightDownVectorBar: '⥕', - RightFloor: '⌋', - RightTee: '⊢', - RightTeeArrow: '↦', - RightTeeVector: '⥛', - RightTriangle: '⊳', - RightTriangleBar: '⧐', - RightTriangleEqual: '⊵', - RightUpDownVector: '⥏', - RightUpTeeVector: '⥜', - RightUpVector: '↾', - RightUpVectorBar: '⥔', - RightVector: '⇀', - RightVectorBar: '⥓', - Rightarrow: '⇒', - Ropf: 'ℝ', - RoundImplies: '⥰', - Rrightarrow: '⇛', - Rscr: 'ℛ', - Rsh: '↱', - RuleDelayed: '⧴', - SHCHcy: 'Щ', - SHcy: 'Ш', - SOFTcy: 'Ь', - Sacute: 'Ś', - Sc: '⪼', - Scaron: 'Š', - Scedil: 'Ş', - Scirc: 'Ŝ', - Scy: 'С', - Sfr: '𝔖', - ShortDownArrow: '↓', - ShortLeftArrow: '←', - ShortRightArrow: '→', - ShortUpArrow: '↑', - Sigma: 'Σ', - SmallCircle: '∘', - Sopf: '𝕊', - Sqrt: '√', - Square: '□', - SquareIntersection: '⊓', - SquareSubset: '⊏', - SquareSubsetEqual: '⊑', - SquareSuperset: '⊐', - SquareSupersetEqual: '⊒', - SquareUnion: '⊔', - Sscr: '𝒮', - Star: '⋆', - Sub: '⋐', - Subset: '⋐', - SubsetEqual: '⊆', - Succeeds: '≻', - SucceedsEqual: '⪰', - SucceedsSlantEqual: '≽', - SucceedsTilde: '≿', - SuchThat: '∋', - Sum: '∑', - Sup: '⋑', - Superset: '⊃', - SupersetEqual: '⊇', - Supset: '⋑', - THOR: 'Þ', - THORN: 'Þ', - TRADE: '™', - TSHcy: 'Ћ', - TScy: 'Ц', - Tab: '\t', - Tau: 'Τ', - Tcaron: 'Ť', - Tcedil: 'Ţ', - Tcy: 'Т', - Tfr: '𝔗', - Therefore: '∴', - Theta: 'Θ', - ThickSpace: '  ', - ThinSpace: ' ', - Tilde: '∼', - TildeEqual: '≃', - TildeFullEqual: '≅', - TildeTilde: '≈', - Topf: '𝕋', - TripleDot: '⃛', - Tscr: '𝒯', - Tstrok: 'Ŧ', - Uacut: 'Ú', - Uacute: 'Ú', - Uarr: '↟', - Uarrocir: '⥉', - Ubrcy: 'Ў', - Ubreve: 'Ŭ', - Ucir: 'Û', - Ucirc: 'Û', - Ucy: 'У', - Udblac: 'Ű', - Ufr: '𝔘', - Ugrav: 'Ù', - Ugrave: 'Ù', - Umacr: 'Ū', - UnderBar: '_', - UnderBrace: '⏟', - UnderBracket: '⎵', - UnderParenthesis: '⏝', - Union: '⋃', - UnionPlus: '⊎', - Uogon: 'Ų', - Uopf: '𝕌', - UpArrow: '↑', - UpArrowBar: '⤒', - UpArrowDownArrow: '⇅', - UpDownArrow: '↕', - UpEquilibrium: '⥮', - UpTee: '⊥', - UpTeeArrow: '↥', - Uparrow: '⇑', - Updownarrow: '⇕', - UpperLeftArrow: '↖', - UpperRightArrow: '↗', - Upsi: 'ϒ', - Upsilon: 'Υ', - Uring: 'Ů', - Uscr: '𝒰', - Utilde: 'Ũ', - Uum: 'Ü', - Uuml: 'Ü', - VDash: '⊫', - Vbar: '⫫', - Vcy: 'В', - Vdash: '⊩', - Vdashl: '⫦', - Vee: '⋁', - Verbar: '‖', - Vert: '‖', - VerticalBar: '∣', - VerticalLine: '|', - VerticalSeparator: '❘', - VerticalTilde: '≀', - VeryThinSpace: ' ', - Vfr: '𝔙', - Vopf: '𝕍', - Vscr: '𝒱', - Vvdash: '⊪', - Wcirc: 'Ŵ', - Wedge: '⋀', - Wfr: '𝔚', - Wopf: '𝕎', - Wscr: '𝒲', - Xfr: '𝔛', - Xi: 'Ξ', - Xopf: '𝕏', - Xscr: '𝒳', - YAcy: 'Я', - YIcy: 'Ї', - YUcy: 'Ю', - Yacut: 'Ý', - Yacute: 'Ý', - Ycirc: 'Ŷ', - Ycy: 'Ы', - Yfr: '𝔜', - Yopf: '𝕐', - Yscr: '𝒴', - Yuml: 'Ÿ', - ZHcy: 'Ж', - Zacute: 'Ź', - Zcaron: 'Ž', - Zcy: 'З', - Zdot: 'Ż', - ZeroWidthSpace: '​', - Zeta: 'Ζ', - Zfr: 'ℨ', - Zopf: 'ℤ', - Zscr: '𝒵', - aacut: 'á', - aacute: 'á', - abreve: 'ă', - ac: '∾', - acE: '∾̳', - acd: '∿', - acir: 'â', - acirc: 'â', - acut: '´', - acute: '´', - acy: 'а', - aeli: 'æ', - aelig: 'æ', - af: '⁡', - afr: '𝔞', - agrav: 'à', - agrave: 'à', - alefsym: 'ℵ', - aleph: 'ℵ', - alpha: 'α', - amacr: 'ā', - amalg: '⨿', - am: '&', - amp: '&', - and: '∧', - andand: '⩕', - andd: '⩜', - andslope: '⩘', - andv: '⩚', - ang: '∠', - ange: '⦤', - angle: '∠', - angmsd: '∡', - angmsdaa: '⦨', - angmsdab: '⦩', - angmsdac: '⦪', - angmsdad: '⦫', - angmsdae: '⦬', - angmsdaf: '⦭', - angmsdag: '⦮', - angmsdah: '⦯', - angrt: '∟', - angrtvb: '⊾', - angrtvbd: '⦝', - angsph: '∢', - angst: 'Å', - angzarr: '⍼', - aogon: 'ą', - aopf: '𝕒', - ap: '≈', - apE: '⩰', - apacir: '⩯', - ape: '≊', - apid: '≋', - apos: "'", - approx: '≈', - approxeq: '≊', - arin: 'å', - aring: 'å', - ascr: '𝒶', - ast: '*', - asymp: '≈', - asympeq: '≍', - atild: 'ã', - atilde: 'ã', - aum: 'ä', - auml: 'ä', - awconint: '∳', - awint: '⨑', - bNot: '⫭', - backcong: '≌', - backepsilon: '϶', - backprime: '‵', - backsim: '∽', - backsimeq: '⋍', - barvee: '⊽', - barwed: '⌅', - barwedge: '⌅', - bbrk: '⎵', - bbrktbrk: '⎶', - bcong: '≌', - bcy: 'б', - bdquo: '„', - becaus: '∵', - because: '∵', - bemptyv: '⦰', - bepsi: '϶', - bernou: 'ℬ', - beta: 'β', - beth: 'ℶ', - between: '≬', - bfr: '𝔟', - bigcap: '⋂', - bigcirc: '◯', - bigcup: '⋃', - bigodot: '⨀', - bigoplus: '⨁', - bigotimes: '⨂', - bigsqcup: '⨆', - bigstar: '★', - bigtriangledown: '▽', - bigtriangleup: '△', - biguplus: '⨄', - bigvee: '⋁', - bigwedge: '⋀', - bkarow: '⤍', - blacklozenge: '⧫', - blacksquare: '▪', - blacktriangle: '▴', - blacktriangledown: '▾', - blacktriangleleft: '◂', - blacktriangleright: '▸', - blank: '␣', - blk12: '▒', - blk14: '░', - blk34: '▓', - block: '█', - bne: '=⃥', - bnequiv: '≡⃥', - bnot: '⌐', - bopf: '𝕓', - bot: '⊥', - bottom: '⊥', - bowtie: '⋈', - boxDL: '╗', - boxDR: '╔', - boxDl: '╖', - boxDr: '╓', - boxH: '═', - boxHD: '╦', - boxHU: '╩', - boxHd: '╤', - boxHu: '╧', - boxUL: '╝', - boxUR: '╚', - boxUl: '╜', - boxUr: '╙', - boxV: '║', - boxVH: '╬', - boxVL: '╣', - boxVR: '╠', - boxVh: '╫', - boxVl: '╢', - boxVr: '╟', - boxbox: '⧉', - boxdL: '╕', - boxdR: '╒', - boxdl: '┐', - boxdr: '┌', - boxh: '─', - boxhD: '╥', - boxhU: '╨', - boxhd: '┬', - boxhu: '┴', - boxminus: '⊟', - boxplus: '⊞', - boxtimes: '⊠', - boxuL: '╛', - boxuR: '╘', - boxul: '┘', - boxur: '└', - boxv: '│', - boxvH: '╪', - boxvL: '╡', - boxvR: '╞', - boxvh: '┼', - boxvl: '┤', - boxvr: '├', - bprime: '‵', - breve: '˘', - brvba: '¦', - brvbar: '¦', - bscr: '𝒷', - bsemi: '⁏', - bsim: '∽', - bsime: '⋍', - bsol: '\\', - bsolb: '⧅', - bsolhsub: '⟈', - bull: '•', - bullet: '•', - bump: '≎', - bumpE: '⪮', - bumpe: '≏', - bumpeq: '≏', - cacute: 'ć', - cap: '∩', - capand: '⩄', - capbrcup: '⩉', - capcap: '⩋', - capcup: '⩇', - capdot: '⩀', - caps: '∩︀', - caret: '⁁', - caron: 'ˇ', - ccaps: '⩍', - ccaron: 'č', - ccedi: 'ç', - ccedil: 'ç', - ccirc: 'ĉ', - ccups: '⩌', - ccupssm: '⩐', - cdot: 'ċ', - cedi: '¸', - cedil: '¸', - cemptyv: '⦲', - cen: '¢', - cent: '¢', - centerdot: '·', - cfr: '𝔠', - chcy: 'ч', - check: '✓', - checkmark: '✓', - chi: 'χ', - cir: '○', - cirE: '⧃', - circ: 'ˆ', - circeq: '≗', - circlearrowleft: '↺', - circlearrowright: '↻', - circledR: '®', - circledS: 'Ⓢ', - circledast: '⊛', - circledcirc: '⊚', - circleddash: '⊝', - cire: '≗', - cirfnint: '⨐', - cirmid: '⫯', - cirscir: '⧂', - clubs: '♣', - clubsuit: '♣', - colon: ':', - colone: '≔', - coloneq: '≔', - comma: ',', - commat: '@', - comp: '∁', - compfn: '∘', - complement: '∁', - complexes: 'ℂ', - cong: '≅', - congdot: '⩭', - conint: '∮', - copf: '𝕔', - coprod: '∐', - cop: '©', - copy: '©', - copysr: '℗', - crarr: '↵', - cross: '✗', - cscr: '𝒸', - csub: '⫏', - csube: '⫑', - csup: '⫐', - csupe: '⫒', - ctdot: '⋯', - cudarrl: '⤸', - cudarrr: '⤵', - cuepr: '⋞', - cuesc: '⋟', - cularr: '↶', - cularrp: '⤽', - cup: '∪', - cupbrcap: '⩈', - cupcap: '⩆', - cupcup: '⩊', - cupdot: '⊍', - cupor: '⩅', - cups: '∪︀', - curarr: '↷', - curarrm: '⤼', - curlyeqprec: '⋞', - curlyeqsucc: '⋟', - curlyvee: '⋎', - curlywedge: '⋏', - curre: '¤', - curren: '¤', - curvearrowleft: '↶', - curvearrowright: '↷', - cuvee: '⋎', - cuwed: '⋏', - cwconint: '∲', - cwint: '∱', - cylcty: '⌭', - dArr: '⇓', - dHar: '⥥', - dagger: '†', - daleth: 'ℸ', - darr: '↓', - dash: '‐', - dashv: '⊣', - dbkarow: '⤏', - dblac: '˝', - dcaron: 'ď', - dcy: 'д', - dd: 'ⅆ', - ddagger: '‡', - ddarr: '⇊', - ddotseq: '⩷', - de: '°', - deg: '°', - delta: 'δ', - demptyv: '⦱', - dfisht: '⥿', - dfr: '𝔡', - dharl: '⇃', - dharr: '⇂', - diam: '⋄', - diamond: '⋄', - diamondsuit: '♦', - diams: '♦', - die: '¨', - digamma: 'ϝ', - disin: '⋲', - div: '÷', - divid: '÷', - divide: '÷', - divideontimes: '⋇', - divonx: '⋇', - djcy: 'ђ', - dlcorn: '⌞', - dlcrop: '⌍', - dollar: '$', - dopf: '𝕕', - dot: '˙', - doteq: '≐', - doteqdot: '≑', - dotminus: '∸', - dotplus: '∔', - dotsquare: '⊡', - doublebarwedge: '⌆', - downarrow: '↓', - downdownarrows: '⇊', - downharpoonleft: '⇃', - downharpoonright: '⇂', - drbkarow: '⤐', - drcorn: '⌟', - drcrop: '⌌', - dscr: '𝒹', - dscy: 'ѕ', - dsol: '⧶', - dstrok: 'đ', - dtdot: '⋱', - dtri: '▿', - dtrif: '▾', - duarr: '⇵', - duhar: '⥯', - dwangle: '⦦', - dzcy: 'џ', - dzigrarr: '⟿', - eDDot: '⩷', - eDot: '≑', - eacut: 'é', - eacute: 'é', - easter: '⩮', - ecaron: 'ě', - ecir: 'ê', - ecirc: 'ê', - ecolon: '≕', - ecy: 'э', - edot: 'ė', - ee: 'ⅇ', - efDot: '≒', - efr: '𝔢', - eg: '⪚', - egrav: 'è', - egrave: 'è', - egs: '⪖', - egsdot: '⪘', - el: '⪙', - elinters: '⏧', - ell: 'ℓ', - els: '⪕', - elsdot: '⪗', - emacr: 'ē', - empty: '∅', - emptyset: '∅', - emptyv: '∅', - emsp13: ' ', - emsp14: ' ', - emsp: ' ', - eng: 'ŋ', - ensp: ' ', - eogon: 'ę', - eopf: '𝕖', - epar: '⋕', - eparsl: '⧣', - eplus: '⩱', - epsi: 'ε', - epsilon: 'ε', - epsiv: 'ϵ', - eqcirc: '≖', - eqcolon: '≕', - eqsim: '≂', - eqslantgtr: '⪖', - eqslantless: '⪕', - equals: '=', - equest: '≟', - equiv: '≡', - equivDD: '⩸', - eqvparsl: '⧥', - erDot: '≓', - erarr: '⥱', - escr: 'ℯ', - esdot: '≐', - esim: '≂', - eta: 'η', - et: 'ð', - eth: 'ð', - eum: 'ë', - euml: 'ë', - euro: '€', - excl: '!', - exist: '∃', - expectation: 'ℰ', - exponentiale: 'ⅇ', - fallingdotseq: '≒', - fcy: 'ф', - female: '♀', - ffilig: 'ffi', - fflig: 'ff', - ffllig: 'ffl', - ffr: '𝔣', - filig: 'fi', - fjlig: 'fj', - flat: '♭', - fllig: 'fl', - fltns: '▱', - fnof: 'ƒ', - fopf: '𝕗', - forall: '∀', - fork: '⋔', - forkv: '⫙', - fpartint: '⨍', - frac1: '¼', - frac12: '½', - frac13: '⅓', - frac14: '¼', - frac15: '⅕', - frac16: '⅙', - frac18: '⅛', - frac23: '⅔', - frac25: '⅖', - frac3: '¾', - frac34: '¾', - frac35: '⅗', - frac38: '⅜', - frac45: '⅘', - frac56: '⅚', - frac58: '⅝', - frac78: '⅞', - frasl: '⁄', - frown: '⌢', - fscr: '𝒻', - gE: '≧', - gEl: '⪌', - gacute: 'ǵ', - gamma: 'γ', - gammad: 'ϝ', - gap: '⪆', - gbreve: 'ğ', - gcirc: 'ĝ', - gcy: 'г', - gdot: 'ġ', - ge: '≥', - gel: '⋛', - geq: '≥', - geqq: '≧', - geqslant: '⩾', - ges: '⩾', - gescc: '⪩', - gesdot: '⪀', - gesdoto: '⪂', - gesdotol: '⪄', - gesl: '⋛︀', - gesles: '⪔', - gfr: '𝔤', - gg: '≫', - ggg: '⋙', - gimel: 'ℷ', - gjcy: 'ѓ', - gl: '≷', - glE: '⪒', - gla: '⪥', - glj: '⪤', - gnE: '≩', - gnap: '⪊', - gnapprox: '⪊', - gne: '⪈', - gneq: '⪈', - gneqq: '≩', - gnsim: '⋧', - gopf: '𝕘', - grave: '`', - gscr: 'ℊ', - gsim: '≳', - gsime: '⪎', - gsiml: '⪐', - g: '>', - gt: '>', - gtcc: '⪧', - gtcir: '⩺', - gtdot: '⋗', - gtlPar: '⦕', - gtquest: '⩼', - gtrapprox: '⪆', - gtrarr: '⥸', - gtrdot: '⋗', - gtreqless: '⋛', - gtreqqless: '⪌', - gtrless: '≷', - gtrsim: '≳', - gvertneqq: '≩︀', - gvnE: '≩︀', - hArr: '⇔', - hairsp: ' ', - half: '½', - hamilt: 'ℋ', - hardcy: 'ъ', - harr: '↔', - harrcir: '⥈', - harrw: '↭', - hbar: 'ℏ', - hcirc: 'ĥ', - hearts: '♥', - heartsuit: '♥', - hellip: '…', - hercon: '⊹', - hfr: '𝔥', - hksearow: '⤥', - hkswarow: '⤦', - hoarr: '⇿', - homtht: '∻', - hookleftarrow: '↩', - hookrightarrow: '↪', - hopf: '𝕙', - horbar: '―', - hscr: '𝒽', - hslash: 'ℏ', - hstrok: 'ħ', - hybull: '⁃', - hyphen: '‐', - iacut: 'í', - iacute: 'í', - ic: '⁣', - icir: 'î', - icirc: 'î', - icy: 'и', - iecy: 'е', - iexc: '¡', - iexcl: '¡', - iff: '⇔', - ifr: '𝔦', - igrav: 'ì', - igrave: 'ì', - ii: 'ⅈ', - iiiint: '⨌', - iiint: '∭', - iinfin: '⧜', - iiota: '℩', - ijlig: 'ij', - imacr: 'ī', - image: 'ℑ', - imagline: 'ℐ', - imagpart: 'ℑ', - imath: 'ı', - imof: '⊷', - imped: 'Ƶ', - in: '∈', - incare: '℅', - infin: '∞', - infintie: '⧝', - inodot: 'ı', - int: '∫', - intcal: '⊺', - integers: 'ℤ', - intercal: '⊺', - intlarhk: '⨗', - intprod: '⨼', - iocy: 'ё', - iogon: 'į', - iopf: '𝕚', - iota: 'ι', - iprod: '⨼', - iques: '¿', - iquest: '¿', - iscr: '𝒾', - isin: '∈', - isinE: '⋹', - isindot: '⋵', - isins: '⋴', - isinsv: '⋳', - isinv: '∈', - it: '⁢', - itilde: 'ĩ', - iukcy: 'і', - ium: 'ï', - iuml: 'ï', - jcirc: 'ĵ', - jcy: 'й', - jfr: '𝔧', - jmath: 'ȷ', - jopf: '𝕛', - jscr: '𝒿', - jsercy: 'ј', - jukcy: 'є', - kappa: 'κ', - kappav: 'ϰ', - kcedil: 'ķ', - kcy: 'к', - kfr: '𝔨', - kgreen: 'ĸ', - khcy: 'х', - kjcy: 'ќ', - kopf: '𝕜', - kscr: '𝓀', - lAarr: '⇚', - lArr: '⇐', - lAtail: '⤛', - lBarr: '⤎', - lE: '≦', - lEg: '⪋', - lHar: '⥢', - lacute: 'ĺ', - laemptyv: '⦴', - lagran: 'ℒ', - lambda: 'λ', - lang: '⟨', - langd: '⦑', - langle: '⟨', - lap: '⪅', - laqu: '«', - laquo: '«', - larr: '←', - larrb: '⇤', - larrbfs: '⤟', - larrfs: '⤝', - larrhk: '↩', - larrlp: '↫', - larrpl: '⤹', - larrsim: '⥳', - larrtl: '↢', - lat: '⪫', - latail: '⤙', - late: '⪭', - lates: '⪭︀', - lbarr: '⤌', - lbbrk: '❲', - lbrace: '{', - lbrack: '[', - lbrke: '⦋', - lbrksld: '⦏', - lbrkslu: '⦍', - lcaron: 'ľ', - lcedil: 'ļ', - lceil: '⌈', - lcub: '{', - lcy: 'л', - ldca: '⤶', - ldquo: '“', - ldquor: '„', - ldrdhar: '⥧', - ldrushar: '⥋', - ldsh: '↲', - le: '≤', - leftarrow: '←', - leftarrowtail: '↢', - leftharpoondown: '↽', - leftharpoonup: '↼', - leftleftarrows: '⇇', - leftrightarrow: '↔', - leftrightarrows: '⇆', - leftrightharpoons: '⇋', - leftrightsquigarrow: '↭', - leftthreetimes: '⋋', - leg: '⋚', - leq: '≤', - leqq: '≦', - leqslant: '⩽', - les: '⩽', - lescc: '⪨', - lesdot: '⩿', - lesdoto: '⪁', - lesdotor: '⪃', - lesg: '⋚︀', - lesges: '⪓', - lessapprox: '⪅', - lessdot: '⋖', - lesseqgtr: '⋚', - lesseqqgtr: '⪋', - lessgtr: '≶', - lesssim: '≲', - lfisht: '⥼', - lfloor: '⌊', - lfr: '𝔩', - lg: '≶', - lgE: '⪑', - lhard: '↽', - lharu: '↼', - lharul: '⥪', - lhblk: '▄', - ljcy: 'љ', - ll: '≪', - llarr: '⇇', - llcorner: '⌞', - llhard: '⥫', - lltri: '◺', - lmidot: 'ŀ', - lmoust: '⎰', - lmoustache: '⎰', - lnE: '≨', - lnap: '⪉', - lnapprox: '⪉', - lne: '⪇', - lneq: '⪇', - lneqq: '≨', - lnsim: '⋦', - loang: '⟬', - loarr: '⇽', - lobrk: '⟦', - longleftarrow: '⟵', - longleftrightarrow: '⟷', - longmapsto: '⟼', - longrightarrow: '⟶', - looparrowleft: '↫', - looparrowright: '↬', - lopar: '⦅', - lopf: '𝕝', - loplus: '⨭', - lotimes: '⨴', - lowast: '∗', - lowbar: '_', - loz: '◊', - lozenge: '◊', - lozf: '⧫', - lpar: '(', - lparlt: '⦓', - lrarr: '⇆', - lrcorner: '⌟', - lrhar: '⇋', - lrhard: '⥭', - lrm: '‎', - lrtri: '⊿', - lsaquo: '‹', - lscr: '𝓁', - lsh: '↰', - lsim: '≲', - lsime: '⪍', - lsimg: '⪏', - lsqb: '[', - lsquo: '‘', - lsquor: '‚', - lstrok: 'ł', - l: '<', - lt: '<', - ltcc: '⪦', - ltcir: '⩹', - ltdot: '⋖', - lthree: '⋋', - ltimes: '⋉', - ltlarr: '⥶', - ltquest: '⩻', - ltrPar: '⦖', - ltri: '◃', - ltrie: '⊴', - ltrif: '◂', - lurdshar: '⥊', - luruhar: '⥦', - lvertneqq: '≨︀', - lvnE: '≨︀', - mDDot: '∺', - mac: '¯', - macr: '¯', - male: '♂', - malt: '✠', - maltese: '✠', - map: '↦', - mapsto: '↦', - mapstodown: '↧', - mapstoleft: '↤', - mapstoup: '↥', - marker: '▮', - mcomma: '⨩', - mcy: 'м', - mdash: '—', - measuredangle: '∡', - mfr: '𝔪', - mho: '℧', - micr: 'µ', - micro: 'µ', - mid: '∣', - midast: '*', - midcir: '⫰', - middo: '·', - middot: '·', - minus: '−', - minusb: '⊟', - minusd: '∸', - minusdu: '⨪', - mlcp: '⫛', - mldr: '…', - mnplus: '∓', - models: '⊧', - mopf: '𝕞', - mp: '∓', - mscr: '𝓂', - mstpos: '∾', - mu: 'μ', - multimap: '⊸', - mumap: '⊸', - nGg: '⋙̸', - nGt: '≫⃒', - nGtv: '≫̸', - nLeftarrow: '⇍', - nLeftrightarrow: '⇎', - nLl: '⋘̸', - nLt: '≪⃒', - nLtv: '≪̸', - nRightarrow: '⇏', - nVDash: '⊯', - nVdash: '⊮', - nabla: '∇', - nacute: 'ń', - nang: '∠⃒', - nap: '≉', - napE: '⩰̸', - napid: '≋̸', - napos: 'ʼn', - napprox: '≉', - natur: '♮', - natural: '♮', - naturals: 'ℕ', - nbs: ' ', - nbsp: ' ', - nbump: '≎̸', - nbumpe: '≏̸', - ncap: '⩃', - ncaron: 'ň', - ncedil: 'ņ', - ncong: '≇', - ncongdot: '⩭̸', - ncup: '⩂', - ncy: 'н', - ndash: '–', - ne: '≠', - neArr: '⇗', - nearhk: '⤤', - nearr: '↗', - nearrow: '↗', - nedot: '≐̸', - nequiv: '≢', - nesear: '⤨', - nesim: '≂̸', - nexist: '∄', - nexists: '∄', - nfr: '𝔫', - ngE: '≧̸', - nge: '≱', - ngeq: '≱', - ngeqq: '≧̸', - ngeqslant: '⩾̸', - nges: '⩾̸', - ngsim: '≵', - ngt: '≯', - ngtr: '≯', - nhArr: '⇎', - nharr: '↮', - nhpar: '⫲', - ni: '∋', - nis: '⋼', - nisd: '⋺', - niv: '∋', - njcy: 'њ', - nlArr: '⇍', - nlE: '≦̸', - nlarr: '↚', - nldr: '‥', - nle: '≰', - nleftarrow: '↚', - nleftrightarrow: '↮', - nleq: '≰', - nleqq: '≦̸', - nleqslant: '⩽̸', - nles: '⩽̸', - nless: '≮', - nlsim: '≴', - nlt: '≮', - nltri: '⋪', - nltrie: '⋬', - nmid: '∤', - nopf: '𝕟', - no: '¬', - not: '¬', - notin: '∉', - notinE: '⋹̸', - notindot: '⋵̸', - notinva: '∉', - notinvb: '⋷', - notinvc: '⋶', - notni: '∌', - notniva: '∌', - notnivb: '⋾', - notnivc: '⋽', - npar: '∦', - nparallel: '∦', - nparsl: '⫽⃥', - npart: '∂̸', - npolint: '⨔', - npr: '⊀', - nprcue: '⋠', - npre: '⪯̸', - nprec: '⊀', - npreceq: '⪯̸', - nrArr: '⇏', - nrarr: '↛', - nrarrc: '⤳̸', - nrarrw: '↝̸', - nrightarrow: '↛', - nrtri: '⋫', - nrtrie: '⋭', - nsc: '⊁', - nsccue: '⋡', - nsce: '⪰̸', - nscr: '𝓃', - nshortmid: '∤', - nshortparallel: '∦', - nsim: '≁', - nsime: '≄', - nsimeq: '≄', - nsmid: '∤', - nspar: '∦', - nsqsube: '⋢', - nsqsupe: '⋣', - nsub: '⊄', - nsubE: '⫅̸', - nsube: '⊈', - nsubset: '⊂⃒', - nsubseteq: '⊈', - nsubseteqq: '⫅̸', - nsucc: '⊁', - nsucceq: '⪰̸', - nsup: '⊅', - nsupE: '⫆̸', - nsupe: '⊉', - nsupset: '⊃⃒', - nsupseteq: '⊉', - nsupseteqq: '⫆̸', - ntgl: '≹', - ntild: 'ñ', - ntilde: 'ñ', - ntlg: '≸', - ntriangleleft: '⋪', - ntrianglelefteq: '⋬', - ntriangleright: '⋫', - ntrianglerighteq: '⋭', - nu: 'ν', - num: '#', - numero: '№', - numsp: ' ', - nvDash: '⊭', - nvHarr: '⤄', - nvap: '≍⃒', - nvdash: '⊬', - nvge: '≥⃒', - nvgt: '>⃒', - nvinfin: '⧞', - nvlArr: '⤂', - nvle: '≤⃒', - nvlt: '<⃒', - nvltrie: '⊴⃒', - nvrArr: '⤃', - nvrtrie: '⊵⃒', - nvsim: '∼⃒', - nwArr: '⇖', - nwarhk: '⤣', - nwarr: '↖', - nwarrow: '↖', - nwnear: '⤧', - oS: 'Ⓢ', - oacut: 'ó', - oacute: 'ó', - oast: '⊛', - ocir: 'ô', - ocirc: 'ô', - ocy: 'о', - odash: '⊝', - odblac: 'ő', - odiv: '⨸', - odot: '⊙', - odsold: '⦼', - oelig: 'œ', - ofcir: '⦿', - ofr: '𝔬', - ogon: '˛', - ograv: 'ò', - ograve: 'ò', - ogt: '⧁', - ohbar: '⦵', - ohm: 'Ω', - oint: '∮', - olarr: '↺', - olcir: '⦾', - olcross: '⦻', - oline: '‾', - olt: '⧀', - omacr: 'ō', - omega: 'ω', - omicron: 'ο', - omid: '⦶', - ominus: '⊖', - oopf: '𝕠', - opar: '⦷', - operp: '⦹', - oplus: '⊕', - or: '∨', - orarr: '↻', - ord: 'º', - order: 'ℴ', - orderof: 'ℴ', - ordf: 'ª', - ordm: 'º', - origof: '⊶', - oror: '⩖', - orslope: '⩗', - orv: '⩛', - oscr: 'ℴ', - oslas: 'ø', - oslash: 'ø', - osol: '⊘', - otild: 'õ', - otilde: 'õ', - otimes: '⊗', - otimesas: '⨶', - oum: 'ö', - ouml: 'ö', - ovbar: '⌽', - par: '¶', - para: '¶', - parallel: '∥', - parsim: '⫳', - parsl: '⫽', - part: '∂', - pcy: 'п', - percnt: '%', - period: '.', - permil: '‰', - perp: '⊥', - pertenk: '‱', - pfr: '𝔭', - phi: 'φ', - phiv: 'ϕ', - phmmat: 'ℳ', - phone: '☎', - pi: 'π', - pitchfork: '⋔', - piv: 'ϖ', - planck: 'ℏ', - planckh: 'ℎ', - plankv: 'ℏ', - plus: '+', - plusacir: '⨣', - plusb: '⊞', - pluscir: '⨢', - plusdo: '∔', - plusdu: '⨥', - pluse: '⩲', - plusm: '±', - plusmn: '±', - plussim: '⨦', - plustwo: '⨧', - pm: '±', - pointint: '⨕', - popf: '𝕡', - poun: '£', - pound: '£', - pr: '≺', - prE: '⪳', - prap: '⪷', - prcue: '≼', - pre: '⪯', - prec: '≺', - precapprox: '⪷', - preccurlyeq: '≼', - preceq: '⪯', - precnapprox: '⪹', - precneqq: '⪵', - precnsim: '⋨', - precsim: '≾', - prime: '′', - primes: 'ℙ', - prnE: '⪵', - prnap: '⪹', - prnsim: '⋨', - prod: '∏', - profalar: '⌮', - profline: '⌒', - profsurf: '⌓', - prop: '∝', - propto: '∝', - prsim: '≾', - prurel: '⊰', - pscr: '𝓅', - psi: 'ψ', - puncsp: ' ', - qfr: '𝔮', - qint: '⨌', - qopf: '𝕢', - qprime: '⁗', - qscr: '𝓆', - quaternions: 'ℍ', - quatint: '⨖', - quest: '?', - questeq: '≟', - quo: '"', - quot: '"', - rAarr: '⇛', - rArr: '⇒', - rAtail: '⤜', - rBarr: '⤏', - rHar: '⥤', - race: '∽̱', - racute: 'ŕ', - radic: '√', - raemptyv: '⦳', - rang: '⟩', - rangd: '⦒', - range: '⦥', - rangle: '⟩', - raqu: '»', - raquo: '»', - rarr: '→', - rarrap: '⥵', - rarrb: '⇥', - rarrbfs: '⤠', - rarrc: '⤳', - rarrfs: '⤞', - rarrhk: '↪', - rarrlp: '↬', - rarrpl: '⥅', - rarrsim: '⥴', - rarrtl: '↣', - rarrw: '↝', - ratail: '⤚', - ratio: '∶', - rationals: 'ℚ', - rbarr: '⤍', - rbbrk: '❳', - rbrace: '}', - rbrack: ']', - rbrke: '⦌', - rbrksld: '⦎', - rbrkslu: '⦐', - rcaron: 'ř', - rcedil: 'ŗ', - rceil: '⌉', - rcub: '}', - rcy: 'р', - rdca: '⤷', - rdldhar: '⥩', - rdquo: '”', - rdquor: '”', - rdsh: '↳', - real: 'ℜ', - realine: 'ℛ', - realpart: 'ℜ', - reals: 'ℝ', - rect: '▭', - re: '®', - reg: '®', - rfisht: '⥽', - rfloor: '⌋', - rfr: '𝔯', - rhard: '⇁', - rharu: '⇀', - rharul: '⥬', - rho: 'ρ', - rhov: 'ϱ', - rightarrow: '→', - rightarrowtail: '↣', - rightharpoondown: '⇁', - rightharpoonup: '⇀', - rightleftarrows: '⇄', - rightleftharpoons: '⇌', - rightrightarrows: '⇉', - rightsquigarrow: '↝', - rightthreetimes: '⋌', - ring: '˚', - risingdotseq: '≓', - rlarr: '⇄', - rlhar: '⇌', - rlm: '‏', - rmoust: '⎱', - rmoustache: '⎱', - rnmid: '⫮', - roang: '⟭', - roarr: '⇾', - robrk: '⟧', - ropar: '⦆', - ropf: '𝕣', - roplus: '⨮', - rotimes: '⨵', - rpar: ')', - rpargt: '⦔', - rppolint: '⨒', - rrarr: '⇉', - rsaquo: '›', - rscr: '𝓇', - rsh: '↱', - rsqb: ']', - rsquo: '’', - rsquor: '’', - rthree: '⋌', - rtimes: '⋊', - rtri: '▹', - rtrie: '⊵', - rtrif: '▸', - rtriltri: '⧎', - ruluhar: '⥨', - rx: '℞', - sacute: 'ś', - sbquo: '‚', - sc: '≻', - scE: '⪴', - scap: '⪸', - scaron: 'š', - sccue: '≽', - sce: '⪰', - scedil: 'ş', - scirc: 'ŝ', - scnE: '⪶', - scnap: '⪺', - scnsim: '⋩', - scpolint: '⨓', - scsim: '≿', - scy: 'с', - sdot: '⋅', - sdotb: '⊡', - sdote: '⩦', - seArr: '⇘', - searhk: '⤥', - searr: '↘', - searrow: '↘', - sec: '§', - sect: '§', - semi: ';', - seswar: '⤩', - setminus: '∖', - setmn: '∖', - sext: '✶', - sfr: '𝔰', - sfrown: '⌢', - sharp: '♯', - shchcy: 'щ', - shcy: 'ш', - shortmid: '∣', - shortparallel: '∥', - sh: '­', - shy: '­', - sigma: 'σ', - sigmaf: 'ς', - sigmav: 'ς', - sim: '∼', - simdot: '⩪', - sime: '≃', - simeq: '≃', - simg: '⪞', - simgE: '⪠', - siml: '⪝', - simlE: '⪟', - simne: '≆', - simplus: '⨤', - simrarr: '⥲', - slarr: '←', - smallsetminus: '∖', - smashp: '⨳', - smeparsl: '⧤', - smid: '∣', - smile: '⌣', - smt: '⪪', - smte: '⪬', - smtes: '⪬︀', - softcy: 'ь', - sol: '/', - solb: '⧄', - solbar: '⌿', - sopf: '𝕤', - spades: '♠', - spadesuit: '♠', - spar: '∥', - sqcap: '⊓', - sqcaps: '⊓︀', - sqcup: '⊔', - sqcups: '⊔︀', - sqsub: '⊏', - sqsube: '⊑', - sqsubset: '⊏', - sqsubseteq: '⊑', - sqsup: '⊐', - sqsupe: '⊒', - sqsupset: '⊐', - sqsupseteq: '⊒', - squ: '□', - square: '□', - squarf: '▪', - squf: '▪', - srarr: '→', - sscr: '𝓈', - ssetmn: '∖', - ssmile: '⌣', - sstarf: '⋆', - star: '☆', - starf: '★', - straightepsilon: 'ϵ', - straightphi: 'ϕ', - strns: '¯', - sub: '⊂', - subE: '⫅', - subdot: '⪽', - sube: '⊆', - subedot: '⫃', - submult: '⫁', - subnE: '⫋', - subne: '⊊', - subplus: '⪿', - subrarr: '⥹', - subset: '⊂', - subseteq: '⊆', - subseteqq: '⫅', - subsetneq: '⊊', - subsetneqq: '⫋', - subsim: '⫇', - subsub: '⫕', - subsup: '⫓', - succ: '≻', - succapprox: '⪸', - succcurlyeq: '≽', - succeq: '⪰', - succnapprox: '⪺', - succneqq: '⪶', - succnsim: '⋩', - succsim: '≿', - sum: '∑', - sung: '♪', - sup: '⊃', - sup1: '¹', - sup2: '²', - sup3: '³', - supE: '⫆', - supdot: '⪾', - supdsub: '⫘', - supe: '⊇', - supedot: '⫄', - suphsol: '⟉', - suphsub: '⫗', - suplarr: '⥻', - supmult: '⫂', - supnE: '⫌', - supne: '⊋', - supplus: '⫀', - supset: '⊃', - supseteq: '⊇', - supseteqq: '⫆', - supsetneq: '⊋', - supsetneqq: '⫌', - supsim: '⫈', - supsub: '⫔', - supsup: '⫖', - swArr: '⇙', - swarhk: '⤦', - swarr: '↙', - swarrow: '↙', - swnwar: '⤪', - szli: 'ß', - szlig: 'ß', - target: '⌖', - tau: 'τ', - tbrk: '⎴', - tcaron: 'ť', - tcedil: 'ţ', - tcy: 'т', - tdot: '⃛', - telrec: '⌕', - tfr: '𝔱', - there4: '∴', - therefore: '∴', - theta: 'θ', - thetasym: 'ϑ', - thetav: 'ϑ', - thickapprox: '≈', - thicksim: '∼', - thinsp: ' ', - thkap: '≈', - thksim: '∼', - thor: 'þ', - thorn: 'þ', - tilde: '˜', - time: '×', - times: '×', - timesb: '⊠', - timesbar: '⨱', - timesd: '⨰', - tint: '∭', - toea: '⤨', - top: '⊤', - topbot: '⌶', - topcir: '⫱', - topf: '𝕥', - topfork: '⫚', - tosa: '⤩', - tprime: '‴', - trade: '™', - triangle: '▵', - triangledown: '▿', - triangleleft: '◃', - trianglelefteq: '⊴', - triangleq: '≜', - triangleright: '▹', - trianglerighteq: '⊵', - tridot: '◬', - trie: '≜', - triminus: '⨺', - triplus: '⨹', - trisb: '⧍', - tritime: '⨻', - trpezium: '⏢', - tscr: '𝓉', - tscy: 'ц', - tshcy: 'ћ', - tstrok: 'ŧ', - twixt: '≬', - twoheadleftarrow: '↞', - twoheadrightarrow: '↠', - uArr: '⇑', - uHar: '⥣', - uacut: 'ú', - uacute: 'ú', - uarr: '↑', - ubrcy: 'ў', - ubreve: 'ŭ', - ucir: 'û', - ucirc: 'û', - ucy: 'у', - udarr: '⇅', - udblac: 'ű', - udhar: '⥮', - ufisht: '⥾', - ufr: '𝔲', - ugrav: 'ù', - ugrave: 'ù', - uharl: '↿', - uharr: '↾', - uhblk: '▀', - ulcorn: '⌜', - ulcorner: '⌜', - ulcrop: '⌏', - ultri: '◸', - umacr: 'ū', - um: '¨', - uml: '¨', - uogon: 'ų', - uopf: '𝕦', - uparrow: '↑', - updownarrow: '↕', - upharpoonleft: '↿', - upharpoonright: '↾', - uplus: '⊎', - upsi: 'υ', - upsih: 'ϒ', - upsilon: 'υ', - upuparrows: '⇈', - urcorn: '⌝', - urcorner: '⌝', - urcrop: '⌎', - uring: 'ů', - urtri: '◹', - uscr: '𝓊', - utdot: '⋰', - utilde: 'ũ', - utri: '▵', - utrif: '▴', - uuarr: '⇈', - uum: 'ü', - uuml: 'ü', - uwangle: '⦧', - vArr: '⇕', - vBar: '⫨', - vBarv: '⫩', - vDash: '⊨', - vangrt: '⦜', - varepsilon: 'ϵ', - varkappa: 'ϰ', - varnothing: '∅', - varphi: 'ϕ', - varpi: 'ϖ', - varpropto: '∝', - varr: '↕', - varrho: 'ϱ', - varsigma: 'ς', - varsubsetneq: '⊊︀', - varsubsetneqq: '⫋︀', - varsupsetneq: '⊋︀', - varsupsetneqq: '⫌︀', - vartheta: 'ϑ', - vartriangleleft: '⊲', - vartriangleright: '⊳', - vcy: 'в', - vdash: '⊢', - vee: '∨', - veebar: '⊻', - veeeq: '≚', - vellip: '⋮', - verbar: '|', - vert: '|', - vfr: '𝔳', - vltri: '⊲', - vnsub: '⊂⃒', - vnsup: '⊃⃒', - vopf: '𝕧', - vprop: '∝', - vrtri: '⊳', - vscr: '𝓋', - vsubnE: '⫋︀', - vsubne: '⊊︀', - vsupnE: '⫌︀', - vsupne: '⊋︀', - vzigzag: '⦚', - wcirc: 'ŵ', - wedbar: '⩟', - wedge: '∧', - wedgeq: '≙', - weierp: '℘', - wfr: '𝔴', - wopf: '𝕨', - wp: '℘', - wr: '≀', - wreath: '≀', - wscr: '𝓌', - xcap: '⋂', - xcirc: '◯', - xcup: '⋃', - xdtri: '▽', - xfr: '𝔵', - xhArr: '⟺', - xharr: '⟷', - xi: 'ξ', - xlArr: '⟸', - xlarr: '⟵', - xmap: '⟼', - xnis: '⋻', - xodot: '⨀', - xopf: '𝕩', - xoplus: '⨁', - xotime: '⨂', - xrArr: '⟹', - xrarr: '⟶', - xscr: '𝓍', - xsqcup: '⨆', - xuplus: '⨄', - xutri: '△', - xvee: '⋁', - xwedge: '⋀', - yacut: 'ý', - yacute: 'ý', - yacy: 'я', - ycirc: 'ŷ', - ycy: 'ы', - ye: '¥', - yen: '¥', - yfr: '𝔶', - yicy: 'ї', - yopf: '𝕪', - yscr: '𝓎', - yucy: 'ю', - yum: 'ÿ', - yuml: 'ÿ', - zacute: 'ź', - zcaron: 'ž', - zcy: 'з', - zdot: 'ż', - zeetrf: 'ℨ', - zeta: 'ζ', - zfr: '𝔷', - zhcy: 'ж', - zigrarr: '⇝', - zopf: '𝕫', - zscr: '𝓏', - zwj: '‍', - zwnj: '‌' -}; - -var own$5 = {}.hasOwnProperty; - -/** - * @param {string} characters - * @returns {string|false} - */ -function decodeEntity(characters) { - return own$5.call(characterEntities, characters) - ? characterEntities[characters] - : false -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const characterReference$1 = { - name: 'characterReference', - tokenize: tokenizeCharacterReference -}; -/** @type {Tokenizer} */ - -function tokenizeCharacterReference(effects, ok, nok) { - const self = this; - let size = 0; - /** @type {number} */ - - let max; - /** @type {(code: Code) => code is number} */ - - let test; - return start - /** @type {State} */ - - function start(code) { - effects.enter('characterReference'); - effects.enter('characterReferenceMarker'); - effects.consume(code); - effects.exit('characterReferenceMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 35) { - effects.enter('characterReferenceMarkerNumeric'); - effects.consume(code); - effects.exit('characterReferenceMarkerNumeric'); - return numeric - } - - effects.enter('characterReferenceValue'); - max = 31; - test = asciiAlphanumeric; - return value(code) - } - /** @type {State} */ - - function numeric(code) { - if (code === 88 || code === 120) { - effects.enter('characterReferenceMarkerHexadecimal'); - effects.consume(code); - effects.exit('characterReferenceMarkerHexadecimal'); - effects.enter('characterReferenceValue'); - max = 6; - test = asciiHexDigit; - return value - } - - effects.enter('characterReferenceValue'); - max = 7; - test = asciiDigit; - return value(code) - } - /** @type {State} */ - - function value(code) { - /** @type {Token} */ - let token; - - if (code === 59 && size) { - token = effects.exit('characterReferenceValue'); - - if ( - test === asciiAlphanumeric && - !decodeEntity(self.sliceSerialize(token)) - ) { - return nok(code) - } - - effects.enter('characterReferenceMarker'); - effects.consume(code); - effects.exit('characterReferenceMarker'); - effects.exit('characterReference'); - return ok - } - - if (test(code) && size++ < max) { - effects.consume(code); - return value - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const codeFenced = { - name: 'codeFenced', - tokenize: tokenizeCodeFenced, - concrete: true -}; -/** @type {Tokenizer} */ - -function tokenizeCodeFenced(effects, ok, nok) { - const self = this; - /** @type {Construct} */ - - const closingFenceConstruct = { - tokenize: tokenizeClosingFence, - partial: true - }; - /** @type {Construct} */ - - const nonLazyLine = { - tokenize: tokenizeNonLazyLine, - partial: true - }; - const tail = this.events[this.events.length - 1]; - const initialPrefix = - tail && tail[1].type === 'linePrefix' - ? tail[2].sliceSerialize(tail[1], true).length - : 0; - let sizeOpen = 0; - /** @type {NonNullable} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('codeFenced'); - effects.enter('codeFencedFence'); - effects.enter('codeFencedFenceSequence'); - marker = code; - return sequenceOpen(code) - } - /** @type {State} */ - - function sequenceOpen(code) { - if (code === marker) { - effects.consume(code); - sizeOpen++; - return sequenceOpen - } - - effects.exit('codeFencedFenceSequence'); - return sizeOpen < 3 - ? nok(code) - : factorySpace(effects, infoOpen, 'whitespace')(code) - } - /** @type {State} */ - - function infoOpen(code) { - if (code === null || markdownLineEnding(code)) { - return openAfter(code) - } - - effects.enter('codeFencedFenceInfo'); - effects.enter('chunkString', { - contentType: 'string' - }); - return info(code) - } - /** @type {State} */ - - function info(code) { - if (code === null || markdownLineEndingOrSpace(code)) { - effects.exit('chunkString'); - effects.exit('codeFencedFenceInfo'); - return factorySpace(effects, infoAfter, 'whitespace')(code) - } - - if (code === 96 && code === marker) return nok(code) - effects.consume(code); - return info - } - /** @type {State} */ - - function infoAfter(code) { - if (code === null || markdownLineEnding(code)) { - return openAfter(code) - } - - effects.enter('codeFencedFenceMeta'); - effects.enter('chunkString', { - contentType: 'string' - }); - return meta(code) - } - /** @type {State} */ - - function meta(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('chunkString'); - effects.exit('codeFencedFenceMeta'); - return openAfter(code) - } - - if (code === 96 && code === marker) return nok(code) - effects.consume(code); - return meta - } - /** @type {State} */ - - function openAfter(code) { - effects.exit('codeFencedFence'); - return self.interrupt ? ok(code) : contentStart(code) - } - /** @type {State} */ - - function contentStart(code) { - if (code === null) { - return after(code) - } - - if (markdownLineEnding(code)) { - return effects.attempt( - nonLazyLine, - effects.attempt( - closingFenceConstruct, - after, - initialPrefix - ? factorySpace( - effects, - contentStart, - 'linePrefix', - initialPrefix + 1 - ) - : contentStart - ), - after - )(code) - } - - effects.enter('codeFlowValue'); - return contentContinue(code) - } - /** @type {State} */ - - function contentContinue(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('codeFlowValue'); - return contentStart(code) - } - - effects.consume(code); - return contentContinue - } - /** @type {State} */ - - function after(code) { - effects.exit('codeFenced'); - return ok(code) - } - /** @type {Tokenizer} */ - - function tokenizeNonLazyLine(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return lineStart - } - /** @type {State} */ - - function lineStart(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) - } - } - /** @type {Tokenizer} */ - - function tokenizeClosingFence(effects, ok, nok) { - let size = 0; - return factorySpace( - effects, - closingSequenceStart, - 'linePrefix', - this.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - ) - /** @type {State} */ - - function closingSequenceStart(code) { - effects.enter('codeFencedFence'); - effects.enter('codeFencedFenceSequence'); - return closingSequence(code) - } - /** @type {State} */ - - function closingSequence(code) { - if (code === marker) { - effects.consume(code); - size++; - return closingSequence - } - - if (size < sizeOpen) return nok(code) - effects.exit('codeFencedFenceSequence'); - return factorySpace(effects, closingSequenceEnd, 'whitespace')(code) - } - /** @type {State} */ - - function closingSequenceEnd(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('codeFencedFence'); - return ok(code) - } - - return nok(code) - } - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const codeIndented = { - name: 'codeIndented', - tokenize: tokenizeCodeIndented -}; -/** @type {Construct} */ - -const indentedContent = { - tokenize: tokenizeIndentedContent, - partial: true -}; -/** @type {Tokenizer} */ - -function tokenizeCodeIndented(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('codeIndented'); - return factorySpace(effects, afterStartPrefix, 'linePrefix', 4 + 1)(code) - } - /** @type {State} */ - - function afterStartPrefix(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ? afterPrefix(code) - : nok(code) - } - /** @type {State} */ - - function afterPrefix(code) { - if (code === null) { - return after(code) - } - - if (markdownLineEnding(code)) { - return effects.attempt(indentedContent, afterPrefix, after)(code) - } - - effects.enter('codeFlowValue'); - return content(code) - } - /** @type {State} */ - - function content(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('codeFlowValue'); - return afterPrefix(code) - } - - effects.consume(code); - return content - } - /** @type {State} */ - - function after(code) { - effects.exit('codeIndented'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeIndentedContent(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - // If this is a lazy line, it can’t be code. - if (self.parser.lazy[self.now().line]) { - return nok(code) - } - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return start - } - - return factorySpace(effects, afterPrefix, 'linePrefix', 4 + 1)(code) - } - /** @type {State} */ - - function afterPrefix(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ? ok(code) - : markdownLineEnding(code) - ? start(code) - : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Previous} Previous - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const codeText = { - name: 'codeText', - tokenize: tokenizeCodeText, - resolve: resolveCodeText, - previous: previous$1 -}; -/** @type {Resolver} */ - -function resolveCodeText(events) { - let tailExitIndex = events.length - 4; - let headEnterIndex = 3; - /** @type {number} */ - - let index; - /** @type {number|undefined} */ - - let enter; // If we start and end with an EOL or a space. - - if ( - (events[headEnterIndex][1].type === 'lineEnding' || - events[headEnterIndex][1].type === 'space') && - (events[tailExitIndex][1].type === 'lineEnding' || - events[tailExitIndex][1].type === 'space') - ) { - index = headEnterIndex; // And we have data. - - while (++index < tailExitIndex) { - if (events[index][1].type === 'codeTextData') { - // Then we have padding. - events[headEnterIndex][1].type = 'codeTextPadding'; - events[tailExitIndex][1].type = 'codeTextPadding'; - headEnterIndex += 2; - tailExitIndex -= 2; - break - } - } - } // Merge adjacent spaces and data. - - index = headEnterIndex - 1; - tailExitIndex++; - - while (++index <= tailExitIndex) { - if (enter === undefined) { - if (index !== tailExitIndex && events[index][1].type !== 'lineEnding') { - enter = index; - } - } else if ( - index === tailExitIndex || - events[index][1].type === 'lineEnding' - ) { - events[enter][1].type = 'codeTextData'; - - if (index !== enter + 2) { - events[enter][1].end = events[index - 1][1].end; - events.splice(enter + 2, index - enter - 2); - tailExitIndex -= index - enter - 2; - index = enter + 2; - } - - enter = undefined; - } - } - - return events -} -/** @type {Previous} */ - -function previous$1(code) { - // If there is a previous code, there will always be a tail. - return ( - code !== 96 || - this.events[this.events.length - 1][1].type === 'characterEscape' - ) -} -/** @type {Tokenizer} */ - -function tokenizeCodeText(effects, ok, nok) { - let sizeOpen = 0; - /** @type {number} */ - - let size; - /** @type {Token} */ - - let token; - return start - /** @type {State} */ - - function start(code) { - effects.enter('codeText'); - effects.enter('codeTextSequence'); - return openingSequence(code) - } - /** @type {State} */ - - function openingSequence(code) { - if (code === 96) { - effects.consume(code); - sizeOpen++; - return openingSequence - } - - effects.exit('codeTextSequence'); - return gap(code) - } - /** @type {State} */ - - function gap(code) { - // EOF. - if (code === null) { - return nok(code) - } // Closing fence? - // Could also be data. - - if (code === 96) { - token = effects.enter('codeTextSequence'); - size = 0; - return closingSequence(code) - } // Tabs don’t work, and virtual spaces don’t make sense. - - if (code === 32) { - effects.enter('space'); - effects.consume(code); - effects.exit('space'); - return gap - } - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return gap - } // Data. - - effects.enter('codeTextData'); - return data(code) - } // In code. - - /** @type {State} */ - - function data(code) { - if ( - code === null || - code === 32 || - code === 96 || - markdownLineEnding(code) - ) { - effects.exit('codeTextData'); - return gap(code) - } - - effects.consume(code); - return data - } // Closing fence. - - /** @type {State} */ - - function closingSequence(code) { - // More. - if (code === 96) { - effects.consume(code); - size++; - return closingSequence - } // Done! - - if (size === sizeOpen) { - effects.exit('codeTextSequence'); - effects.exit('codeText'); - return ok(code) - } // More or less accents: mark as data. - - token.type = 'codeTextData'; - return data(code) - } -} - -/** - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Chunk} Chunk - * @typedef {import('micromark-util-types').Event} Event - */ - -/** - * Tokenize subcontent. - * - * @param {Event[]} events - * @returns {boolean} - */ -function subtokenize(events) { - /** @type {Record} */ - const jumps = {}; - let index = -1; - /** @type {Event} */ - - let event; - /** @type {number|undefined} */ - - let lineIndex; - /** @type {number} */ - - let otherIndex; - /** @type {Event} */ - - let otherEvent; - /** @type {Event[]} */ - - let parameters; - /** @type {Event[]} */ - - let subevents; - /** @type {boolean|undefined} */ - - let more; - - while (++index < events.length) { - while (index in jumps) { - index = jumps[index]; - } - - event = events[index]; // Add a hook for the GFM tasklist extension, which needs to know if text - // is in the first content of a list item. - - if ( - index && - event[1].type === 'chunkFlow' && - events[index - 1][1].type === 'listItemPrefix' - ) { - subevents = event[1]._tokenizer.events; - otherIndex = 0; - - if ( - otherIndex < subevents.length && - subevents[otherIndex][1].type === 'lineEndingBlank' - ) { - otherIndex += 2; - } - - if ( - otherIndex < subevents.length && - subevents[otherIndex][1].type === 'content' - ) { - while (++otherIndex < subevents.length) { - if (subevents[otherIndex][1].type === 'content') { - break - } - - if (subevents[otherIndex][1].type === 'chunkText') { - subevents[otherIndex][1]._isInFirstContentOfListItem = true; - otherIndex++; - } - } - } - } // Enter. - - if (event[0] === 'enter') { - if (event[1].contentType) { - Object.assign(jumps, subcontent(events, index)); - index = jumps[index]; - more = true; - } - } // Exit. - else if (event[1]._container) { - otherIndex = index; - lineIndex = undefined; - - while (otherIndex--) { - otherEvent = events[otherIndex]; - - if ( - otherEvent[1].type === 'lineEnding' || - otherEvent[1].type === 'lineEndingBlank' - ) { - if (otherEvent[0] === 'enter') { - if (lineIndex) { - events[lineIndex][1].type = 'lineEndingBlank'; - } - - otherEvent[1].type = 'lineEnding'; - lineIndex = otherIndex; - } - } else { - break - } - } - - if (lineIndex) { - // Fix position. - event[1].end = Object.assign({}, events[lineIndex][1].start); // Switch container exit w/ line endings. - - parameters = events.slice(lineIndex, index); - parameters.unshift(event); - splice(events, lineIndex, index - lineIndex + 1, parameters); - } - } - } - - return !more -} -/** - * Tokenize embedded tokens. - * - * @param {Event[]} events - * @param {number} eventIndex - * @returns {Record} - */ - -function subcontent(events, eventIndex) { - const token = events[eventIndex][1]; - const context = events[eventIndex][2]; - let startPosition = eventIndex - 1; - /** @type {number[]} */ - - const startPositions = []; - const tokenizer = - token._tokenizer || context.parser[token.contentType](token.start); - const childEvents = tokenizer.events; - /** @type {[number, number][]} */ - - const jumps = []; - /** @type {Record} */ - - const gaps = {}; - /** @type {Chunk[]} */ - - let stream; - /** @type {Token|undefined} */ - - let previous; - let index = -1; - /** @type {Token|undefined} */ - - let current = token; - let adjust = 0; - let start = 0; - const breaks = [start]; // Loop forward through the linked tokens to pass them in order to the - // subtokenizer. - - while (current) { - // Find the position of the event for this token. - while (events[++startPosition][1] !== current) { - // Empty. - } - - startPositions.push(startPosition); - - if (!current._tokenizer) { - stream = context.sliceStream(current); - - if (!current.next) { - stream.push(null); - } - - if (previous) { - tokenizer.defineSkip(current.start); - } - - if (current._isInFirstContentOfListItem) { - tokenizer._gfmTasklistFirstContentOfListItem = true; - } - - tokenizer.write(stream); - - if (current._isInFirstContentOfListItem) { - tokenizer._gfmTasklistFirstContentOfListItem = undefined; - } - } // Unravel the next token. - - previous = current; - current = current.next; - } // Now, loop back through all events (and linked tokens), to figure out which - // parts belong where. - - current = token; - - while (++index < childEvents.length) { - if ( - // Find a void token that includes a break. - childEvents[index][0] === 'exit' && - childEvents[index - 1][0] === 'enter' && - childEvents[index][1].type === childEvents[index - 1][1].type && - childEvents[index][1].start.line !== childEvents[index][1].end.line - ) { - start = index + 1; - breaks.push(start); // Help GC. - - current._tokenizer = undefined; - current.previous = undefined; - current = current.next; - } - } // Help GC. - - tokenizer.events = []; // If there’s one more token (which is the cases for lines that end in an - // EOF), that’s perfect: the last point we found starts it. - // If there isn’t then make sure any remaining content is added to it. - - if (current) { - // Help GC. - current._tokenizer = undefined; - current.previous = undefined; - } else { - breaks.pop(); - } // Now splice the events from the subtokenizer into the current events, - // moving back to front so that splice indices aren’t affected. - - index = breaks.length; - - while (index--) { - const slice = childEvents.slice(breaks[index], breaks[index + 1]); - const start = startPositions.pop(); - jumps.unshift([start, start + slice.length - 1]); - splice(events, start, 2, slice); - } - - index = -1; - - while (++index < jumps.length) { - gaps[adjust + jumps[index][0]] = adjust + jumps[index][1]; - adjust += jumps[index][1] - jumps[index][0] - 1; - } - - return gaps -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** - * No name because it must not be turned off. - * @type {Construct} - */ -const content = { - tokenize: tokenizeContent, - resolve: resolveContent -}; -/** @type {Construct} */ - -const continuationConstruct = { - tokenize: tokenizeContinuation, - partial: true -}; -/** - * Content is transparent: it’s parsed right now. That way, definitions are also - * parsed right now: before text in paragraphs (specifically, media) are parsed. - * - * @type {Resolver} - */ - -function resolveContent(events) { - subtokenize(events); - return events -} -/** @type {Tokenizer} */ - -function tokenizeContent(effects, ok) { - /** @type {Token} */ - let previous; - return start - /** @type {State} */ - - function start(code) { - effects.enter('content'); - previous = effects.enter('chunkContent', { - contentType: 'content' - }); - return data(code) - } - /** @type {State} */ - - function data(code) { - if (code === null) { - return contentEnd(code) - } - - if (markdownLineEnding(code)) { - return effects.check( - continuationConstruct, - contentContinue, - contentEnd - )(code) - } // Data. - - effects.consume(code); - return data - } - /** @type {State} */ - - function contentEnd(code) { - effects.exit('chunkContent'); - effects.exit('content'); - return ok(code) - } - /** @type {State} */ - - function contentContinue(code) { - effects.consume(code); - effects.exit('chunkContent'); - previous.next = effects.enter('chunkContent', { - contentType: 'content', - previous - }); - previous = previous.next; - return data - } -} -/** @type {Tokenizer} */ - -function tokenizeContinuation(effects, ok, nok) { - const self = this; - return startLookahead - /** @type {State} */ - - function startLookahead(code) { - effects.exit('chunkContent'); - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, prefixed, 'linePrefix') - } - /** @type {State} */ - - function prefixed(code) { - if (code === null || markdownLineEnding(code)) { - return nok(code) - } - - const tail = self.events[self.events.length - 1]; - - if ( - !self.parser.constructs.disable.null.includes('codeIndented') && - tail && - tail[1].type === 'linePrefix' && - tail[2].sliceSerialize(tail[1], true).length >= 4 - ) { - return ok(code) - } - - return effects.interrupt(self.parser.constructs.flow, nok, ok)(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - */ - -/** - * @param {Effects} effects - * @param {State} ok - * @param {State} nok - * @param {string} type - * @param {string} literalType - * @param {string} literalMarkerType - * @param {string} rawType - * @param {string} stringType - * @param {number} [max=Infinity] - * @returns {State} - */ -// eslint-disable-next-line max-params -function factoryDestination( - effects, - ok, - nok, - type, - literalType, - literalMarkerType, - rawType, - stringType, - max -) { - const limit = max || Number.POSITIVE_INFINITY; - let balance = 0; - return start - /** @type {State} */ - - function start(code) { - if (code === 60) { - effects.enter(type); - effects.enter(literalType); - effects.enter(literalMarkerType); - effects.consume(code); - effects.exit(literalMarkerType); - return destinationEnclosedBefore - } - - if (code === null || code === 41 || asciiControl(code)) { - return nok(code) - } - - effects.enter(type); - effects.enter(rawType); - effects.enter(stringType); - effects.enter('chunkString', { - contentType: 'string' - }); - return destinationRaw(code) - } - /** @type {State} */ - - function destinationEnclosedBefore(code) { - if (code === 62) { - effects.enter(literalMarkerType); - effects.consume(code); - effects.exit(literalMarkerType); - effects.exit(literalType); - effects.exit(type); - return ok - } - - effects.enter(stringType); - effects.enter('chunkString', { - contentType: 'string' - }); - return destinationEnclosed(code) - } - /** @type {State} */ - - function destinationEnclosed(code) { - if (code === 62) { - effects.exit('chunkString'); - effects.exit(stringType); - return destinationEnclosedBefore(code) - } - - if (code === null || code === 60 || markdownLineEnding(code)) { - return nok(code) - } - - effects.consume(code); - return code === 92 ? destinationEnclosedEscape : destinationEnclosed - } - /** @type {State} */ - - function destinationEnclosedEscape(code) { - if (code === 60 || code === 62 || code === 92) { - effects.consume(code); - return destinationEnclosed - } - - return destinationEnclosed(code) - } - /** @type {State} */ - - function destinationRaw(code) { - if (code === 40) { - if (++balance > limit) return nok(code) - effects.consume(code); - return destinationRaw - } - - if (code === 41) { - if (!balance--) { - effects.exit('chunkString'); - effects.exit(stringType); - effects.exit(rawType); - effects.exit(type); - return ok(code) - } - - effects.consume(code); - return destinationRaw - } - - if (code === null || markdownLineEndingOrSpace(code)) { - if (balance) return nok(code) - effects.exit('chunkString'); - effects.exit(stringType); - effects.exit(rawType); - effects.exit(type); - return ok(code) - } - - if (asciiControl(code)) return nok(code) - effects.consume(code); - return code === 92 ? destinationRawEscape : destinationRaw - } - /** @type {State} */ - - function destinationRawEscape(code) { - if (code === 40 || code === 41 || code === 92) { - effects.consume(code); - return destinationRaw - } - - return destinationRaw(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').State} State - */ - -/** - * @this {TokenizeContext} - * @param {Effects} effects - * @param {State} ok - * @param {State} nok - * @param {string} type - * @param {string} markerType - * @param {string} stringType - * @returns {State} - */ -// eslint-disable-next-line max-params -function factoryLabel(effects, ok, nok, type, markerType, stringType) { - const self = this; - let size = 0; - /** @type {boolean} */ - - let data; - return start - /** @type {State} */ - - function start(code) { - effects.enter(type); - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - effects.enter(stringType); - return atBreak - } - /** @type {State} */ - - function atBreak(code) { - if ( - code === null || - code === 91 || - (code === 93 && !data) || - /* Hidden footnotes hook */ - - /* c8 ignore next 3 */ - (code === 94 && - !size && - '_hiddenFootnoteSupport' in self.parser.constructs) || - size > 999 - ) { - return nok(code) - } - - if (code === 93) { - effects.exit(stringType); - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - effects.exit(type); - return ok - } - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return atBreak - } - - effects.enter('chunkString', { - contentType: 'string' - }); - return label(code) - } - /** @type {State} */ - - function label(code) { - if ( - code === null || - code === 91 || - code === 93 || - markdownLineEnding(code) || - size++ > 999 - ) { - effects.exit('chunkString'); - return atBreak(code) - } - - effects.consume(code); - data = data || !markdownSpace(code); - return code === 92 ? labelEscape : label - } - /** @type {State} */ - - function labelEscape(code) { - if (code === 91 || code === 92 || code === 93) { - effects.consume(code); - size++; - return label - } - - return label(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** - * @param {Effects} effects - * @param {State} ok - * @param {State} nok - * @param {string} type - * @param {string} markerType - * @param {string} stringType - * @returns {State} - */ -// eslint-disable-next-line max-params -function factoryTitle(effects, ok, nok, type, markerType, stringType) { - /** @type {NonNullable} */ - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter(type); - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - marker = code === 40 ? 41 : code; - return atFirstTitleBreak - } - /** @type {State} */ - - function atFirstTitleBreak(code) { - if (code === marker) { - effects.enter(markerType); - effects.consume(code); - effects.exit(markerType); - effects.exit(type); - return ok - } - - effects.enter(stringType); - return atTitleBreak(code) - } - /** @type {State} */ - - function atTitleBreak(code) { - if (code === marker) { - effects.exit(stringType); - return atFirstTitleBreak(marker) - } - - if (code === null) { - return nok(code) - } // Note: blank lines can’t exist in content. - - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, atTitleBreak, 'linePrefix') - } - - effects.enter('chunkString', { - contentType: 'string' - }); - return title(code) - } - /** @type {State} */ - - function title(code) { - if (code === marker || code === null || markdownLineEnding(code)) { - effects.exit('chunkString'); - return atTitleBreak(code) - } - - effects.consume(code); - return code === 92 ? titleEscape : title - } - /** @type {State} */ - - function titleEscape(code) { - if (code === marker || code === 92) { - effects.consume(code); - return title - } - - return title(code) - } -} - -/** - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - */ - -/** - * @param {Effects} effects - * @param {State} ok - */ -function factoryWhitespace(effects, ok) { - /** @type {boolean} */ - let seen; - return start - /** @type {State} */ - - function start(code) { - if (markdownLineEnding(code)) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - seen = true; - return start - } - - if (markdownSpace(code)) { - return factorySpace( - effects, - start, - seen ? 'linePrefix' : 'lineSuffix' - )(code) - } - - return ok(code) - } -} - -/** - * Normalize an identifier (such as used in definitions). - * - * @param {string} value - * @returns {string} - */ -function normalizeIdentifier(value) { - return ( - value // Collapse Markdown whitespace. - .replace(/[\t\n\r ]+/g, ' ') // Trim. - .replace(/^ | $/g, '') // Some characters are considered “uppercase”, but if their lowercase - // counterpart is uppercased will result in a different uppercase - // character. - // Hence, to get that form, we perform both lower- and uppercase. - // Upper case makes sure keys will not interact with default prototypal - // methods: no method is uppercase. - .toLowerCase() - .toUpperCase() - ) -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const definition$1 = { - name: 'definition', - tokenize: tokenizeDefinition -}; -/** @type {Construct} */ - -const titleConstruct = { - tokenize: tokenizeTitle, - partial: true -}; -/** @type {Tokenizer} */ - -function tokenizeDefinition(effects, ok, nok) { - const self = this; - /** @type {string} */ - - let identifier; - return start - /** @type {State} */ - - function start(code) { - effects.enter('definition'); - return factoryLabel.call( - self, - effects, - labelAfter, - nok, - 'definitionLabel', - 'definitionLabelMarker', - 'definitionLabelString' - )(code) - } - /** @type {State} */ - - function labelAfter(code) { - identifier = normalizeIdentifier( - self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) - ); - - if (code === 58) { - effects.enter('definitionMarker'); - effects.consume(code); - effects.exit('definitionMarker'); // Note: blank lines can’t exist in content. - - return factoryWhitespace( - effects, - factoryDestination( - effects, - effects.attempt( - titleConstruct, - factorySpace(effects, after, 'whitespace'), - factorySpace(effects, after, 'whitespace') - ), - nok, - 'definitionDestination', - 'definitionDestinationLiteral', - 'definitionDestinationLiteralMarker', - 'definitionDestinationRaw', - 'definitionDestinationString' - ) - ) - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('definition'); - - if (!self.parser.defined.includes(identifier)) { - self.parser.defined.push(identifier); - } - - return ok(code) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeTitle(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, before)(code) - : nok(code) - } - /** @type {State} */ - - function before(code) { - if (code === 34 || code === 39 || code === 40) { - return factoryTitle( - effects, - factorySpace(effects, after, 'whitespace'), - nok, - 'definitionTitle', - 'definitionTitleMarker', - 'definitionTitleString' - )(code) - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - return code === null || markdownLineEnding(code) ? ok(code) : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const hardBreakEscape = { - name: 'hardBreakEscape', - tokenize: tokenizeHardBreakEscape -}; -/** @type {Tokenizer} */ - -function tokenizeHardBreakEscape(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('hardBreakEscape'); - effects.enter('escapeMarker'); - effects.consume(code); - return open - } - /** @type {State} */ - - function open(code) { - if (markdownLineEnding(code)) { - effects.exit('escapeMarker'); - effects.exit('hardBreakEscape'); - return ok(code) - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const headingAtx = { - name: 'headingAtx', - tokenize: tokenizeHeadingAtx, - resolve: resolveHeadingAtx -}; -/** @type {Resolver} */ - -function resolveHeadingAtx(events, context) { - let contentEnd = events.length - 2; - let contentStart = 3; - /** @type {Token} */ - - let content; - /** @type {Token} */ - - let text; // Prefix whitespace, part of the opening. - - if (events[contentStart][1].type === 'whitespace') { - contentStart += 2; - } // Suffix whitespace, part of the closing. - - if ( - contentEnd - 2 > contentStart && - events[contentEnd][1].type === 'whitespace' - ) { - contentEnd -= 2; - } - - if ( - events[contentEnd][1].type === 'atxHeadingSequence' && - (contentStart === contentEnd - 1 || - (contentEnd - 4 > contentStart && - events[contentEnd - 2][1].type === 'whitespace')) - ) { - contentEnd -= contentStart + 1 === contentEnd ? 2 : 4; - } - - if (contentEnd > contentStart) { - content = { - type: 'atxHeadingText', - start: events[contentStart][1].start, - end: events[contentEnd][1].end - }; - text = { - type: 'chunkText', - start: events[contentStart][1].start, - end: events[contentEnd][1].end, - // @ts-expect-error Constants are fine to assign. - contentType: 'text' - }; - splice(events, contentStart, contentEnd - contentStart + 1, [ - ['enter', content, context], - ['enter', text, context], - ['exit', text, context], - ['exit', content, context] - ]); - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeHeadingAtx(effects, ok, nok) { - const self = this; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - effects.enter('atxHeading'); - effects.enter('atxHeadingSequence'); - return fenceOpenInside(code) - } - /** @type {State} */ - - function fenceOpenInside(code) { - if (code === 35 && size++ < 6) { - effects.consume(code); - return fenceOpenInside - } - - if (code === null || markdownLineEndingOrSpace(code)) { - effects.exit('atxHeadingSequence'); - return self.interrupt ? ok(code) : headingBreak(code) - } - - return nok(code) - } - /** @type {State} */ - - function headingBreak(code) { - if (code === 35) { - effects.enter('atxHeadingSequence'); - return sequence(code) - } - - if (code === null || markdownLineEnding(code)) { - effects.exit('atxHeading'); - return ok(code) - } - - if (markdownSpace(code)) { - return factorySpace(effects, headingBreak, 'whitespace')(code) - } - - effects.enter('atxHeadingText'); - return data(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === 35) { - effects.consume(code); - return sequence - } - - effects.exit('atxHeadingSequence'); - return headingBreak(code) - } - /** @type {State} */ - - function data(code) { - if (code === null || code === 35 || markdownLineEndingOrSpace(code)) { - effects.exit('atxHeadingText'); - return headingBreak(code) - } - - effects.consume(code); - return data - } -} - -/** - * List of lowercase HTML tag names which when parsing HTML (flow), result - * in more relaxed rules (condition 6): because they are known blocks, the - * HTML-like syntax doesn’t have to be strictly parsed. - * For tag names not in this list, a more strict algorithm (condition 7) is used - * to detect whether the HTML-like syntax is seen as HTML (flow) or not. - * - * This is copied from: - * . - */ -const htmlBlockNames = [ - 'address', - 'article', - 'aside', - 'base', - 'basefont', - 'blockquote', - 'body', - 'caption', - 'center', - 'col', - 'colgroup', - 'dd', - 'details', - 'dialog', - 'dir', - 'div', - 'dl', - 'dt', - 'fieldset', - 'figcaption', - 'figure', - 'footer', - 'form', - 'frame', - 'frameset', - 'h1', - 'h2', - 'h3', - 'h4', - 'h5', - 'h6', - 'head', - 'header', - 'hr', - 'html', - 'iframe', - 'legend', - 'li', - 'link', - 'main', - 'menu', - 'menuitem', - 'nav', - 'noframes', - 'ol', - 'optgroup', - 'option', - 'p', - 'param', - 'section', - 'source', - 'summary', - 'table', - 'tbody', - 'td', - 'tfoot', - 'th', - 'thead', - 'title', - 'tr', - 'track', - 'ul' -]; - -/** - * List of lowercase HTML tag names which when parsing HTML (flow), result in - * HTML that can include lines w/o exiting, until a closing tag also in this - * list is found (condition 1). - * - * This module is copied from: - * . - * - * Note that `textarea` is not available in `CommonMark@0.29` but has been - * merged to the primary branch and is slated to be released in the next release - * of CommonMark. - */ -const htmlRawNames = ['pre', 'script', 'style', 'textarea']; - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ -/** @type {Construct} */ - -const htmlFlow = { - name: 'htmlFlow', - tokenize: tokenizeHtmlFlow, - resolveTo: resolveToHtmlFlow, - concrete: true -}; -/** @type {Construct} */ - -const nextBlankConstruct = { - tokenize: tokenizeNextBlank, - partial: true -}; -/** @type {Resolver} */ - -function resolveToHtmlFlow(events) { - let index = events.length; - - while (index--) { - if (events[index][0] === 'enter' && events[index][1].type === 'htmlFlow') { - break - } - } - - if (index > 1 && events[index - 2][1].type === 'linePrefix') { - // Add the prefix start to the HTML token. - events[index][1].start = events[index - 2][1].start; // Add the prefix start to the HTML line token. - - events[index + 1][1].start = events[index - 2][1].start; // Remove the line prefix. - - events.splice(index - 2, 2); - } - - return events -} -/** @type {Tokenizer} */ - -function tokenizeHtmlFlow(effects, ok, nok) { - const self = this; - /** @type {number} */ - - let kind; - /** @type {boolean} */ - - let startTag; - /** @type {string} */ - - let buffer; - /** @type {number} */ - - let index; - /** @type {Code} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('htmlFlow'); - effects.enter('htmlFlowData'); - effects.consume(code); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 33) { - effects.consume(code); - return declarationStart - } - - if (code === 47) { - effects.consume(code); - return tagCloseStart - } - - if (code === 63) { - effects.consume(code); - kind = 3; // While we’re in an instruction instead of a declaration, we’re on a `?` - // right now, so we do need to search for `>`, similar to declarations. - - return self.interrupt ? ok : continuationDeclarationInside - } - - if (asciiAlpha(code)) { - effects.consume(code); - buffer = String.fromCharCode(code); - startTag = true; - return tagName - } - - return nok(code) - } - /** @type {State} */ - - function declarationStart(code) { - if (code === 45) { - effects.consume(code); - kind = 2; - return commentOpenInside - } - - if (code === 91) { - effects.consume(code); - kind = 5; - buffer = 'CDATA['; - index = 0; - return cdataOpenInside - } - - if (asciiAlpha(code)) { - effects.consume(code); - kind = 4; - return self.interrupt ? ok : continuationDeclarationInside - } - - return nok(code) - } - /** @type {State} */ - - function commentOpenInside(code) { - if (code === 45) { - effects.consume(code); - return self.interrupt ? ok : continuationDeclarationInside - } - - return nok(code) - } - /** @type {State} */ - - function cdataOpenInside(code) { - if (code === buffer.charCodeAt(index++)) { - effects.consume(code); - return index === buffer.length - ? self.interrupt - ? ok - : continuation - : cdataOpenInside - } - - return nok(code) - } - /** @type {State} */ - - function tagCloseStart(code) { - if (asciiAlpha(code)) { - effects.consume(code); - buffer = String.fromCharCode(code); - return tagName - } - - return nok(code) - } - /** @type {State} */ - - function tagName(code) { - if ( - code === null || - code === 47 || - code === 62 || - markdownLineEndingOrSpace(code) - ) { - if ( - code !== 47 && - startTag && - htmlRawNames.includes(buffer.toLowerCase()) - ) { - kind = 1; - return self.interrupt ? ok(code) : continuation(code) - } - - if (htmlBlockNames.includes(buffer.toLowerCase())) { - kind = 6; - - if (code === 47) { - effects.consume(code); - return basicSelfClosing - } - - return self.interrupt ? ok(code) : continuation(code) - } - - kind = 7; // Do not support complete HTML when interrupting - - return self.interrupt && !self.parser.lazy[self.now().line] - ? nok(code) - : startTag - ? completeAttributeNameBefore(code) - : completeClosingTagAfter(code) - } - - if (code === 45 || asciiAlphanumeric(code)) { - effects.consume(code); - buffer += String.fromCharCode(code); - return tagName - } - - return nok(code) - } - /** @type {State} */ - - function basicSelfClosing(code) { - if (code === 62) { - effects.consume(code); - return self.interrupt ? ok : continuation - } - - return nok(code) - } - /** @type {State} */ - - function completeClosingTagAfter(code) { - if (markdownSpace(code)) { - effects.consume(code); - return completeClosingTagAfter - } - - return completeEnd(code) - } - /** @type {State} */ - - function completeAttributeNameBefore(code) { - if (code === 47) { - effects.consume(code); - return completeEnd - } - - if (code === 58 || code === 95 || asciiAlpha(code)) { - effects.consume(code); - return completeAttributeName - } - - if (markdownSpace(code)) { - effects.consume(code); - return completeAttributeNameBefore - } - - return completeEnd(code) - } - /** @type {State} */ - - function completeAttributeName(code) { - if ( - code === 45 || - code === 46 || - code === 58 || - code === 95 || - asciiAlphanumeric(code) - ) { - effects.consume(code); - return completeAttributeName - } - - return completeAttributeNameAfter(code) - } - /** @type {State} */ - - function completeAttributeNameAfter(code) { - if (code === 61) { - effects.consume(code); - return completeAttributeValueBefore - } - - if (markdownSpace(code)) { - effects.consume(code); - return completeAttributeNameAfter - } - - return completeAttributeNameBefore(code) - } - /** @type {State} */ - - function completeAttributeValueBefore(code) { - if ( - code === null || - code === 60 || - code === 61 || - code === 62 || - code === 96 - ) { - return nok(code) - } - - if (code === 34 || code === 39) { - effects.consume(code); - marker = code; - return completeAttributeValueQuoted - } - - if (markdownSpace(code)) { - effects.consume(code); - return completeAttributeValueBefore - } - - marker = null; - return completeAttributeValueUnquoted(code) - } - /** @type {State} */ - - function completeAttributeValueQuoted(code) { - if (code === null || markdownLineEnding(code)) { - return nok(code) - } - - if (code === marker) { - effects.consume(code); - return completeAttributeValueQuotedAfter - } - - effects.consume(code); - return completeAttributeValueQuoted - } - /** @type {State} */ - - function completeAttributeValueUnquoted(code) { - if ( - code === null || - code === 34 || - code === 39 || - code === 60 || - code === 61 || - code === 62 || - code === 96 || - markdownLineEndingOrSpace(code) - ) { - return completeAttributeNameAfter(code) - } - - effects.consume(code); - return completeAttributeValueUnquoted - } - /** @type {State} */ - - function completeAttributeValueQuotedAfter(code) { - if (code === 47 || code === 62 || markdownSpace(code)) { - return completeAttributeNameBefore(code) - } - - return nok(code) - } - /** @type {State} */ - - function completeEnd(code) { - if (code === 62) { - effects.consume(code); - return completeAfter - } - - return nok(code) - } - /** @type {State} */ - - function completeAfter(code) { - if (markdownSpace(code)) { - effects.consume(code); - return completeAfter - } - - return code === null || markdownLineEnding(code) - ? continuation(code) - : nok(code) - } - /** @type {State} */ - - function continuation(code) { - if (code === 45 && kind === 2) { - effects.consume(code); - return continuationCommentInside - } - - if (code === 60 && kind === 1) { - effects.consume(code); - return continuationRawTagOpen - } - - if (code === 62 && kind === 4) { - effects.consume(code); - return continuationClose - } - - if (code === 63 && kind === 3) { - effects.consume(code); - return continuationDeclarationInside - } - - if (code === 93 && kind === 5) { - effects.consume(code); - return continuationCharacterDataInside - } - - if (markdownLineEnding(code) && (kind === 6 || kind === 7)) { - return effects.check( - nextBlankConstruct, - continuationClose, - continuationAtLineEnding - )(code) - } - - if (code === null || markdownLineEnding(code)) { - return continuationAtLineEnding(code) - } - - effects.consume(code); - return continuation - } - /** @type {State} */ - - function continuationAtLineEnding(code) { - effects.exit('htmlFlowData'); - return htmlContinueStart(code) - } - /** @type {State} */ - - function htmlContinueStart(code) { - if (code === null) { - return done(code) - } - - if (markdownLineEnding(code)) { - return effects.attempt( - { - tokenize: htmlLineEnd, - partial: true - }, - htmlContinueStart, - done - )(code) - } - - effects.enter('htmlFlowData'); - return continuation(code) - } - /** @type {Tokenizer} */ - - function htmlLineEnd(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return lineStart - } - /** @type {State} */ - - function lineStart(code) { - return self.parser.lazy[self.now().line] ? nok(code) : ok(code) - } - } - /** @type {State} */ - - function continuationCommentInside(code) { - if (code === 45) { - effects.consume(code); - return continuationDeclarationInside - } - - return continuation(code) - } - /** @type {State} */ - - function continuationRawTagOpen(code) { - if (code === 47) { - effects.consume(code); - buffer = ''; - return continuationRawEndTag - } - - return continuation(code) - } - /** @type {State} */ - - function continuationRawEndTag(code) { - if (code === 62 && htmlRawNames.includes(buffer.toLowerCase())) { - effects.consume(code); - return continuationClose - } - - if (asciiAlpha(code) && buffer.length < 8) { - effects.consume(code); - buffer += String.fromCharCode(code); - return continuationRawEndTag - } - - return continuation(code) - } - /** @type {State} */ - - function continuationCharacterDataInside(code) { - if (code === 93) { - effects.consume(code); - return continuationDeclarationInside - } - - return continuation(code) - } - /** @type {State} */ - - function continuationDeclarationInside(code) { - if (code === 62) { - effects.consume(code); - return continuationClose - } - - return continuation(code) - } - /** @type {State} */ - - function continuationClose(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('htmlFlowData'); - return done(code) - } - - effects.consume(code); - return continuationClose - } - /** @type {State} */ - - function done(code) { - effects.exit('htmlFlow'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeNextBlank(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.exit('htmlFlowData'); - effects.enter('lineEndingBlank'); - effects.consume(code); - effects.exit('lineEndingBlank'); - return effects.attempt(blankLine, ok, nok) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const htmlText = { - name: 'htmlText', - tokenize: tokenizeHtmlText -}; -/** @type {Tokenizer} */ - -function tokenizeHtmlText(effects, ok, nok) { - const self = this; - /** @type {NonNullable|undefined} */ - - let marker; - /** @type {string} */ - - let buffer; - /** @type {number} */ - - let index; - /** @type {State} */ - - let returnState; - return start - /** @type {State} */ - - function start(code) { - effects.enter('htmlText'); - effects.enter('htmlTextData'); - effects.consume(code); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 33) { - effects.consume(code); - return declarationOpen - } - - if (code === 47) { - effects.consume(code); - return tagCloseStart - } - - if (code === 63) { - effects.consume(code); - return instruction - } - - if (asciiAlpha(code)) { - effects.consume(code); - return tagOpen - } - - return nok(code) - } - /** @type {State} */ - - function declarationOpen(code) { - if (code === 45) { - effects.consume(code); - return commentOpen - } - - if (code === 91) { - effects.consume(code); - buffer = 'CDATA['; - index = 0; - return cdataOpen - } - - if (asciiAlpha(code)) { - effects.consume(code); - return declaration - } - - return nok(code) - } - /** @type {State} */ - - function commentOpen(code) { - if (code === 45) { - effects.consume(code); - return commentStart - } - - return nok(code) - } - /** @type {State} */ - - function commentStart(code) { - if (code === null || code === 62) { - return nok(code) - } - - if (code === 45) { - effects.consume(code); - return commentStartDash - } - - return comment(code) - } - /** @type {State} */ - - function commentStartDash(code) { - if (code === null || code === 62) { - return nok(code) - } - - return comment(code) - } - /** @type {State} */ - - function comment(code) { - if (code === null) { - return nok(code) - } - - if (code === 45) { - effects.consume(code); - return commentClose - } - - if (markdownLineEnding(code)) { - returnState = comment; - return atLineEnding(code) - } - - effects.consume(code); - return comment - } - /** @type {State} */ - - function commentClose(code) { - if (code === 45) { - effects.consume(code); - return end - } - - return comment(code) - } - /** @type {State} */ - - function cdataOpen(code) { - if (code === buffer.charCodeAt(index++)) { - effects.consume(code); - return index === buffer.length ? cdata : cdataOpen - } - - return nok(code) - } - /** @type {State} */ - - function cdata(code) { - if (code === null) { - return nok(code) - } - - if (code === 93) { - effects.consume(code); - return cdataClose - } - - if (markdownLineEnding(code)) { - returnState = cdata; - return atLineEnding(code) - } - - effects.consume(code); - return cdata - } - /** @type {State} */ - - function cdataClose(code) { - if (code === 93) { - effects.consume(code); - return cdataEnd - } - - return cdata(code) - } - /** @type {State} */ - - function cdataEnd(code) { - if (code === 62) { - return end(code) - } - - if (code === 93) { - effects.consume(code); - return cdataEnd - } - - return cdata(code) - } - /** @type {State} */ - - function declaration(code) { - if (code === null || code === 62) { - return end(code) - } - - if (markdownLineEnding(code)) { - returnState = declaration; - return atLineEnding(code) - } - - effects.consume(code); - return declaration - } - /** @type {State} */ - - function instruction(code) { - if (code === null) { - return nok(code) - } - - if (code === 63) { - effects.consume(code); - return instructionClose - } - - if (markdownLineEnding(code)) { - returnState = instruction; - return atLineEnding(code) - } - - effects.consume(code); - return instruction - } - /** @type {State} */ - - function instructionClose(code) { - return code === 62 ? end(code) : instruction(code) - } - /** @type {State} */ - - function tagCloseStart(code) { - if (asciiAlpha(code)) { - effects.consume(code); - return tagClose - } - - return nok(code) - } - /** @type {State} */ - - function tagClose(code) { - if (code === 45 || asciiAlphanumeric(code)) { - effects.consume(code); - return tagClose - } - - return tagCloseBetween(code) - } - /** @type {State} */ - - function tagCloseBetween(code) { - if (markdownLineEnding(code)) { - returnState = tagCloseBetween; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagCloseBetween - } - - return end(code) - } - /** @type {State} */ - - function tagOpen(code) { - if (code === 45 || asciiAlphanumeric(code)) { - effects.consume(code); - return tagOpen - } - - if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) - } - - return nok(code) - } - /** @type {State} */ - - function tagOpenBetween(code) { - if (code === 47) { - effects.consume(code); - return end - } - - if (code === 58 || code === 95 || asciiAlpha(code)) { - effects.consume(code); - return tagOpenAttributeName - } - - if (markdownLineEnding(code)) { - returnState = tagOpenBetween; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagOpenBetween - } - - return end(code) - } - /** @type {State} */ - - function tagOpenAttributeName(code) { - if ( - code === 45 || - code === 46 || - code === 58 || - code === 95 || - asciiAlphanumeric(code) - ) { - effects.consume(code); - return tagOpenAttributeName - } - - return tagOpenAttributeNameAfter(code) - } - /** @type {State} */ - - function tagOpenAttributeNameAfter(code) { - if (code === 61) { - effects.consume(code); - return tagOpenAttributeValueBefore - } - - if (markdownLineEnding(code)) { - returnState = tagOpenAttributeNameAfter; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagOpenAttributeNameAfter - } - - return tagOpenBetween(code) - } - /** @type {State} */ - - function tagOpenAttributeValueBefore(code) { - if ( - code === null || - code === 60 || - code === 61 || - code === 62 || - code === 96 - ) { - return nok(code) - } - - if (code === 34 || code === 39) { - effects.consume(code); - marker = code; - return tagOpenAttributeValueQuoted - } - - if (markdownLineEnding(code)) { - returnState = tagOpenAttributeValueBefore; - return atLineEnding(code) - } - - if (markdownSpace(code)) { - effects.consume(code); - return tagOpenAttributeValueBefore - } - - effects.consume(code); - marker = undefined; - return tagOpenAttributeValueUnquoted - } - /** @type {State} */ - - function tagOpenAttributeValueQuoted(code) { - if (code === marker) { - effects.consume(code); - return tagOpenAttributeValueQuotedAfter - } - - if (code === null) { - return nok(code) - } - - if (markdownLineEnding(code)) { - returnState = tagOpenAttributeValueQuoted; - return atLineEnding(code) - } - - effects.consume(code); - return tagOpenAttributeValueQuoted - } - /** @type {State} */ - - function tagOpenAttributeValueQuotedAfter(code) { - if (code === 62 || code === 47 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) - } - - return nok(code) - } - /** @type {State} */ - - function tagOpenAttributeValueUnquoted(code) { - if ( - code === null || - code === 34 || - code === 39 || - code === 60 || - code === 61 || - code === 96 - ) { - return nok(code) - } - - if (code === 62 || markdownLineEndingOrSpace(code)) { - return tagOpenBetween(code) - } - - effects.consume(code); - return tagOpenAttributeValueUnquoted - } // We can’t have blank lines in content, so no need to worry about empty - // tokens. - - /** @type {State} */ - - function atLineEnding(code) { - effects.exit('htmlTextData'); - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace( - effects, - afterPrefix, - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - ) - } - /** @type {State} */ - - function afterPrefix(code) { - effects.enter('htmlTextData'); - return returnState(code) - } - /** @type {State} */ - - function end(code) { - if (code === 62) { - effects.consume(code); - effects.exit('htmlTextData'); - effects.exit('htmlText'); - return ok - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const labelEnd = { - name: 'labelEnd', - tokenize: tokenizeLabelEnd, - resolveTo: resolveToLabelEnd, - resolveAll: resolveAllLabelEnd -}; -/** @type {Construct} */ - -const resourceConstruct = { - tokenize: tokenizeResource -}; -/** @type {Construct} */ - -const fullReferenceConstruct = { - tokenize: tokenizeFullReference -}; -/** @type {Construct} */ - -const collapsedReferenceConstruct = { - tokenize: tokenizeCollapsedReference -}; -/** @type {Resolver} */ - -function resolveAllLabelEnd(events) { - let index = -1; - /** @type {Token} */ - - let token; - - while (++index < events.length) { - token = events[index][1]; - - if ( - token.type === 'labelImage' || - token.type === 'labelLink' || - token.type === 'labelEnd' - ) { - // Remove the marker. - events.splice(index + 1, token.type === 'labelImage' ? 4 : 2); - token.type = 'data'; - index++; - } - } - - return events -} -/** @type {Resolver} */ - -function resolveToLabelEnd(events, context) { - let index = events.length; - let offset = 0; - /** @type {Token} */ - - let token; - /** @type {number|undefined} */ - - let open; - /** @type {number|undefined} */ - - let close; - /** @type {Event[]} */ - - let media; // Find an opening. - - while (index--) { - token = events[index][1]; - - if (open) { - // If we see another link, or inactive link label, we’ve been here before. - if ( - token.type === 'link' || - (token.type === 'labelLink' && token._inactive) - ) { - break - } // Mark other link openings as inactive, as we can’t have links in - // links. - - if (events[index][0] === 'enter' && token.type === 'labelLink') { - token._inactive = true; - } - } else if (close) { - if ( - events[index][0] === 'enter' && - (token.type === 'labelImage' || token.type === 'labelLink') && - !token._balanced - ) { - open = index; - - if (token.type !== 'labelLink') { - offset = 2; - break - } - } - } else if (token.type === 'labelEnd') { - close = index; - } - } - - const group = { - type: events[open][1].type === 'labelLink' ? 'link' : 'image', - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[events.length - 1][1].end) - }; - const label = { - type: 'label', - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[close][1].end) - }; - const text = { - type: 'labelText', - start: Object.assign({}, events[open + offset + 2][1].end), - end: Object.assign({}, events[close - 2][1].start) - }; - media = [ - ['enter', group, context], - ['enter', label, context] - ]; // Opening marker. - - media = push(media, events.slice(open + 1, open + offset + 3)); // Text open. - - media = push(media, [['enter', text, context]]); // Between. - - media = push( - media, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + offset + 4, close - 3), - context - ) - ); // Text close, marker close, label close. - - media = push(media, [ - ['exit', text, context], - events[close - 2], - events[close - 1], - ['exit', label, context] - ]); // Reference, resource, or so. - - media = push(media, events.slice(close + 1)); // Media close. - - media = push(media, [['exit', group, context]]); - splice(events, open, events.length, media); - return events -} -/** @type {Tokenizer} */ - -function tokenizeLabelEnd(effects, ok, nok) { - const self = this; - let index = self.events.length; - /** @type {Token} */ - - let labelStart; - /** @type {boolean} */ - - let defined; // Find an opening. - - while (index--) { - if ( - (self.events[index][1].type === 'labelImage' || - self.events[index][1].type === 'labelLink') && - !self.events[index][1]._balanced - ) { - labelStart = self.events[index][1]; - break - } - } - - return start - /** @type {State} */ - - function start(code) { - if (!labelStart) { - return nok(code) - } // It’s a balanced bracket, but contains a link. - - if (labelStart._inactive) return balanced(code) - defined = self.parser.defined.includes( - normalizeIdentifier( - self.sliceSerialize({ - start: labelStart.end, - end: self.now() - }) - ) - ); - effects.enter('labelEnd'); - effects.enter('labelMarker'); - effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelEnd'); - return afterLabelEnd - } - /** @type {State} */ - - function afterLabelEnd(code) { - // Resource: `[asd](fgh)`. - if (code === 40) { - return effects.attempt( - resourceConstruct, - ok, - defined ? ok : balanced - )(code) - } // Collapsed (`[asd][]`) or full (`[asd][fgh]`) reference? - - if (code === 91) { - return effects.attempt( - fullReferenceConstruct, - ok, - defined - ? effects.attempt(collapsedReferenceConstruct, ok, balanced) - : balanced - )(code) - } // Shortcut reference: `[asd]`? - - return defined ? ok(code) : balanced(code) - } - /** @type {State} */ - - function balanced(code) { - labelStart._balanced = true; - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeResource(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('resource'); - effects.enter('resourceMarker'); - effects.consume(code); - effects.exit('resourceMarker'); - return factoryWhitespace(effects, open) - } - /** @type {State} */ - - function open(code) { - if (code === 41) { - return end(code) - } - - return factoryDestination( - effects, - destinationAfter, - nok, - 'resourceDestination', - 'resourceDestinationLiteral', - 'resourceDestinationLiteralMarker', - 'resourceDestinationRaw', - 'resourceDestinationString', - 3 - )(code) - } - /** @type {State} */ - - function destinationAfter(code) { - return markdownLineEndingOrSpace(code) - ? factoryWhitespace(effects, between)(code) - : end(code) - } - /** @type {State} */ - - function between(code) { - if (code === 34 || code === 39 || code === 40) { - return factoryTitle( - effects, - factoryWhitespace(effects, end), - nok, - 'resourceTitle', - 'resourceTitleMarker', - 'resourceTitleString' - )(code) - } - - return end(code) - } - /** @type {State} */ - - function end(code) { - if (code === 41) { - effects.enter('resourceMarker'); - effects.consume(code); - effects.exit('resourceMarker'); - effects.exit('resource'); - return ok - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeFullReference(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - return factoryLabel.call( - self, - effects, - afterLabel, - nok, - 'reference', - 'referenceMarker', - 'referenceString' - )(code) - } - /** @type {State} */ - - function afterLabel(code) { - return self.parser.defined.includes( - normalizeIdentifier( - self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1) - ) - ) - ? ok(code) - : nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeCollapsedReference(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('reference'); - effects.enter('referenceMarker'); - effects.consume(code); - effects.exit('referenceMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 93) { - effects.enter('referenceMarker'); - effects.consume(code); - effects.exit('referenceMarker'); - effects.exit('reference'); - return ok - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ -/** @type {Construct} */ - -const labelStartImage = { - name: 'labelStartImage', - tokenize: tokenizeLabelStartImage, - resolveAll: labelEnd.resolveAll -}; -/** @type {Tokenizer} */ - -function tokenizeLabelStartImage(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('labelImage'); - effects.enter('labelImageMarker'); - effects.consume(code); - effects.exit('labelImageMarker'); - return open - } - /** @type {State} */ - - function open(code) { - if (code === 91) { - effects.enter('labelMarker'); - effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelImage'); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - /* Hidden footnotes hook */ - - /* c8 ignore next 3 */ - return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs - ? nok(code) - : ok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ -/** @type {Construct} */ - -const labelStartLink = { - name: 'labelStartLink', - tokenize: tokenizeLabelStartLink, - resolveAll: labelEnd.resolveAll -}; -/** @type {Tokenizer} */ - -function tokenizeLabelStartLink(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - effects.enter('labelLink'); - effects.enter('labelMarker'); - effects.consume(code); - effects.exit('labelMarker'); - effects.exit('labelLink'); - return after - } - /** @type {State} */ - - function after(code) { - /* Hidden footnotes hook. */ - - /* c8 ignore next 3 */ - return code === 94 && '_hiddenFootnoteSupport' in self.parser.constructs - ? nok(code) - : ok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {Construct} */ -const lineEnding = { - name: 'lineEnding', - tokenize: tokenizeLineEnding -}; -/** @type {Tokenizer} */ - -function tokenizeLineEnding(effects, ok) { - return start - /** @type {State} */ - - function start(code) { - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - return factorySpace(effects, ok, 'linePrefix') - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const thematicBreak$1 = { - name: 'thematicBreak', - tokenize: tokenizeThematicBreak -}; -/** @type {Tokenizer} */ - -function tokenizeThematicBreak(effects, ok, nok) { - let size = 0; - /** @type {NonNullable} */ - - let marker; - return start - /** @type {State} */ - - function start(code) { - effects.enter('thematicBreak'); - marker = code; - return atBreak(code) - } - /** @type {State} */ - - function atBreak(code) { - if (code === marker) { - effects.enter('thematicBreakSequence'); - return sequence(code) - } - - if (markdownSpace(code)) { - return factorySpace(effects, atBreak, 'whitespace')(code) - } - - if (size < 3 || (code !== null && !markdownLineEnding(code))) { - return nok(code) - } - - effects.exit('thematicBreak'); - return ok(code) - } - /** @type {State} */ - - function sequence(code) { - if (code === marker) { - effects.consume(code); - size++; - return sequence - } - - effects.exit('thematicBreakSequence'); - return atBreak(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Exiter} Exiter - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ -/** @type {Construct} */ - -const list$1 = { - name: 'list', - tokenize: tokenizeListStart, - continuation: { - tokenize: tokenizeListContinuation - }, - exit: tokenizeListEnd -}; -/** @type {Construct} */ - -const listItemPrefixWhitespaceConstruct = { - tokenize: tokenizeListItemPrefixWhitespace, - partial: true -}; -/** @type {Construct} */ - -const indentConstruct = { - tokenize: tokenizeIndent, - partial: true -}; -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeListStart(effects, ok, nok) { - const self = this; - const tail = self.events[self.events.length - 1]; - let initialSize = - tail && tail[1].type === 'linePrefix' - ? tail[2].sliceSerialize(tail[1], true).length - : 0; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - const kind = - self.containerState.type || - (code === 42 || code === 43 || code === 45 - ? 'listUnordered' - : 'listOrdered'); - - if ( - kind === 'listUnordered' - ? !self.containerState.marker || code === self.containerState.marker - : asciiDigit(code) - ) { - if (!self.containerState.type) { - self.containerState.type = kind; - effects.enter(kind, { - _container: true - }); - } - - if (kind === 'listUnordered') { - effects.enter('listItemPrefix'); - return code === 42 || code === 45 - ? effects.check(thematicBreak$1, nok, atMarker)(code) - : atMarker(code) - } - - if (!self.interrupt || code === 49) { - effects.enter('listItemPrefix'); - effects.enter('listItemValue'); - return inside(code) - } - } - - return nok(code) - } - /** @type {State} */ - - function inside(code) { - if (asciiDigit(code) && ++size < 10) { - effects.consume(code); - return inside - } - - if ( - (!self.interrupt || size < 2) && - (self.containerState.marker - ? code === self.containerState.marker - : code === 41 || code === 46) - ) { - effects.exit('listItemValue'); - return atMarker(code) - } - - return nok(code) - } - /** - * @type {State} - **/ - - function atMarker(code) { - effects.enter('listItemMarker'); - effects.consume(code); - effects.exit('listItemMarker'); - self.containerState.marker = self.containerState.marker || code; - return effects.check( - blankLine, // Can’t be empty when interrupting. - self.interrupt ? nok : onBlank, - effects.attempt( - listItemPrefixWhitespaceConstruct, - endOfPrefix, - otherPrefix - ) - ) - } - /** @type {State} */ - - function onBlank(code) { - self.containerState.initialBlankLine = true; - initialSize++; - return endOfPrefix(code) - } - /** @type {State} */ - - function otherPrefix(code) { - if (markdownSpace(code)) { - effects.enter('listItemPrefixWhitespace'); - effects.consume(code); - effects.exit('listItemPrefixWhitespace'); - return endOfPrefix - } - - return nok(code) - } - /** @type {State} */ - - function endOfPrefix(code) { - self.containerState.size = - initialSize + - self.sliceSerialize(effects.exit('listItemPrefix'), true).length; - return ok(code) - } -} -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeListContinuation(effects, ok, nok) { - const self = this; - self.containerState._closeFlow = undefined; - return effects.check(blankLine, onBlank, notBlank) - /** @type {State} */ - - function onBlank(code) { - self.containerState.furtherBlankLines = - self.containerState.furtherBlankLines || - self.containerState.initialBlankLine; // We have a blank line. - // Still, try to consume at most the items size. - - return factorySpace( - effects, - ok, - 'listItemIndent', - self.containerState.size + 1 - )(code) - } - /** @type {State} */ - - function notBlank(code) { - if (self.containerState.furtherBlankLines || !markdownSpace(code)) { - self.containerState.furtherBlankLines = undefined; - self.containerState.initialBlankLine = undefined; - return notInCurrentItem(code) - } - - self.containerState.furtherBlankLines = undefined; - self.containerState.initialBlankLine = undefined; - return effects.attempt(indentConstruct, ok, notInCurrentItem)(code) - } - /** @type {State} */ - - function notInCurrentItem(code) { - // While we do continue, we signal that the flow should be closed. - self.containerState._closeFlow = true; // As we’re closing flow, we’re no longer interrupting. - - self.interrupt = undefined; - return factorySpace( - effects, - effects.attempt(list$1, ok, nok), - 'linePrefix', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 - )(code) - } -} -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeIndent(effects, ok, nok) { - const self = this; - return factorySpace( - effects, - afterPrefix, - 'listItemIndent', - self.containerState.size + 1 - ) - /** @type {State} */ - - function afterPrefix(code) { - const tail = self.events[self.events.length - 1]; - return tail && - tail[1].type === 'listItemIndent' && - tail[2].sliceSerialize(tail[1], true).length === self.containerState.size - ? ok(code) - : nok(code) - } -} -/** - * @type {Exiter} - * @this {TokenizeContextWithState} - */ - -function tokenizeListEnd(effects) { - effects.exit(this.containerState.type); -} -/** - * @type {Tokenizer} - * @this {TokenizeContextWithState} - */ - -function tokenizeListItemPrefixWhitespace(effects, ok, nok) { - const self = this; - return factorySpace( - effects, - afterPrefix, - 'listItemPrefixWhitespace', - self.parser.constructs.disable.null.includes('codeIndented') - ? undefined - : 4 + 1 - ) - /** @type {State} */ - - function afterPrefix(code) { - const tail = self.events[self.events.length - 1]; - return !markdownSpace(code) && - tail && - tail[1].type === 'listItemPrefixWhitespace' - ? ok(code) - : nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ - -/** @type {Construct} */ -const setextUnderline = { - name: 'setextUnderline', - tokenize: tokenizeSetextUnderline, - resolveTo: resolveToSetextUnderline -}; -/** @type {Resolver} */ - -function resolveToSetextUnderline(events, context) { - let index = events.length; - /** @type {number|undefined} */ - - let content; - /** @type {number|undefined} */ - - let text; - /** @type {number|undefined} */ - - let definition; // Find the opening of the content. - // It’ll always exist: we don’t tokenize if it isn’t there. - - while (index--) { - if (events[index][0] === 'enter') { - if (events[index][1].type === 'content') { - content = index; - break - } - - if (events[index][1].type === 'paragraph') { - text = index; - } - } // Exit - else { - if (events[index][1].type === 'content') { - // Remove the content end (if needed we’ll add it later) - events.splice(index, 1); - } - - if (!definition && events[index][1].type === 'definition') { - definition = index; - } - } - } - - const heading = { - type: 'setextHeading', - start: Object.assign({}, events[text][1].start), - end: Object.assign({}, events[events.length - 1][1].end) - }; // Change the paragraph to setext heading text. - - events[text][1].type = 'setextHeadingText'; // If we have definitions in the content, we’ll keep on having content, - // but we need move it. - - if (definition) { - events.splice(text, 0, ['enter', heading, context]); - events.splice(definition + 1, 0, ['exit', events[content][1], context]); - events[content][1].end = Object.assign({}, events[definition][1].end); - } else { - events[content][1] = heading; - } // Add the heading exit at the end. - - events.push(['exit', heading, context]); - return events -} -/** @type {Tokenizer} */ - -function tokenizeSetextUnderline(effects, ok, nok) { - const self = this; - let index = self.events.length; - /** @type {NonNullable} */ - - let marker; - /** @type {boolean} */ - - let paragraph; // Find an opening. - - while (index--) { - // Skip enter/exit of line ending, line prefix, and content. - // We can now either have a definition or a paragraph. - if ( - self.events[index][1].type !== 'lineEnding' && - self.events[index][1].type !== 'linePrefix' && - self.events[index][1].type !== 'content' - ) { - paragraph = self.events[index][1].type === 'paragraph'; - break - } - } - - return start - /** @type {State} */ - - function start(code) { - if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) { - effects.enter('setextHeadingLine'); - effects.enter('setextHeadingLineSequence'); - marker = code; - return closingSequence(code) - } - - return nok(code) - } - /** @type {State} */ - - function closingSequence(code) { - if (code === marker) { - effects.consume(code); - return closingSequence - } - - effects.exit('setextHeadingLineSequence'); - return factorySpace(effects, closingSequenceEnd, 'lineSuffix')(code) - } - /** @type {State} */ - - function closingSequenceEnd(code) { - if (code === null || markdownLineEnding(code)) { - effects.exit('setextHeadingLine'); - return ok(code) - } - - return nok(code) - } -} - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').State} State - */ - -/** @type {InitialConstruct} */ -const flow$1 = { - tokenize: initializeFlow -}; -/** @type {Initializer} */ - -function initializeFlow(effects) { - const self = this; - const initial = effects.attempt( - // Try to parse a blank line. - blankLine, - atBlankEnding, // Try to parse initial flow (essentially, only code). - effects.attempt( - this.parser.constructs.flowInitial, - afterConstruct, - factorySpace( - effects, - effects.attempt( - this.parser.constructs.flow, - afterConstruct, - effects.attempt(content, afterConstruct) - ), - 'linePrefix' - ) - ) - ); - return initial - /** @type {State} */ - - function atBlankEnding(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('lineEndingBlank'); - effects.consume(code); - effects.exit('lineEndingBlank'); - self.currentConstruct = undefined; - return initial - } - /** @type {State} */ - - function afterConstruct(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('lineEnding'); - effects.consume(code); - effects.exit('lineEnding'); - self.currentConstruct = undefined; - return initial - } -} - -/** - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Initializer} Initializer - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Code} Code - */ -const resolver = { - resolveAll: createResolver() -}; -const string$1 = initializeFactory('string'); -const text$3 = initializeFactory('text'); -/** - * @param {'string'|'text'} field - * @returns {InitialConstruct} - */ - -function initializeFactory(field) { - return { - tokenize: initializeText, - resolveAll: createResolver( - field === 'text' ? resolveAllLineSuffixes : undefined - ) - } - /** @type {Initializer} */ - - function initializeText(effects) { - const self = this; - const constructs = this.parser.constructs[field]; - const text = effects.attempt(constructs, start, notText); - return start - /** @type {State} */ - - function start(code) { - return atBreak(code) ? text(code) : notText(code) - } - /** @type {State} */ - - function notText(code) { - if (code === null) { - effects.consume(code); - return - } - - effects.enter('data'); - effects.consume(code); - return data - } - /** @type {State} */ - - function data(code) { - if (atBreak(code)) { - effects.exit('data'); - return text(code) - } // Data. - - effects.consume(code); - return data - } - /** - * @param {Code} code - * @returns {boolean} - */ - - function atBreak(code) { - if (code === null) { - return true - } - - const list = constructs[code]; - let index = -1; - - if (list) { - while (++index < list.length) { - const item = list[index]; - - if (!item.previous || item.previous.call(self, self.previous)) { - return true - } - } - } - - return false - } - } -} -/** - * @param {Resolver} [extraResolver] - * @returns {Resolver} - */ - -function createResolver(extraResolver) { - return resolveAllText - /** @type {Resolver} */ - - function resolveAllText(events, context) { - let index = -1; - /** @type {number|undefined} */ - - let enter; // A rather boring computation (to merge adjacent `data` events) which - // improves mm performance by 29%. - - while (++index <= events.length) { - if (enter === undefined) { - if (events[index] && events[index][1].type === 'data') { - enter = index; - index++; - } - } else if (!events[index] || events[index][1].type !== 'data') { - // Don’t do anything if there is one data token. - if (index !== enter + 2) { - events[enter][1].end = events[index - 1][1].end; - events.splice(enter + 2, index - enter - 2); - index = enter + 2; - } - - enter = undefined; - } - } - - return extraResolver ? extraResolver(events, context) : events - } -} -/** - * A rather ugly set of instructions which again looks at chunks in the input - * stream. - * The reason to do this here is that it is *much* faster to parse in reverse. - * And that we can’t hook into `null` to split the line suffix before an EOF. - * To do: figure out if we can make this into a clean utility, or even in core. - * As it will be useful for GFMs literal autolink extension (and maybe even - * tables?) - * - * @type {Resolver} - */ - -function resolveAllLineSuffixes(events, context) { - let eventIndex = -1; - - while (++eventIndex <= events.length) { - if ( - (eventIndex === events.length || - events[eventIndex][1].type === 'lineEnding') && - events[eventIndex - 1][1].type === 'data' - ) { - const data = events[eventIndex - 1][1]; - const chunks = context.sliceStream(data); - let index = chunks.length; - let bufferIndex = -1; - let size = 0; - /** @type {boolean|undefined} */ - - let tabs; - - while (index--) { - const chunk = chunks[index]; - - if (typeof chunk === 'string') { - bufferIndex = chunk.length; - - while (chunk.charCodeAt(bufferIndex - 1) === 32) { - size++; - bufferIndex--; - } - - if (bufferIndex) break - bufferIndex = -1; - } // Number - else if (chunk === -2) { - tabs = true; - size++; - } else if (chunk === -1) ; else { - // Replacement character, exit. - index++; - break - } - } - - if (size) { - const token = { - type: - eventIndex === events.length || tabs || size < 2 - ? 'lineSuffix' - : 'hardBreakTrailing', - start: { - line: data.end.line, - column: data.end.column - size, - offset: data.end.offset - size, - _index: data.start._index + index, - _bufferIndex: index - ? bufferIndex - : data.start._bufferIndex + bufferIndex - }, - end: Object.assign({}, data.end) - }; - data.end = Object.assign({}, token.start); - - if (data.start.offset === data.end.offset) { - Object.assign(data, token); - } else { - events.splice( - eventIndex, - 0, - ['enter', token, context], - ['exit', token, context] - ); - eventIndex += 2; - } - } - - eventIndex++; - } - } - - return events -} - -/** - * @typedef {import('micromark-util-types').Code} Code - * @typedef {import('micromark-util-types').Chunk} Chunk - * @typedef {import('micromark-util-types').Point} Point - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Effects} Effects - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Construct} Construct - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').ParseContext} ParseContext - */ - -/** - * Create a tokenizer. - * Tokenizers deal with one type of data (e.g., containers, flow, text). - * The parser is the object dealing with it all. - * `initialize` works like other constructs, except that only its `tokenize` - * function is used, in which case it doesn’t receive an `ok` or `nok`. - * `from` can be given to set the point before the first character, although - * when further lines are indented, they must be set with `defineSkip`. - * - * @param {ParseContext} parser - * @param {InitialConstruct} initialize - * @param {Omit} [from] - * @returns {TokenizeContext} - */ -function createTokenizer(parser, initialize, from) { - /** @type {Point} */ - let point = Object.assign( - from - ? Object.assign({}, from) - : { - line: 1, - column: 1, - offset: 0 - }, - { - _index: 0, - _bufferIndex: -1 - } - ); - /** @type {Record} */ - - const columnStart = {}; - /** @type {Construct[]} */ - - const resolveAllConstructs = []; - /** @type {Chunk[]} */ - - let chunks = []; - /** @type {Token[]} */ - - let stack = []; - /** - * Tools used for tokenizing. - * - * @type {Effects} - */ - - const effects = { - consume, - enter, - exit, - attempt: constructFactory(onsuccessfulconstruct), - check: constructFactory(onsuccessfulcheck), - interrupt: constructFactory(onsuccessfulcheck, { - interrupt: true - }) - }; - /** - * State and tools for resolving and serializing. - * - * @type {TokenizeContext} - */ - - const context = { - previous: null, - code: null, - containerState: {}, - events: [], - parser, - sliceStream, - sliceSerialize, - now, - defineSkip, - write - }; - /** - * The state function. - * - * @type {State|void} - */ - - let state = initialize.tokenize.call(context, effects); - - if (initialize.resolveAll) { - resolveAllConstructs.push(initialize); - } - - return context - /** @type {TokenizeContext['write']} */ - - function write(slice) { - chunks = push(chunks, slice); - main(); // Exit if we’re not done, resolve might change stuff. - - if (chunks[chunks.length - 1] !== null) { - return [] - } - - addResult(initialize, 0); // Otherwise, resolve, and exit. - - context.events = resolveAll(resolveAllConstructs, context.events, context); - return context.events - } // - // Tools. - // - - /** @type {TokenizeContext['sliceSerialize']} */ - - function sliceSerialize(token, expandTabs) { - return serializeChunks(sliceStream(token), expandTabs) - } - /** @type {TokenizeContext['sliceStream']} */ - - function sliceStream(token) { - return sliceChunks(chunks, token) - } - /** @type {TokenizeContext['now']} */ - - function now() { - return Object.assign({}, point) - } - /** @type {TokenizeContext['defineSkip']} */ - - function defineSkip(value) { - columnStart[value.line] = value.column; - accountForPotentialSkip(); - } // - // State management. - // - - /** - * Main loop (note that `_index` and `_bufferIndex` in `point` are modified by - * `consume`). - * Here is where we walk through the chunks, which either include strings of - * several characters, or numerical character codes. - * The reason to do this in a loop instead of a call is so the stack can - * drain. - * - * @returns {void} - */ - - function main() { - /** @type {number} */ - let chunkIndex; - - while (point._index < chunks.length) { - const chunk = chunks[point._index]; // If we’re in a buffer chunk, loop through it. - - if (typeof chunk === 'string') { - chunkIndex = point._index; - - if (point._bufferIndex < 0) { - point._bufferIndex = 0; - } - - while ( - point._index === chunkIndex && - point._bufferIndex < chunk.length - ) { - go(chunk.charCodeAt(point._bufferIndex)); - } - } else { - go(chunk); - } - } - } - /** - * Deal with one code. - * - * @param {Code} code - * @returns {void} - */ - - function go(code) { - state = state(code); - } - /** @type {Effects['consume']} */ - - function consume(code) { - if (markdownLineEnding(code)) { - point.line++; - point.column = 1; - point.offset += code === -3 ? 2 : 1; - accountForPotentialSkip(); - } else if (code !== -1) { - point.column++; - point.offset++; - } // Not in a string chunk. - - if (point._bufferIndex < 0) { - point._index++; - } else { - point._bufferIndex++; // At end of string chunk. - // @ts-expect-error Points w/ non-negative `_bufferIndex` reference - // strings. - - if (point._bufferIndex === chunks[point._index].length) { - point._bufferIndex = -1; - point._index++; - } - } // Expose the previous character. - - context.previous = code; // Mark as consumed. - } - /** @type {Effects['enter']} */ - - function enter(type, fields) { - /** @type {Token} */ - // @ts-expect-error Patch instead of assign required fields to help GC. - const token = fields || {}; - token.type = type; - token.start = now(); - context.events.push(['enter', token, context]); - stack.push(token); - return token - } - /** @type {Effects['exit']} */ - - function exit(type) { - const token = stack.pop(); - token.end = now(); - context.events.push(['exit', token, context]); - return token - } - /** - * Use results. - * - * @type {ReturnHandle} - */ - - function onsuccessfulconstruct(construct, info) { - addResult(construct, info.from); - } - /** - * Discard results. - * - * @type {ReturnHandle} - */ - - function onsuccessfulcheck(_, info) { - info.restore(); - } - /** - * Factory to attempt/check/interrupt. - * - * @param {ReturnHandle} onreturn - * @param {Record} [fields] - */ - - function constructFactory(onreturn, fields) { - return hook - /** - * Handle either an object mapping codes to constructs, a list of - * constructs, or a single construct. - * - * @param {Construct|Construct[]|ConstructRecord} constructs - * @param {State} returnState - * @param {State} [bogusState] - * @returns {State} - */ - - function hook(constructs, returnState, bogusState) { - /** @type {Construct[]} */ - let listOfConstructs; - /** @type {number} */ - - let constructIndex; - /** @type {Construct} */ - - let currentConstruct; - /** @type {Info} */ - - let info; - return Array.isArray(constructs) - ? /* c8 ignore next 1 */ - handleListOfConstructs(constructs) - : 'tokenize' in constructs // @ts-expect-error Looks like a construct. - ? handleListOfConstructs([constructs]) - : handleMapOfConstructs(constructs) - /** - * Handle a list of construct. - * - * @param {ConstructRecord} map - * @returns {State} - */ - - function handleMapOfConstructs(map) { - return start - /** @type {State} */ - - function start(code) { - const def = code !== null && map[code]; - const all = code !== null && map.null; - const list = [ - // To do: add more extension tests. - - /* c8 ignore next 2 */ - ...(Array.isArray(def) ? def : def ? [def] : []), - ...(Array.isArray(all) ? all : all ? [all] : []) - ]; - return handleListOfConstructs(list)(code) - } - } - /** - * Handle a list of construct. - * - * @param {Construct[]} list - * @returns {State} - */ - - function handleListOfConstructs(list) { - listOfConstructs = list; - constructIndex = 0; - - if (list.length === 0) { - return bogusState - } - - return handleConstruct(list[constructIndex]) - } - /** - * Handle a single construct. - * - * @param {Construct} construct - * @returns {State} - */ - - function handleConstruct(construct) { - return start - /** @type {State} */ - - function start(code) { - // To do: not needed to store if there is no bogus state, probably? - // Currently doesn’t work because `inspect` in document does a check - // w/o a bogus, which doesn’t make sense. But it does seem to help perf - // by not storing. - info = store(); - currentConstruct = construct; - - if (!construct.partial) { - context.currentConstruct = construct; - } - - if ( - construct.name && - context.parser.constructs.disable.null.includes(construct.name) - ) { - return nok() - } - - return construct.tokenize.call( - // If we do have fields, create an object w/ `context` as its - // prototype. - // This allows a “live binding”, which is needed for `interrupt`. - fields ? Object.assign(Object.create(context), fields) : context, - effects, - ok, - nok - )(code) - } - } - /** @type {State} */ - - function ok(code) { - onreturn(currentConstruct, info); - return returnState - } - /** @type {State} */ - - function nok(code) { - info.restore(); - - if (++constructIndex < listOfConstructs.length) { - return handleConstruct(listOfConstructs[constructIndex]) - } - - return bogusState - } - } - } - /** - * @param {Construct} construct - * @param {number} from - * @returns {void} - */ - - function addResult(construct, from) { - if (construct.resolveAll && !resolveAllConstructs.includes(construct)) { - resolveAllConstructs.push(construct); - } - - if (construct.resolve) { - splice( - context.events, - from, - context.events.length - from, - construct.resolve(context.events.slice(from), context) - ); - } - - if (construct.resolveTo) { - context.events = construct.resolveTo(context.events, context); - } - } - /** - * Store state. - * - * @returns {Info} - */ - - function store() { - const startPoint = now(); - const startPrevious = context.previous; - const startCurrentConstruct = context.currentConstruct; - const startEventsIndex = context.events.length; - const startStack = Array.from(stack); - return { - restore, - from: startEventsIndex - } - /** - * Restore state. - * - * @returns {void} - */ - - function restore() { - point = startPoint; - context.previous = startPrevious; - context.currentConstruct = startCurrentConstruct; - context.events.length = startEventsIndex; - stack = startStack; - accountForPotentialSkip(); - } - } - /** - * Move the current point a bit forward in the line when it’s on a column - * skip. - * - * @returns {void} - */ - - function accountForPotentialSkip() { - if (point.line in columnStart && point.column < 2) { - point.column = columnStart[point.line]; - point.offset += columnStart[point.line] - 1; - } - } -} -/** - * Get the chunks from a slice of chunks in the range of a token. - * - * @param {Chunk[]} chunks - * @param {Pick} token - * @returns {Chunk[]} - */ - -function sliceChunks(chunks, token) { - const startIndex = token.start._index; - const startBufferIndex = token.start._bufferIndex; - const endIndex = token.end._index; - const endBufferIndex = token.end._bufferIndex; - /** @type {Chunk[]} */ - - let view; - - if (startIndex === endIndex) { - // @ts-expect-error `_bufferIndex` is used on string chunks. - view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)]; - } else { - view = chunks.slice(startIndex, endIndex); - - if (startBufferIndex > -1) { - // @ts-expect-error `_bufferIndex` is used on string chunks. - view[0] = view[0].slice(startBufferIndex); - } - - if (endBufferIndex > 0) { - // @ts-expect-error `_bufferIndex` is used on string chunks. - view.push(chunks[endIndex].slice(0, endBufferIndex)); - } - } - - return view -} -/** - * Get the string value of a slice of chunks. - * - * @param {Chunk[]} chunks - * @param {boolean} [expandTabs=false] - * @returns {string} - */ - -function serializeChunks(chunks, expandTabs) { - let index = -1; - /** @type {string[]} */ - - const result = []; - /** @type {boolean|undefined} */ - - let atTab; - - while (++index < chunks.length) { - const chunk = chunks[index]; - /** @type {string} */ - - let value; - - if (typeof chunk === 'string') { - value = chunk; - } else - switch (chunk) { - case -5: { - value = '\r'; - break - } - - case -4: { - value = '\n'; - break - } - - case -3: { - value = '\r' + '\n'; - break - } - - case -2: { - value = expandTabs ? ' ' : '\t'; - break - } - - case -1: { - if (!expandTabs && atTab) continue - value = ' '; - break - } - - default: { - // Currently only replacement character. - value = String.fromCharCode(chunk); - } - } - - atTab = chunk === -2; - result.push(value); - } - - return result.join('') -} - -/** - * @typedef {import('micromark-util-types').Extension} Extension - */ -/** @type {Extension['document']} */ - -const document$1 = { - [42]: list$1, - [43]: list$1, - [45]: list$1, - [48]: list$1, - [49]: list$1, - [50]: list$1, - [51]: list$1, - [52]: list$1, - [53]: list$1, - [54]: list$1, - [55]: list$1, - [56]: list$1, - [57]: list$1, - [62]: blockQuote -}; -/** @type {Extension['contentInitial']} */ - -const contentInitial = { - [91]: definition$1 -}; -/** @type {Extension['flowInitial']} */ - -const flowInitial = { - [-2]: codeIndented, - [-1]: codeIndented, - [32]: codeIndented -}; -/** @type {Extension['flow']} */ - -const flow = { - [35]: headingAtx, - [42]: thematicBreak$1, - [45]: [setextUnderline, thematicBreak$1], - [60]: htmlFlow, - [61]: setextUnderline, - [95]: thematicBreak$1, - [96]: codeFenced, - [126]: codeFenced -}; -/** @type {Extension['string']} */ - -const string = { - [38]: characterReference$1, - [92]: characterEscape$1 -}; -/** @type {Extension['text']} */ - -const text$2 = { - [-5]: lineEnding, - [-4]: lineEnding, - [-3]: lineEnding, - [33]: labelStartImage, - [38]: characterReference$1, - [42]: attention, - [60]: [autolink, htmlText], - [91]: labelStartLink, - [92]: [hardBreakEscape, characterEscape$1], - [93]: labelEnd, - [95]: attention, - [96]: codeText -}; -/** @type {Extension['insideSpan']} */ - -const insideSpan = { - null: [attention, resolver] -}; -/** @type {Extension['attentionMarkers']} */ - -const attentionMarkers = { - null: [42, 95] -}; -/** @type {Extension['disable']} */ - -const disable = { - null: [] -}; - -var defaultConstructs = /*#__PURE__*/Object.freeze({ - __proto__: null, - document: document$1, - contentInitial: contentInitial, - flowInitial: flowInitial, - flow: flow, - string: string, - text: text$2, - insideSpan: insideSpan, - attentionMarkers: attentionMarkers, - disable: disable -}); - -/** - * @typedef {import('micromark-util-types').InitialConstruct} InitialConstruct - * @typedef {import('micromark-util-types').FullNormalizedExtension} FullNormalizedExtension - * @typedef {import('micromark-util-types').ParseOptions} ParseOptions - * @typedef {import('micromark-util-types').ParseContext} ParseContext - * @typedef {import('micromark-util-types').Create} Create - */ -/** - * @param {ParseOptions} [options] - * @returns {ParseContext} - */ - -function parse(options = {}) { - /** @type {FullNormalizedExtension} */ - // @ts-expect-error `defaultConstructs` is full, so the result will be too. - const constructs = combineExtensions( - // @ts-expect-error Same as above. - [defaultConstructs].concat(options.extensions || []) - ); - /** @type {ParseContext} */ - - const parser = { - defined: [], - lazy: {}, - constructs, - content: create(content$1), - document: create(document$2), - flow: create(flow$1), - string: create(string$1), - text: create(text$3) - }; - return parser - /** - * @param {InitialConstruct} initial - */ - - function create(initial) { - return creator - /** @type {Create} */ - - function creator(from) { - return createTokenizer(parser, initial, from) - } - } -} - -/** - * @typedef {import('micromark-util-types').Encoding} Encoding - * @typedef {import('micromark-util-types').Value} Value - * @typedef {import('micromark-util-types').Chunk} Chunk - * @typedef {import('micromark-util-types').Code} Code - */ - -/** - * @callback Preprocessor - * @param {Value} value - * @param {Encoding} [encoding] - * @param {boolean} [end=false] - * @returns {Chunk[]} - */ -const search = /[\0\t\n\r]/g; -/** - * @returns {Preprocessor} - */ - -function preprocess() { - let column = 1; - let buffer = ''; - /** @type {boolean|undefined} */ - - let start = true; - /** @type {boolean|undefined} */ - - let atCarriageReturn; - return preprocessor - /** @type {Preprocessor} */ - - function preprocessor(value, encoding, end) { - /** @type {Chunk[]} */ - const chunks = []; - /** @type {RegExpMatchArray|null} */ - - let match; - /** @type {number} */ - - let next; - /** @type {number} */ - - let startPosition; - /** @type {number} */ - - let endPosition; - /** @type {Code} */ - - let code; // @ts-expect-error `Buffer` does allow an encoding. - - value = buffer + value.toString(encoding); - startPosition = 0; - buffer = ''; - - if (start) { - if (value.charCodeAt(0) === 65279) { - startPosition++; - } - - start = undefined; - } - - while (startPosition < value.length) { - search.lastIndex = startPosition; - match = search.exec(value); - endPosition = - match && match.index !== undefined ? match.index : value.length; - code = value.charCodeAt(endPosition); - - if (!match) { - buffer = value.slice(startPosition); - break - } - - if (code === 10 && startPosition === endPosition && atCarriageReturn) { - chunks.push(-3); - atCarriageReturn = undefined; - } else { - if (atCarriageReturn) { - chunks.push(-5); - atCarriageReturn = undefined; - } - - if (startPosition < endPosition) { - chunks.push(value.slice(startPosition, endPosition)); - column += endPosition - startPosition; - } - - switch (code) { - case 0: { - chunks.push(65533); - column++; - break - } - - case 9: { - next = Math.ceil(column / 4) * 4; - chunks.push(-2); - - while (column++ < next) chunks.push(-1); - - break - } - - case 10: { - chunks.push(-4); - column = 1; - break - } - - default: { - atCarriageReturn = true; - column = 1; - } - } - } - - startPosition = endPosition + 1; - } - - if (end) { - if (atCarriageReturn) chunks.push(-5); - if (buffer) chunks.push(buffer); - chunks.push(null); - } - - return chunks - } -} - -/** - * @typedef {import('micromark-util-types').Event} Event - */ -/** - * @param {Event[]} events - * @returns {Event[]} - */ - -function postprocess(events) { - while (!subtokenize(events)) { - // Empty - } - - return events -} - -/** - * Turn the number (in string form as either hexa- or plain decimal) coming from - * a numeric character reference into a character. - * - * @param {string} value - * Value to decode. - * @param {number} base - * Numeric base. - * @returns {string} - */ -function decodeNumericCharacterReference(value, base) { - const code = Number.parseInt(value, base); - - if ( - // C0 except for HT, LF, FF, CR, space - code < 9 || - code === 11 || - (code > 13 && code < 32) || // Control character (DEL) of the basic block and C1 controls. - (code > 126 && code < 160) || // Lone high surrogates and low surrogates. - (code > 55295 && code < 57344) || // Noncharacters. - (code > 64975 && code < 65008) || - (code & 65535) === 65535 || - (code & 65535) === 65534 || // Out of range - code > 1114111 - ) { - return '\uFFFD' - } - - return String.fromCharCode(code) -} - -/** - * @typedef {import('micromark-util-types').Encoding} Encoding - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').ParseOptions} ParseOptions - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext - * @typedef {import('micromark-util-types').Value} Value - * @typedef {Root|Root['children'][number]} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist').Point} Point - * @typedef {import('mdast').Break} Break - * @typedef {import('mdast').Blockquote} Blockquote - * @typedef {import('mdast').Code} Code - * @typedef {import('mdast').Definition} Definition - * @typedef {import('mdast').Emphasis} Emphasis - * @typedef {import('mdast').Heading} Heading - * @typedef {import('mdast').HTML} HTML - * @typedef {import('mdast').Image} Image - * @typedef {import('mdast').InlineCode} InlineCode - * @typedef {import('mdast').Link} Link - * @typedef {import('mdast').List} List - * @typedef {import('mdast').ListItem} ListItem - * @typedef {import('mdast').Paragraph} Paragraph - * @typedef {import('mdast').Root} Root - * @typedef {import('mdast').Strong} Strong - * @typedef {import('mdast').Text} Text - * @typedef {import('mdast').ThematicBreak} ThematicBreak - */ -const own$4 = {}.hasOwnProperty; -/** - * @param value Markdown to parse (`string` or `Buffer`). - * @param [encoding] Character encoding to understand `value` as when it’s a `Buffer` (`string`, default: `'utf8'`). - * @param [options] Configuration - */ - -const fromMarkdown = - /** - * @type {( - * ((value: Value, encoding: Encoding, options?: Options) => Root) & - * ((value: Value, options?: Options) => Root) - * )} - */ - - /** - * @param {Value} value - * @param {Encoding} [encoding] - * @param {Options} [options] - * @returns {Root} - */ - function (value, encoding, options) { - if (typeof encoding !== 'string') { - options = encoding; - encoding = undefined; - } - - return compiler(options)( - postprocess( - parse(options).document().write(preprocess()(value, encoding, true)) - ) - ) - }; -/** - * Note this compiler only understand complete buffering, not streaming. - * - * @param {Options} [options] - */ - -function compiler(options = {}) { - /** @type {NormalizedExtension} */ - // @ts-expect-error: our base has all required fields, so the result will too. - const config = configure$1( - { - transforms: [], - canContainEols: [ - 'emphasis', - 'fragment', - 'heading', - 'paragraph', - 'strong' - ], - enter: { - autolink: opener(link), - autolinkProtocol: onenterdata, - autolinkEmail: onenterdata, - atxHeading: opener(heading), - blockQuote: opener(blockQuote), - characterEscape: onenterdata, - characterReference: onenterdata, - codeFenced: opener(codeFlow), - codeFencedFenceInfo: buffer, - codeFencedFenceMeta: buffer, - codeIndented: opener(codeFlow, buffer), - codeText: opener(codeText, buffer), - codeTextData: onenterdata, - data: onenterdata, - codeFlowValue: onenterdata, - definition: opener(definition), - definitionDestinationString: buffer, - definitionLabelString: buffer, - definitionTitleString: buffer, - emphasis: opener(emphasis), - hardBreakEscape: opener(hardBreak), - hardBreakTrailing: opener(hardBreak), - htmlFlow: opener(html, buffer), - htmlFlowData: onenterdata, - htmlText: opener(html, buffer), - htmlTextData: onenterdata, - image: opener(image), - label: buffer, - link: opener(link), - listItem: opener(listItem), - listItemValue: onenterlistitemvalue, - listOrdered: opener(list, onenterlistordered), - listUnordered: opener(list), - paragraph: opener(paragraph), - reference: onenterreference, - referenceString: buffer, - resourceDestinationString: buffer, - resourceTitleString: buffer, - setextHeading: opener(heading), - strong: opener(strong), - thematicBreak: opener(thematicBreak) - }, - exit: { - atxHeading: closer(), - atxHeadingSequence: onexitatxheadingsequence, - autolink: closer(), - autolinkEmail: onexitautolinkemail, - autolinkProtocol: onexitautolinkprotocol, - blockQuote: closer(), - characterEscapeValue: onexitdata, - characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker, - characterReferenceMarkerNumeric: onexitcharacterreferencemarker, - characterReferenceValue: onexitcharacterreferencevalue, - codeFenced: closer(onexitcodefenced), - codeFencedFence: onexitcodefencedfence, - codeFencedFenceInfo: onexitcodefencedfenceinfo, - codeFencedFenceMeta: onexitcodefencedfencemeta, - codeFlowValue: onexitdata, - codeIndented: closer(onexitcodeindented), - codeText: closer(onexitcodetext), - codeTextData: onexitdata, - data: onexitdata, - definition: closer(), - definitionDestinationString: onexitdefinitiondestinationstring, - definitionLabelString: onexitdefinitionlabelstring, - definitionTitleString: onexitdefinitiontitlestring, - emphasis: closer(), - hardBreakEscape: closer(onexithardbreak), - hardBreakTrailing: closer(onexithardbreak), - htmlFlow: closer(onexithtmlflow), - htmlFlowData: onexitdata, - htmlText: closer(onexithtmltext), - htmlTextData: onexitdata, - image: closer(onexitimage), - label: onexitlabel, - labelText: onexitlabeltext, - lineEnding: onexitlineending, - link: closer(onexitlink), - listItem: closer(), - listOrdered: closer(), - listUnordered: closer(), - paragraph: closer(), - referenceString: onexitreferencestring, - resourceDestinationString: onexitresourcedestinationstring, - resourceTitleString: onexitresourcetitlestring, - resource: onexitresource, - setextHeading: closer(onexitsetextheading), - setextHeadingLineSequence: onexitsetextheadinglinesequence, - setextHeadingText: onexitsetextheadingtext, - strong: closer(), - thematicBreak: closer() - } - }, - options.mdastExtensions || [] - ); - /** @type {CompileData} */ - - const data = {}; - return compile - /** - * @param {Array.} events - * @returns {Root} - */ - - function compile(events) { - /** @type {Root} */ - let tree = { - type: 'root', - children: [] - }; - /** @type {CompileContext['stack']} */ - - const stack = [tree]; - /** @type {CompileContext['tokenStack']} */ - - const tokenStack = []; - /** @type {Array.} */ - - const listStack = []; - /** @type {Omit} */ - - const context = { - stack, - tokenStack, - config, - enter, - exit, - buffer, - resume, - setData, - getData - }; - let index = -1; - - while (++index < events.length) { - // We preprocess lists to add `listItem` tokens, and to infer whether - // items the list itself are spread out. - if ( - events[index][1].type === 'listOrdered' || - events[index][1].type === 'listUnordered' - ) { - if (events[index][0] === 'enter') { - listStack.push(index); - } else { - const tail = listStack.pop(); - index = prepareList(events, tail, index); - } - } - } - - index = -1; - - while (++index < events.length) { - const handler = config[events[index][0]]; - - if (own$4.call(handler, events[index][1].type)) { - handler[events[index][1].type].call( - Object.assign( - { - sliceSerialize: events[index][2].sliceSerialize - }, - context - ), - events[index][1] - ); - } - } - - if (tokenStack.length > 0) { - throw new Error( - 'Cannot close document, a token (`' + - tokenStack[tokenStack.length - 1].type + - '`, ' + - stringifyPosition$1({ - start: tokenStack[tokenStack.length - 1].start, - end: tokenStack[tokenStack.length - 1].end - }) + - ') is still open' - ) - } // Figure out `root` position. - - tree.position = { - start: point( - events.length > 0 - ? events[0][1].start - : { - line: 1, - column: 1, - offset: 0 - } - ), - end: point( - events.length > 0 - ? events[events.length - 2][1].end - : { - line: 1, - column: 1, - offset: 0 - } - ) - }; - index = -1; - - while (++index < config.transforms.length) { - tree = config.transforms[index](tree) || tree; - } - - return tree - } - /** - * @param {Array.} events - * @param {number} start - * @param {number} length - * @returns {number} - */ - - function prepareList(events, start, length) { - let index = start - 1; - let containerBalance = -1; - let listSpread = false; - /** @type {Token|undefined} */ - - let listItem; - /** @type {number|undefined} */ - - let lineIndex; - /** @type {number|undefined} */ - - let firstBlankLineIndex; - /** @type {boolean|undefined} */ - - let atMarker; - - while (++index <= length) { - const event = events[index]; - - if ( - event[1].type === 'listUnordered' || - event[1].type === 'listOrdered' || - event[1].type === 'blockQuote' - ) { - if (event[0] === 'enter') { - containerBalance++; - } else { - containerBalance--; - } - - atMarker = undefined; - } else if (event[1].type === 'lineEndingBlank') { - if (event[0] === 'enter') { - if ( - listItem && - !atMarker && - !containerBalance && - !firstBlankLineIndex - ) { - firstBlankLineIndex = index; - } - - atMarker = undefined; - } - } else if ( - event[1].type === 'linePrefix' || - event[1].type === 'listItemValue' || - event[1].type === 'listItemMarker' || - event[1].type === 'listItemPrefix' || - event[1].type === 'listItemPrefixWhitespace' - ) ; else { - atMarker = undefined; - } - - if ( - (!containerBalance && - event[0] === 'enter' && - event[1].type === 'listItemPrefix') || - (containerBalance === -1 && - event[0] === 'exit' && - (event[1].type === 'listUnordered' || - event[1].type === 'listOrdered')) - ) { - if (listItem) { - let tailIndex = index; - lineIndex = undefined; - - while (tailIndex--) { - const tailEvent = events[tailIndex]; - - if ( - tailEvent[1].type === 'lineEnding' || - tailEvent[1].type === 'lineEndingBlank' - ) { - if (tailEvent[0] === 'exit') continue - - if (lineIndex) { - events[lineIndex][1].type = 'lineEndingBlank'; - listSpread = true; - } - - tailEvent[1].type = 'lineEnding'; - lineIndex = tailIndex; - } else if ( - tailEvent[1].type === 'linePrefix' || - tailEvent[1].type === 'blockQuotePrefix' || - tailEvent[1].type === 'blockQuotePrefixWhitespace' || - tailEvent[1].type === 'blockQuoteMarker' || - tailEvent[1].type === 'listItemIndent' - ) ; else { - break - } - } - - if ( - firstBlankLineIndex && - (!lineIndex || firstBlankLineIndex < lineIndex) - ) { - // @ts-expect-error Patched. - listItem._spread = true; - } // Fix position. - - listItem.end = Object.assign( - {}, - lineIndex ? events[lineIndex][1].start : event[1].end - ); - events.splice(lineIndex || index, 0, ['exit', listItem, event[2]]); - index++; - length++; - } // Create a new list item. - - if (event[1].type === 'listItemPrefix') { - listItem = { - type: 'listItem', - // @ts-expect-error Patched - _spread: false, - start: Object.assign({}, event[1].start) - }; // @ts-expect-error: `listItem` is most definitely defined, TS... - - events.splice(index, 0, ['enter', listItem, event[2]]); - index++; - length++; - firstBlankLineIndex = undefined; - atMarker = true; - } - } - } // @ts-expect-error Patched. - - events[start][1]._spread = listSpread; - return length - } - /** - * @type {CompileContext['setData']} - * @param [value] - */ - - function setData(key, value) { - data[key] = value; - } - /** - * @type {CompileContext['getData']} - * @template {string} K - * @param {K} key - * @returns {CompileData[K]} - */ - - function getData(key) { - return data[key] - } - /** - * @param {Point} d - * @returns {Point} - */ - - function point(d) { - return { - line: d.line, - column: d.column, - offset: d.offset - } - } - /** - * @param {(token: Token) => Node} create - * @param {Handle} [and] - * @returns {Handle} - */ - - function opener(create, and) { - return open - /** - * @this {CompileContext} - * @param {Token} token - * @returns {void} - */ - - function open(token) { - enter.call(this, create(token), token); - if (and) and.call(this, token); - } - } - /** @type {CompileContext['buffer']} */ - - function buffer() { - // @ts-expect-error: Custom node type to collect text. - this.stack.push({ - type: 'fragment', - children: [] - }); - } - /** - * @type {CompileContext['enter']} - * @template {Node} N - * @this {CompileContext} - * @param {N} node - * @param {Token} token - * @returns {N} - */ - - function enter(node, token) { - /** @type {Parent} */ - // @ts-expect-error: Assume parent. - const parent = this.stack[this.stack.length - 1]; - parent.children.push(node); - this.stack.push(node); - this.tokenStack.push(token); // @ts-expect-error: `end` will be patched later. - - node.position = { - start: point(token.start) - }; - return node - } - /** - * @param {Handle} [and] - * @returns {Handle} - */ - - function closer(and) { - return close - /** - * @this {CompileContext} - * @param {Token} token - * @returns {void} - */ - - function close(token) { - if (and) and.call(this, token); - exit.call(this, token); - } - } - /** @type {CompileContext['exit']} */ - - function exit(token) { - const node = this.stack.pop(); - const open = this.tokenStack.pop(); - - if (!open) { - throw new Error( - 'Cannot close `' + - token.type + - '` (' + - stringifyPosition$1({ - start: token.start, - end: token.end - }) + - '): it’s not open' - ) - } else if (open.type !== token.type) { - throw new Error( - 'Cannot close `' + - token.type + - '` (' + - stringifyPosition$1({ - start: token.start, - end: token.end - }) + - '): a different token (`' + - open.type + - '`, ' + - stringifyPosition$1({ - start: open.start, - end: open.end - }) + - ') is open' - ) - } - - node.position.end = point(token.end); - return node - } - /** - * @this {CompileContext} - * @returns {string} - */ - - function resume() { - return toString(this.stack.pop()) - } // - // Handlers. - // - - /** @type {Handle} */ - - function onenterlistordered() { - setData('expectingFirstListItemValue', true); - } - /** @type {Handle} */ - - function onenterlistitemvalue(token) { - if (getData('expectingFirstListItemValue')) { - this.stack[this.stack.length - 2].start = Number.parseInt( - this.sliceSerialize(token), - 10 - ); - setData('expectingFirstListItemValue'); - } - } - /** @type {Handle} */ - - function onexitcodefencedfenceinfo() { - const data = this.resume(); - this.stack[this.stack.length - 1].lang = data; - } - /** @type {Handle} */ - - function onexitcodefencedfencemeta() { - const data = this.resume(); - this.stack[this.stack.length - 1].meta = data; - } - /** @type {Handle} */ - - function onexitcodefencedfence() { - // Exit if this is the closing fence. - if (getData('flowCodeInside')) return - this.buffer(); - setData('flowCodeInside', true); - } - /** @type {Handle} */ - - function onexitcodefenced() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data.replace( - /^(\r?\n|\r)|(\r?\n|\r)$/g, - '' - ); - setData('flowCodeInside'); - } - /** @type {Handle} */ - - function onexitcodeindented() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data.replace(/(\r?\n|\r)$/g, ''); - } - /** @type {Handle} */ - - function onexitdefinitionlabelstring(token) { - // Discard label, use the source content instead. - const label = this.resume(); - this.stack[this.stack.length - 1].label = label; - this.stack[this.stack.length - 1].identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - } - /** @type {Handle} */ - - function onexitdefinitiontitlestring() { - const data = this.resume(); - this.stack[this.stack.length - 1].title = data; - } - /** @type {Handle} */ - - function onexitdefinitiondestinationstring() { - const data = this.resume(); - this.stack[this.stack.length - 1].url = data; - } - /** @type {Handle} */ - - function onexitatxheadingsequence(token) { - if (!this.stack[this.stack.length - 1].depth) { - this.stack[this.stack.length - 1].depth = - this.sliceSerialize(token).length; - } - } - /** @type {Handle} */ - - function onexitsetextheadingtext() { - setData('setextHeadingSlurpLineEnding', true); - } - /** @type {Handle} */ - - function onexitsetextheadinglinesequence(token) { - this.stack[this.stack.length - 1].depth = - this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2; - } - /** @type {Handle} */ - - function onexitsetextheading() { - setData('setextHeadingSlurpLineEnding'); - } - /** @type {Handle} */ - - function onenterdata(token) { - /** @type {Parent} */ - // @ts-expect-error: assume parent. - const parent = this.stack[this.stack.length - 1]; - /** @type {Node} */ - // @ts-expect-error: assume child. - - let tail = parent.children[parent.children.length - 1]; - - if (!tail || tail.type !== 'text') { - // Add a new text node. - tail = text(); // @ts-expect-error: we’ll add `end` later. - - tail.position = { - start: point(token.start) - }; - parent.children.push(tail); - } - - this.stack.push(tail); - } - /** @type {Handle} */ - - function onexitdata(token) { - const tail = this.stack.pop(); - tail.value += this.sliceSerialize(token); - tail.position.end = point(token.end); - } - /** @type {Handle} */ - - function onexitlineending(token) { - /** @type {Parent} */ - // @ts-expect-error: supposed to be a parent. - const context = this.stack[this.stack.length - 1]; - - // If we’re at a hard break, include the line ending in there. - if (getData('atHardBreak')) { - const tail = context.children[context.children.length - 1]; - tail.position.end = point(token.end); - setData('atHardBreak'); - return - } - - if ( - !getData('setextHeadingSlurpLineEnding') && - config.canContainEols.includes(context.type) - ) { - onenterdata.call(this, token); - onexitdata.call(this, token); - } - } - /** @type {Handle} */ - - function onexithardbreak() { - setData('atHardBreak', true); - } - /** @type {Handle} */ - - function onexithtmlflow() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data; - } - /** @type {Handle} */ - - function onexithtmltext() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data; - } - /** @type {Handle} */ - - function onexitcodetext() { - const data = this.resume(); - this.stack[this.stack.length - 1].value = data; - } - /** @type {Handle} */ - - function onexitlink() { - const context = this.stack[this.stack.length - 1]; // To do: clean. - - if (getData('inReference')) { - context.type += 'Reference'; - context.referenceType = getData('referenceType') || 'shortcut'; - delete context.url; - delete context.title; - } else { - delete context.identifier; - delete context.label; - delete context.referenceType; - } - - setData('referenceType'); - } - /** @type {Handle} */ - - function onexitimage() { - const context = this.stack[this.stack.length - 1]; // To do: clean. - - if (getData('inReference')) { - context.type += 'Reference'; - context.referenceType = getData('referenceType') || 'shortcut'; - delete context.url; - delete context.title; - } else { - delete context.identifier; - delete context.label; - delete context.referenceType; - } - - setData('referenceType'); - } - /** @type {Handle} */ - - function onexitlabeltext(token) { - this.stack[this.stack.length - 2].identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - } - /** @type {Handle} */ - - function onexitlabel() { - const fragment = this.stack[this.stack.length - 1]; - const value = this.resume(); - this.stack[this.stack.length - 1].label = value; // Assume a reference. - - setData('inReference', true); - - if (this.stack[this.stack.length - 1].type === 'link') { - this.stack[this.stack.length - 1].children = fragment.children; - } else { - this.stack[this.stack.length - 1].alt = value; - } - } - /** @type {Handle} */ - - function onexitresourcedestinationstring() { - const data = this.resume(); - this.stack[this.stack.length - 1].url = data; - } - /** @type {Handle} */ - - function onexitresourcetitlestring() { - const data = this.resume(); - this.stack[this.stack.length - 1].title = data; - } - /** @type {Handle} */ - - function onexitresource() { - setData('inReference'); - } - /** @type {Handle} */ - - function onenterreference() { - setData('referenceType', 'collapsed'); - } - /** @type {Handle} */ - - function onexitreferencestring(token) { - const label = this.resume(); - this.stack[this.stack.length - 1].label = label; - this.stack[this.stack.length - 1].identifier = normalizeIdentifier( - this.sliceSerialize(token) - ).toLowerCase(); - setData('referenceType', 'full'); - } - /** @type {Handle} */ - - function onexitcharacterreferencemarker(token) { - setData('characterReferenceType', token.type); - } - /** @type {Handle} */ - - function onexitcharacterreferencevalue(token) { - const data = this.sliceSerialize(token); - const type = getData('characterReferenceType'); - /** @type {string} */ - - let value; - - if (type) { - value = decodeNumericCharacterReference( - data, - type === 'characterReferenceMarkerNumeric' ? 10 : 16 - ); - setData('characterReferenceType'); - } else { - // @ts-expect-error `decodeEntity` can return false for invalid named - // character references, but everything we’ve tokenized is valid. - value = decodeEntity(data); - } - - const tail = this.stack.pop(); - tail.value += value; - tail.position.end = point(token.end); - } - /** @type {Handle} */ - - function onexitautolinkprotocol(token) { - onexitdata.call(this, token); - this.stack[this.stack.length - 1].url = this.sliceSerialize(token); - } - /** @type {Handle} */ - - function onexitautolinkemail(token) { - onexitdata.call(this, token); - this.stack[this.stack.length - 1].url = - 'mailto:' + this.sliceSerialize(token); - } // - // Creaters. - // - - /** @returns {Blockquote} */ - - function blockQuote() { - return { - type: 'blockquote', - children: [] - } - } - /** @returns {Code} */ - - function codeFlow() { - // @ts-expect-error: we’ve always used `null`. - return { - type: 'code', - lang: null, - meta: null, - value: '' - } - } - /** @returns {InlineCode} */ - - function codeText() { - return { - type: 'inlineCode', - value: '' - } - } - /** @returns {Definition} */ - - function definition() { - return { - type: 'definition', - identifier: '', - // @ts-expect-error: we’ve always used `null`. - label: null, - // @ts-expect-error: we’ve always used `null`. - title: null, - url: '' - } - } - /** @returns {Emphasis} */ - - function emphasis() { - return { - type: 'emphasis', - children: [] - } - } - /** @returns {Heading} */ - - function heading() { - // @ts-expect-error `depth` will be set later. - return { - type: 'heading', - depth: undefined, - children: [] - } - } - /** @returns {Break} */ - - function hardBreak() { - return { - type: 'break' - } - } - /** @returns {HTML} */ - - function html() { - return { - type: 'html', - value: '' - } - } - /** @returns {Image} */ - - function image() { - // @ts-expect-error: we’ve always used `null`. - return { - type: 'image', - title: null, - url: '', - alt: null - } - } - /** @returns {Link} */ - - function link() { - // @ts-expect-error: we’ve always used `null`. - return { - type: 'link', - title: null, - url: '', - children: [] - } - } - /** - * @param {Token} token - * @returns {List} - */ - - function list(token) { - return { - type: 'list', - ordered: token.type === 'listOrdered', - // @ts-expect-error: we’ve always used `null`. - start: null, - // @ts-expect-error Patched. - spread: token._spread, - children: [] - } - } - /** - * @param {Token} token - * @returns {ListItem} - */ - - function listItem(token) { - return { - type: 'listItem', - // @ts-expect-error Patched. - spread: token._spread, - // @ts-expect-error: we’ve always used `null`. - checked: null, - children: [] - } - } - /** @returns {Paragraph} */ - - function paragraph() { - return { - type: 'paragraph', - children: [] - } - } - /** @returns {Strong} */ - - function strong() { - return { - type: 'strong', - children: [] - } - } - /** @returns {Text} */ - - function text() { - return { - type: 'text', - value: '' - } - } - /** @returns {ThematicBreak} */ - - function thematicBreak() { - return { - type: 'thematicBreak' - } - } -} -/** - * @param {Extension} combined - * @param {Array.>} extensions - * @returns {Extension} - */ - -function configure$1(combined, extensions) { - let index = -1; - - while (++index < extensions.length) { - const value = extensions[index]; - - if (Array.isArray(value)) { - configure$1(combined, value); - } else { - extension(combined, value); - } - } - - return combined -} -/** - * @param {Extension} combined - * @param {Extension} extension - * @returns {void} - */ - -function extension(combined, extension) { - /** @type {string} */ - let key; - - for (key in extension) { - if (own$4.call(extension, key)) { - const list = key === 'canContainEols' || key === 'transforms'; - const maybe = own$4.call(combined, key) ? combined[key] : undefined; - /* c8 ignore next */ - - const left = maybe || (combined[key] = list ? [] : {}); - const right = extension[key]; - - if (right) { - if (list) { - // @ts-expect-error: `left` is an array. - combined[key] = [...left, ...right]; - } else { - Object.assign(left, right); - } - } - } - } -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('mdast-util-from-markdown').Options} Options - */ - -/** @type {import('unified').Plugin<[Options?] | void[], string, Root>} */ -function remarkParse(options) { - /** @type {import('unified').ParserFunction} */ - const parser = (doc) => { - // Assume options. - const settings = /** @type {Options} */ (this.data('settings')); - - return fromMarkdown( - doc, - Object.assign({}, settings, options, { - // Note: these options are not in the readme. - // The goal is for them to be set by plugins on `data` instead of being - // passed by users. - extensions: this.data('micromarkExtensions') || [], - mdastExtensions: this.data('fromMarkdownExtensions') || [] - }) - ) - }; - - Object.assign(this, {Parser: parser}); -} - -var own$3 = {}.hasOwnProperty; - -/** - * @callback Handler - * @param {...unknown} value - * @return {unknown} - * - * @typedef {Record} Handlers - * - * @typedef {Object} Options - * @property {Handler} [unknown] - * @property {Handler} [invalid] - * @property {Handlers} [handlers] - */ - -/** - * Handle values based on a property. - * - * @param {string} key - * @param {Options} [options] - */ -function zwitch(key, options) { - var settings = options || {}; - - /** - * Handle one value. - * Based on the bound `key`, a respective handler will be called. - * If `value` is not an object, or doesn’t have a `key` property, the special - * “invalid” handler will be called. - * If `value` has an unknown `key`, the special “unknown” handler will be - * called. - * - * All arguments, and the context object, are passed through to the handler, - * and it’s result is returned. - * - * @param {...unknown} [value] - * @this {unknown} - * @returns {unknown} - * @property {Handler} invalid - * @property {Handler} unknown - * @property {Handlers} handlers - */ - function one(value) { - var fn = one.invalid; - var handlers = one.handlers; - - if (value && own$3.call(value, key)) { - fn = own$3.call(handlers, value[key]) ? handlers[value[key]] : one.unknown; - } - - if (fn) { - return fn.apply(this, arguments) - } - } - - one.handlers = settings.handlers || {}; - one.invalid = settings.invalid; - one.unknown = settings.unknown; - - return one -} - -/** - * @typedef {import('./types.js').Options} Options - * @typedef {import('./types.js').Context} Context - */ - -/** - * @param {Context} base - * @param {Options} extension - * @returns {Context} - */ -function configure(base, extension) { - let index = -1; - /** @type {string} */ - let key; - - // First do subextensions. - if (extension.extensions) { - while (++index < extension.extensions.length) { - configure(base, extension.extensions[index]); - } - } - - for (key in extension) { - if (key === 'extensions') ; else if (key === 'unsafe' || key === 'join') { - /* c8 ignore next 2 */ - // @ts-expect-error: hush. - base[key] = [...(base[key] || []), ...(extension[key] || [])]; - } else if (key === 'handlers') { - base[key] = Object.assign(base[key], extension[key] || {}); - } else { - // @ts-expect-error: hush. - base.options[key] = extension[key]; - } - } - - return base -} - -/** - * @typedef {import('../types.js').Node} Node - * @typedef {import('../types.js').Parent} Parent - * @typedef {import('../types.js').Join} Join - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Parent} parent - * @param {Context} context - * @returns {string} - */ -function containerFlow(parent, context) { - const indexStack = context.indexStack; - const children = parent.children || []; - /** @type {Array.} */ - const results = []; - let index = -1; - - indexStack.push(-1); - - while (++index < children.length) { - const child = children[index]; - - indexStack[indexStack.length - 1] = index; - - results.push( - context.handle(child, parent, context, {before: '\n', after: '\n'}) - ); - - if (child.type !== 'list') { - context.bulletLastUsed = undefined; - } - - if (index < children.length - 1) { - results.push(between(child, children[index + 1])); - } - } - - indexStack.pop(); - - return results.join('') - - /** - * @param {Node} left - * @param {Node} right - * @returns {string} - */ - function between(left, right) { - let index = context.join.length; - - while (index--) { - const result = context.join[index](left, right, parent, context); - - if (result === true || result === 1) { - break - } - - if (typeof result === 'number') { - return '\n'.repeat(1 + result) - } - - if (result === false) { - return '\n\n\n\n' - } - } - - return '\n\n' - } -} - -/** - * @callback Map - * @param {string} value - * @param {number} line - * @param {boolean} blank - * @returns {string} - */ - -const eol = /\r?\n|\r/g; - -/** - * @param {string} value - * @param {Map} map - * @returns {string} - */ -function indentLines(value, map) { - /** @type {Array.} */ - const result = []; - let start = 0; - let line = 0; - /** @type {RegExpExecArray|null} */ - let match; - - while ((match = eol.exec(value))) { - one(value.slice(start, match.index)); - result.push(match[0]); - start = match.index + match[0].length; - line++; - } - - one(value.slice(start)); - - return result.join('') - - /** - * @param {string} value - */ - function one(value) { - result.push(map(value, line, !value)); - } -} - -/** - * @typedef {import('mdast').Blockquote} Blockquote - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../util/indent-lines.js').Map} Map - */ - -/** - * @type {Handle} - * @param {Blockquote} node - */ -function blockquote(node, _, context) { - const exit = context.enter('blockquote'); - const value = indentLines(containerFlow(node, context), map$1); - exit(); - return value -} - -/** @type {Map} */ -function map$1(line, _, blank) { - return '>' + (blank ? '' : ' ') + line -} - -/** - * @typedef {import('../types.js').Unsafe} Unsafe - */ - -/** - * @param {Array.} stack - * @param {Unsafe} pattern - * @returns {boolean} - */ -function patternInScope(stack, pattern) { - return ( - listInScope(stack, pattern.inConstruct, true) && - !listInScope(stack, pattern.notInConstruct, false) - ) -} - -/** - * @param {Array.} stack - * @param {Unsafe['inConstruct']} list - * @param {boolean} none - * @returns {boolean} - */ -function listInScope(stack, list, none) { - if (!list) { - return none - } - - if (typeof list === 'string') { - list = [list]; - } - - let index = -1; - - while (++index < list.length) { - if (stack.includes(list[index])) { - return true - } - } - - return false -} - -/** - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('mdast').Break} Break - */ - -/** - * @type {Handle} - * @param {Break} _ - */ -function hardBreak(_, _1, context, safe) { - let index = -1; - - while (++index < context.unsafe.length) { - // If we can’t put eols in this construct (setext headings, tables), use a - // space instead. - if ( - context.unsafe[index].character === '\n' && - patternInScope(context.stack, context.unsafe[index]) - ) { - return /[ \t]/.test(safe.before) ? '' : ' ' - } - } - - return '\\\n' -} - -/** - * Get the count of the longest repeating streak of `character` in `value`. - * - * @param {string} value Content. - * @param {string} character Single character to look for - * @returns {number} Count of most frequent adjacent `character`s in `value` - */ -function longestStreak(value, character) { - var source = String(value); - var index = source.indexOf(character); - var expected = index; - var count = 0; - var max = 0; - - if (typeof character !== 'string' || character.length !== 1) { - throw new Error('Expected character') - } - - while (index !== -1) { - if (index === expected) { - if (++count > max) { - max = count; - } - } else { - count = 1; - } - - expected = index + 1; - index = source.indexOf(character, expected); - } - - return max -} - -/** - * @typedef {import('mdast').Code} Code - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Code} node - * @param {Context} context - * @returns {boolean} - */ -function formatCodeAsIndented(node, context) { - return Boolean( - !context.options.fences && - node.value && - // If there’s no info… - !node.lang && - // And there’s a non-whitespace character… - /[^ \r\n]/.test(node.value) && - // And the value doesn’t start or end in a blank… - !/^[\t ]*(?:[\r\n]|$)|(?:^|[\r\n])[\t ]*$/.test(node.value) - ) -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkFence(context) { - const marker = context.options.fence || '`'; - - if (marker !== '`' && marker !== '~') { - throw new Error( - 'Cannot serialize code with `' + - marker + - '` for `options.fence`, expected `` ` `` or `~`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Unsafe} Unsafe - */ - -/** - * @param {Unsafe} pattern - * @returns {RegExp} - */ -function patternCompile(pattern) { - if (!pattern._compiled) { - const before = - (pattern.atBreak ? '[\\r\\n][\\t ]*' : '') + - (pattern.before ? '(?:' + pattern.before + ')' : ''); - - pattern._compiled = new RegExp( - (before ? '(' + before + ')' : '') + - (/[|\\{}()[\]^$+*?.-]/.test(pattern.character) ? '\\' : '') + - pattern.character + - (pattern.after ? '(?:' + pattern.after + ')' : ''), - 'g' - ); - } - - return pattern._compiled -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').SafeOptions} SafeOptions - */ - -/** - * @param {Context} context - * @param {string|null|undefined} input - * @param {SafeOptions & {encode?: Array.}} config - * @returns {string} - */ -function safe(context, input, config) { - const value = (config.before || '') + (input || '') + (config.after || ''); - /** @type {Array.} */ - const positions = []; - /** @type {Array.} */ - const result = []; - /** @type {Record} */ - const infos = {}; - let index = -1; - - while (++index < context.unsafe.length) { - const pattern = context.unsafe[index]; - - if (!patternInScope(context.stack, pattern)) { - continue - } - - const expression = patternCompile(pattern); - /** @type {RegExpExecArray|null} */ - let match; - - while ((match = expression.exec(value))) { - const before = 'before' in pattern || Boolean(pattern.atBreak); - const after = 'after' in pattern; - const position = match.index + (before ? match[1].length : 0); - - if (positions.includes(position)) { - if (infos[position].before && !before) { - infos[position].before = false; - } - - if (infos[position].after && !after) { - infos[position].after = false; - } - } else { - positions.push(position); - infos[position] = {before, after}; - } - } - } - - positions.sort(numerical); - - let start = config.before ? config.before.length : 0; - const end = value.length - (config.after ? config.after.length : 0); - index = -1; - - while (++index < positions.length) { - const position = positions[index]; - - // Character before or after matched: - if (position < start || position >= end) { - continue - } - - // If this character is supposed to be escaped because it has a condition on - // the next character, and the next character is definitly being escaped, - // then skip this escape. - if ( - (position + 1 < end && - positions[index + 1] === position + 1 && - infos[position].after && - !infos[position + 1].before && - !infos[position + 1].after) || - (positions[index - 1] === position - 1 && - infos[position].before && - !infos[position - 1].before && - !infos[position - 1].after) - ) { - continue - } - - if (start !== position) { - // If we have to use a character reference, an ampersand would be more - // correct, but as backslashes only care about punctuation, either will - // do the trick - result.push(escapeBackslashes(value.slice(start, position), '\\')); - } - - start = position; - - if ( - /[!-/:-@[-`{-~]/.test(value.charAt(position)) && - (!config.encode || !config.encode.includes(value.charAt(position))) - ) { - // Character escape. - result.push('\\'); - } else { - // Character reference. - result.push( - '&#x' + value.charCodeAt(position).toString(16).toUpperCase() + ';' - ); - start++; - } - } - - result.push(escapeBackslashes(value.slice(start, end), config.after)); - - return result.join('') -} - -/** - * @param {number} a - * @param {number} b - * @returns {number} - */ -function numerical(a, b) { - return a - b -} - -/** - * @param {string} value - * @param {string} after - * @returns {string} - */ -function escapeBackslashes(value, after) { - const expression = /\\(?=[!-/:-@[-`{-~])/g; - /** @type {Array.} */ - const positions = []; - /** @type {Array.} */ - const results = []; - const whole = value + after; - let index = -1; - let start = 0; - /** @type {RegExpExecArray|null} */ - let match; - - while ((match = expression.exec(whole))) { - positions.push(match.index); - } - - while (++index < positions.length) { - if (start !== positions[index]) { - results.push(value.slice(start, positions[index])); - } - - results.push('\\'); - start = positions[index]; - } - - results.push(value.slice(start)); - - return results.join('') -} - -/** - * @typedef {import('mdast').Code} Code - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../types.js').Exit} Exit - * @typedef {import('../util/indent-lines.js').Map} Map - */ - -/** - * @type {Handle} - * @param {Code} node - */ -function code$1(node, _, context) { - const marker = checkFence(context); - const raw = node.value || ''; - const suffix = marker === '`' ? 'GraveAccent' : 'Tilde'; - /** @type {string} */ - let value; - /** @type {Exit} */ - let exit; - - if (formatCodeAsIndented(node, context)) { - exit = context.enter('codeIndented'); - value = indentLines(raw, map); - } else { - const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3)); - /** @type {Exit} */ - let subexit; - exit = context.enter('codeFenced'); - value = sequence; - - if (node.lang) { - subexit = context.enter('codeFencedLang' + suffix); - value += safe(context, node.lang, { - before: '`', - after: ' ', - encode: ['`'] - }); - subexit(); - } - - if (node.lang && node.meta) { - subexit = context.enter('codeFencedMeta' + suffix); - value += - ' ' + - safe(context, node.meta, { - before: ' ', - after: '\n', - encode: ['`'] - }); - subexit(); - } - - value += '\n'; - - if (raw) { - value += raw + '\n'; - } - - value += sequence; - } - - exit(); - return value -} - -/** @type {Map} */ -function map(line, _, blank) { - return (blank ? '' : ' ') + line -} - -/** - * @typedef {import('mdast').Association} Association - */ - -const characterEscape = /\\([!-/:-@[-`{-~])/g; -const characterReference = /&(#(\d{1,7}|x[\da-f]{1,6})|[\da-z]{1,31});/gi; - -/** - * The `label` of an association is the string value: character escapes and - * references work, and casing is intact. - * The `identifier` is used to match one association to another: controversially, - * character escapes and references don’t work in this matching: `©` does - * not match `©`, and `\+` does not match `+`. - * But casing is ignored (and whitespace) is trimmed and collapsed: ` A\nb` - * matches `a b`. - * So, we do prefer the label when figuring out how we’re going to serialize: - * it has whitespace, casing, and we can ignore most useless character escapes - * and all character references. - * - * @param {Association} node - * @returns {string} - */ -function association(node) { - if (node.label || !node.identifier) { - return node.label || '' - } - - return node.identifier - .replace(characterEscape, '$1') - .replace(characterReference, decodeIfPossible) -} - -/** - * @param {string} $0 - * @param {string} $1 - * @returns {string} - */ -function decodeIfPossible($0, $1) { - return decodeEntity($1) || $0 -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkQuote(context) { - const marker = context.options.quote || '"'; - - if (marker !== '"' && marker !== "'") { - throw new Error( - 'Cannot serialize title with `' + - marker + - '` for `options.quote`, expected `"`, or `\'`' - ) - } - - return marker -} - -/** - * @typedef {import('mdast').Definition} Definition - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Definition} node - */ -function definition(node, _, context) { - const marker = checkQuote(context); - const suffix = marker === '"' ? 'Quote' : 'Apostrophe'; - const exit = context.enter('definition'); - let subexit = context.enter('label'); - let value = - '[' + safe(context, association(node), {before: '[', after: ']'}) + ']: '; - - subexit(); - - if ( - // If there’s no url, or… - !node.url || - // If there’s whitespace, enclosed is prettier. - /[ \t\r\n]/.test(node.url) - ) { - subexit = context.enter('destinationLiteral'); - value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; - } else { - // No whitespace, raw is prettier. - subexit = context.enter('destinationRaw'); - value += safe(context, node.url, {before: ' ', after: ' '}); - } - - subexit(); - - if (node.title) { - subexit = context.enter('title' + suffix); - value += - ' ' + - marker + - safe(context, node.title, {before: marker, after: marker}) + - marker; - subexit(); - } - - exit(); - - return value -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkEmphasis(context) { - const marker = context.options.emphasis || '*'; - - if (marker !== '*' && marker !== '_') { - throw new Error( - 'Cannot serialize emphasis with `' + - marker + - '` for `options.emphasis`, expected `*`, or `_`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Node} Node - * @typedef {import('../types.js').Parent} Parent - * @typedef {import('../types.js').SafeOptions} SafeOptions - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Parent} parent - * @param {Context} context - * @param {SafeOptions} safeOptions - * @returns {string} - */ -function containerPhrasing(parent, context, safeOptions) { - const indexStack = context.indexStack; - const children = parent.children || []; - /** @type {Array.} */ - const results = []; - let index = -1; - let before = safeOptions.before; - - indexStack.push(-1); - - while (++index < children.length) { - const child = children[index]; - /** @type {string} */ - let after; - - indexStack[indexStack.length - 1] = index; - - if (index + 1 < children.length) { - // @ts-expect-error: hush, it’s actually a `zwitch`. - let handle = context.handle.handlers[children[index + 1].type]; - if (handle && handle.peek) handle = handle.peek; - after = handle - ? handle(children[index + 1], parent, context, { - before: '', - after: '' - }).charAt(0) - : ''; - } else { - after = safeOptions.after; - } - - // In some cases, html (text) can be found in phrasing right after an eol. - // When we’d serialize that, in most cases that would be seen as html - // (flow). - // As we can’t escape or so to prevent it from happening, we take a somewhat - // reasonable approach: replace that eol with a space. - // See: - if ( - results.length > 0 && - (before === '\r' || before === '\n') && - child.type === 'html' - ) { - results[results.length - 1] = results[results.length - 1].replace( - /(\r?\n|\r)$/, - ' ' - ); - before = ' '; - } - - results.push(context.handle(child, parent, context, {before, after})); - - before = results[results.length - 1].slice(-1); - } - - indexStack.pop(); - - return results.join('') -} - -/** - * @typedef {import('mdast').Emphasis} Emphasis - * @typedef {import('../types.js').Handle} Handle - */ - -emphasis.peek = emphasisPeek; - -// To do: there are cases where emphasis cannot “form” depending on the -// previous or next character of sequences. -// There’s no way around that though, except for injecting zero-width stuff. -// Do we need to safeguard against that? -/** - * @type {Handle} - * @param {Emphasis} node - */ -function emphasis(node, _, context) { - const marker = checkEmphasis(context); - const exit = context.enter('emphasis'); - const value = containerPhrasing(node, context, { - before: marker, - after: marker - }); - exit(); - return marker + value + marker -} - -/** - * @type {Handle} - * @param {Emphasis} _ - */ -function emphasisPeek(_, _1, context) { - return context.options.emphasis || '*' -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * - * @typedef {string} Type - * @typedef {Object} Props - * - * @typedef {null|undefined|Type|Props|TestFunctionAnything|Array.} Test - */ - -const convert = - /** - * @type {( - * ((test: T['type']|Partial|TestFunctionPredicate) => AssertPredicate) & - * ((test?: Test) => AssertAnything) - * )} - */ - ( - /** - * Generate an assertion from a check. - * @param {Test} [test] - * When nullish, checks if `node` is a `Node`. - * When `string`, works like passing `function (node) {return node.type === test}`. - * When `function` checks if function passed the node is true. - * When `object`, checks that all keys in test are in node, and that they have (strictly) equal values. - * When `array`, checks any one of the subtests pass. - * @returns {AssertAnything} - */ - function (test) { - if (test === undefined || test === null) { - return ok - } - - if (typeof test === 'string') { - return typeFactory(test) - } - - if (typeof test === 'object') { - return Array.isArray(test) ? anyFactory(test) : propsFactory(test) - } - - if (typeof test === 'function') { - return castFactory(test) - } - - throw new Error('Expected function, string, or object as test') - } - ); -/** - * @param {Array.} tests - * @returns {AssertAnything} - */ -function anyFactory(tests) { - /** @type {Array.} */ - const checks = []; - let index = -1; - - while (++index < tests.length) { - checks[index] = convert(tests[index]); - } - - return castFactory(any) - - /** - * @this {unknown} - * @param {unknown[]} parameters - * @returns {boolean} - */ - function any(...parameters) { - let index = -1; - - while (++index < checks.length) { - if (checks[index].call(this, ...parameters)) return true - } - - return false - } -} - -/** - * Utility to assert each property in `test` is represented in `node`, and each - * values are strictly equal. - * - * @param {Props} check - * @returns {AssertAnything} - */ -function propsFactory(check) { - return castFactory(all) - - /** - * @param {Node} node - * @returns {boolean} - */ - function all(node) { - /** @type {string} */ - let key; - - for (key in check) { - // @ts-expect-error: hush, it sure works as an index. - if (node[key] !== check[key]) return false - } - - return true - } -} - -/** - * Utility to convert a string into a function which checks a given node’s type - * for said string. - * - * @param {Type} check - * @returns {AssertAnything} - */ -function typeFactory(check) { - return castFactory(type) - - /** - * @param {Node} node - */ - function type(node) { - return node && node.type === check - } -} - -/** - * Utility to convert a string into a function which checks a given node’s type - * for said string. - * @param {TestFunctionAnything} check - * @returns {AssertAnything} - */ -function castFactory(check) { - return assertion - - /** - * @this {unknown} - * @param {Array.} parameters - * @returns {boolean} - */ - function assertion(...parameters) { - // @ts-expect-error: spreading is fine. - return Boolean(check.call(this, ...parameters)) - } -} - -// Utility to return true. -function ok() { - return true -} - -/** - * @param {string} d - * @returns {string} - */ -function color$1(d) { - return '\u001B[33m' + d + '\u001B[39m' -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - */ - -/** - * Continue traversing as normal - */ -const CONTINUE$1 = true; -/** - * Do not traverse this node’s children - */ -const SKIP$1 = 'skip'; -/** - * Stop traversing immediately - */ -const EXIT$1 = false; - -/** - * Visit children of tree which pass a test - * - * @param tree Abstract syntax tree to walk - * @param test Test node, optional - * @param visitor Function to run for each node - * @param reverse Visit the tree in reverse order, defaults to false - */ -const visitParents$1 = - /** - * @type {( - * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & - * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) - * )} - */ - ( - /** - * @param {Node} tree - * @param {Test} test - * @param {Visitor} visitor - * @param {boolean} [reverse] - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - // @ts-expect-error no visitor given, so `visitor` is test. - visitor = test; - test = null; - } - - const is = convert(test); - const step = reverse ? -1 : 1; - - factory(tree, null, [])(); - - /** - * @param {Node} node - * @param {number?} index - * @param {Array.} parents - */ - function factory(node, index, parents) { - /** @type {Object.} */ - // @ts-expect-error: hush - const value = typeof node === 'object' && node !== null ? node : {}; - /** @type {string|undefined} */ - let name; - - if (typeof value.type === 'string') { - name = - typeof value.tagName === 'string' - ? value.tagName - : typeof value.name === 'string' - ? value.name - : undefined; - - Object.defineProperty(visit, 'name', { - value: - 'node (' + - color$1(value.type + (name ? '<' + name + '>' : '')) + - ')' - }); - } - - return visit - - function visit() { - /** @type {ActionTuple} */ - let result = []; - /** @type {ActionTuple} */ - let subresult; - /** @type {number} */ - let offset; - /** @type {Array.} */ - let grandparents; - - if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult$1(visitor(node, parents)); - - if (result[0] === EXIT$1) { - return result - } - } - - // @ts-expect-error looks like a parent. - if (node.children && result[0] !== SKIP$1) { - // @ts-expect-error looks like a parent. - offset = (reverse ? node.children.length : -1) + step; - // @ts-expect-error looks like a parent. - grandparents = parents.concat(node); - - // @ts-expect-error looks like a parent. - while (offset > -1 && offset < node.children.length) { - // @ts-expect-error looks like a parent. - subresult = factory(node.children[offset], offset, grandparents)(); - - if (subresult[0] === EXIT$1) { - return subresult - } - - offset = - typeof subresult[1] === 'number' ? subresult[1] : offset + step; - } - } - - return result - } - } - } - ); - -/** - * @param {VisitorResult} value - * @returns {ActionTuple} - */ -function toResult$1(value) { - if (Array.isArray(value)) { - return value - } - - if (typeof value === 'number') { - return [CONTINUE$1, value] - } - - return [value] -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult - */ - -/** - * Visit children of tree which pass a test - * - * @param tree Abstract syntax tree to walk - * @param test Test, optional - * @param visitor Function to run for each node - * @param reverse Fisit the tree in reverse, defaults to false - */ -const visit$1 = - /** - * @type {( - * ((tree: Tree, test: Check, visitor: Visitor, Check>>, reverse?: boolean) => void) & - * ((tree: Tree, visitor: Visitor>, reverse?: boolean) => void) - * )} - */ - ( - /** - * @param {Node} tree - * @param {Test} test - * @param {Visitor} visitor - * @param {boolean} [reverse] - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } - - visitParents$1(tree, test, overload, reverse); - - /** - * @param {Node} node - * @param {Array.} parents - */ - function overload(node, parents) { - const parent = parents[parents.length - 1]; - return visitor( - node, - parent ? parent.children.indexOf(node) : null, - parent - ) - } - } - ); - -/** - * @typedef {import('mdast').Heading} Heading - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Heading} node - * @param {Context} context - * @returns {boolean} - */ -function formatHeadingAsSetext(node, context) { - let literalWithBreak = false; - - // Look for literals with a line break. - // Note that this also - visit$1(node, (node) => { - if ( - ('value' in node && /\r?\n|\r/.test(node.value)) || - node.type === 'break' - ) { - literalWithBreak = true; - return EXIT$1 - } - }); - - return Boolean( - (!node.depth || node.depth < 3) && - toString(node) && - (context.options.setext || literalWithBreak) - ) -} - -/** - * @typedef {import('mdast').Heading} Heading - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../types.js').Exit} Exit - */ - -/** - * @type {Handle} - * @param {Heading} node - */ -function heading(node, _, context) { - const rank = Math.max(Math.min(6, node.depth || 1), 1); - - if (formatHeadingAsSetext(node, context)) { - const exit = context.enter('headingSetext'); - const subexit = context.enter('phrasing'); - const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); - subexit(); - exit(); - - return ( - value + - '\n' + - (rank === 1 ? '=' : '-').repeat( - // The whole size… - value.length - - // Minus the position of the character after the last EOL (or - // 0 if there is none)… - (Math.max(value.lastIndexOf('\r'), value.lastIndexOf('\n')) + 1) - ) - ) - } - - const sequence = '#'.repeat(rank); - const exit = context.enter('headingAtx'); - const subexit = context.enter('phrasing'); - let value = containerPhrasing(node, context, {before: '# ', after: '\n'}); - - if (/^[\t ]/.test(value)) { - value = - '&#x' + - value.charCodeAt(0).toString(16).toUpperCase() + - ';' + - value.slice(1); - } - - value = value ? sequence + ' ' + value : sequence; - - if (context.options.closeAtx) { - value += ' ' + sequence; - } - - subexit(); - exit(); - - return value -} - -/** - * @typedef {import('mdast').HTML} HTML - * @typedef {import('../types.js').Handle} Handle - */ - -html.peek = htmlPeek; - -/** - * @type {Handle} - * @param {HTML} node - */ -function html(node) { - return node.value || '' -} - -/** - * @type {Handle} - */ -function htmlPeek() { - return '<' -} - -/** - * @typedef {import('mdast').Image} Image - * @typedef {import('../types.js').Handle} Handle - */ - -image.peek = imagePeek; - -/** - * @type {Handle} - * @param {Image} node - */ -function image(node, _, context) { - const quote = checkQuote(context); - const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; - const exit = context.enter('image'); - let subexit = context.enter('label'); - let value = '![' + safe(context, node.alt, {before: '[', after: ']'}) + ']('; - - subexit(); - - if ( - // If there’s no url but there is a title… - (!node.url && node.title) || - // Or if there’s markdown whitespace or an eol, enclose. - /[ \t\r\n]/.test(node.url) - ) { - subexit = context.enter('destinationLiteral'); - value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; - } else { - // No whitespace, raw is prettier. - subexit = context.enter('destinationRaw'); - value += safe(context, node.url, { - before: '(', - after: node.title ? ' ' : ')' - }); - } - - subexit(); - - if (node.title) { - subexit = context.enter('title' + suffix); - value += - ' ' + - quote + - safe(context, node.title, {before: quote, after: quote}) + - quote; - subexit(); - } - - value += ')'; - exit(); - - return value -} - -/** - * @type {Handle} - */ -function imagePeek() { - return '!' -} - -/** - * @typedef {import('mdast').ImageReference} ImageReference - * @typedef {import('../types.js').Handle} Handle - */ - -imageReference.peek = imageReferencePeek; - -/** - * @type {Handle} - * @param {ImageReference} node - */ -function imageReference(node, _, context) { - const type = node.referenceType; - const exit = context.enter('imageReference'); - let subexit = context.enter('label'); - const alt = safe(context, node.alt, {before: '[', after: ']'}); - let value = '![' + alt + ']'; - - subexit(); - // Hide the fact that we’re in phrasing, because escapes don’t work. - const stack = context.stack; - context.stack = []; - subexit = context.enter('reference'); - const reference = safe(context, association(node), {before: '[', after: ']'}); - subexit(); - context.stack = stack; - exit(); - - if (type === 'full' || !alt || alt !== reference) { - value += '[' + reference + ']'; - } else if (type !== 'shortcut') { - value += '[]'; - } - - return value -} - -/** - * @type {Handle} - */ -function imageReferencePeek() { - return '!' -} - -/** - * @typedef {import('mdast').InlineCode} InlineCode - * @typedef {import('../types.js').Handle} Handle - */ - -inlineCode.peek = inlineCodePeek; - -/** - * @type {Handle} - * @param {InlineCode} node - */ -function inlineCode(node, _, context) { - let value = node.value || ''; - let sequence = '`'; - let index = -1; - - // If there is a single grave accent on its own in the code, use a fence of - // two. - // If there are two in a row, use one. - while (new RegExp('(^|[^`])' + sequence + '([^`]|$)').test(value)) { - sequence += '`'; - } - - // If this is not just spaces or eols (tabs don’t count), and either the - // first or last character are a space, eol, or tick, then pad with spaces. - if ( - /[^ \r\n]/.test(value) && - ((/^[ \r\n]/.test(value) && /[ \r\n]$/.test(value)) || /^`|`$/.test(value)) - ) { - value = ' ' + value + ' '; - } - - // We have a potential problem: certain characters after eols could result in - // blocks being seen. - // For example, if someone injected the string `'\n# b'`, then that would - // result in an ATX heading. - // We can’t escape characters in `inlineCode`, but because eols are - // transformed to spaces when going from markdown to HTML anyway, we can swap - // them out. - while (++index < context.unsafe.length) { - const pattern = context.unsafe[index]; - const expression = patternCompile(pattern); - /** @type {RegExpExecArray|null} */ - let match; - - // Only look for `atBreak`s. - // Btw: note that `atBreak` patterns will always start the regex at LF or - // CR. - if (!pattern.atBreak) continue - - while ((match = expression.exec(value))) { - let position = match.index; - - // Support CRLF (patterns only look for one of the characters). - if ( - value.charCodeAt(position) === 10 /* `\n` */ && - value.charCodeAt(position - 1) === 13 /* `\r` */ - ) { - position--; - } - - value = value.slice(0, position) + ' ' + value.slice(match.index + 1); - } - } - - return sequence + value + sequence -} - -/** - * @type {Handle} - */ -function inlineCodePeek() { - return '`' -} - -/** - * @typedef {import('mdast').Link} Link - * @typedef {import('../types.js').Context} Context - */ - -/** - * @param {Link} node - * @param {Context} context - * @returns {boolean} - */ -function formatLinkAsAutolink(node, context) { - const raw = toString(node); - - return Boolean( - !context.options.resourceLink && - // If there’s a url… - node.url && - // And there’s a no title… - !node.title && - // And the content of `node` is a single text node… - node.children && - node.children.length === 1 && - node.children[0].type === 'text' && - // And if the url is the same as the content… - (raw === node.url || 'mailto:' + raw === node.url) && - // And that starts w/ a protocol… - /^[a-z][a-z+.-]+:/i.test(node.url) && - // And that doesn’t contain ASCII control codes (character escapes and - // references don’t work) or angle brackets… - !/[\0- <>\u007F]/.test(node.url) - ) -} - -/** - * @typedef {import('mdast').Link} Link - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('../types.js').Exit} Exit - */ - -link.peek = linkPeek; - -/** - * @type {Handle} - * @param {Link} node - */ -function link(node, _, context) { - const quote = checkQuote(context); - const suffix = quote === '"' ? 'Quote' : 'Apostrophe'; - /** @type {Exit} */ - let exit; - /** @type {Exit} */ - let subexit; - /** @type {string} */ - let value; - - if (formatLinkAsAutolink(node, context)) { - // Hide the fact that we’re in phrasing, because escapes don’t work. - const stack = context.stack; - context.stack = []; - exit = context.enter('autolink'); - value = - '<' + containerPhrasing(node, context, {before: '<', after: '>'}) + '>'; - exit(); - context.stack = stack; - return value - } - - exit = context.enter('link'); - subexit = context.enter('label'); - value = - '[' + containerPhrasing(node, context, {before: '[', after: ']'}) + ']('; - subexit(); - - if ( - // If there’s no url but there is a title… - (!node.url && node.title) || - // Or if there’s markdown whitespace or an eol, enclose. - /[ \t\r\n]/.test(node.url) - ) { - subexit = context.enter('destinationLiteral'); - value += '<' + safe(context, node.url, {before: '<', after: '>'}) + '>'; - } else { - // No whitespace, raw is prettier. - subexit = context.enter('destinationRaw'); - value += safe(context, node.url, { - before: '(', - after: node.title ? ' ' : ')' - }); - } - - subexit(); - - if (node.title) { - subexit = context.enter('title' + suffix); - value += - ' ' + - quote + - safe(context, node.title, {before: quote, after: quote}) + - quote; - subexit(); - } - - value += ')'; - - exit(); - return value -} - -/** - * @type {Handle} - * @param {Link} node - */ -function linkPeek(node, _, context) { - return formatLinkAsAutolink(node, context) ? '<' : '[' -} - -/** - * @typedef {import('mdast').LinkReference} LinkReference - * @typedef {import('../types.js').Handle} Handle - */ - -linkReference.peek = linkReferencePeek; - -/** - * @type {Handle} - * @param {LinkReference} node - */ -function linkReference(node, _, context) { - const type = node.referenceType; - const exit = context.enter('linkReference'); - let subexit = context.enter('label'); - const text = containerPhrasing(node, context, {before: '[', after: ']'}); - let value = '[' + text + ']'; - - subexit(); - // Hide the fact that we’re in phrasing, because escapes don’t work. - const stack = context.stack; - context.stack = []; - subexit = context.enter('reference'); - const reference = safe(context, association(node), {before: '[', after: ']'}); - subexit(); - context.stack = stack; - exit(); - - if (type === 'full' || !text || text !== reference) { - value += '[' + reference + ']'; - } else if (type !== 'shortcut') { - value += '[]'; - } - - return value -} - -/** - * @type {Handle} - */ -function linkReferencePeek() { - return '[' -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBullet(context) { - const marker = context.options.bullet || '*'; - - if (marker !== '*' && marker !== '+' && marker !== '-') { - throw new Error( - 'Cannot serialize items with `' + - marker + - '` for `options.bullet`, expected `*`, `+`, or `-`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBulletOther(context) { - const bullet = checkBullet(context); - const bulletOther = context.options.bulletOther; - - if (!bulletOther) { - return bullet === '*' ? '-' : '*' - } - - if (bulletOther !== '*' && bulletOther !== '+' && bulletOther !== '-') { - throw new Error( - 'Cannot serialize items with `' + - bulletOther + - '` for `options.bulletOther`, expected `*`, `+`, or `-`' - ) - } - - if (bulletOther === bullet) { - throw new Error( - 'Expected `bullet` (`' + - bullet + - '`) and `bulletOther` (`' + - bulletOther + - '`) to be different' - ) - } - - return bulletOther -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBulletOrdered(context) { - const marker = context.options.bulletOrdered || '.'; - - if (marker !== '.' && marker !== ')') { - throw new Error( - 'Cannot serialize items with `' + - marker + - '` for `options.bulletOrdered`, expected `.` or `)`' - ) - } - - return marker -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkBulletOrderedOther(context) { - const bulletOrdered = checkBulletOrdered(context); - const bulletOrderedOther = context.options.bulletOrderedOther; - - if (!bulletOrderedOther) { - return bulletOrdered === '.' ? ')' : '.' - } - - if (bulletOrderedOther !== '.' && bulletOrderedOther !== ')') { - throw new Error( - 'Cannot serialize items with `' + - bulletOrderedOther + - '` for `options.bulletOrderedOther`, expected `*`, `+`, or `-`' - ) - } - - if (bulletOrderedOther === bulletOrdered) { - throw new Error( - 'Expected `bulletOrdered` (`' + - bulletOrdered + - '`) and `bulletOrderedOther` (`' + - bulletOrderedOther + - '`) to be different' - ) - } - - return bulletOrderedOther -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkRule(context) { - const marker = context.options.rule || '*'; - - if (marker !== '*' && marker !== '-' && marker !== '_') { - throw new Error( - 'Cannot serialize rules with `' + - marker + - '` for `options.rule`, expected `*`, `-`, or `_`' - ) - } - - return marker -} - -/** - * @typedef {import('mdast').List} List - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {List} node - */ -function list(node, parent, context) { - const exit = context.enter('list'); - const bulletCurrent = context.bulletCurrent; - /** @type {string} */ - let bullet = node.ordered ? checkBulletOrdered(context) : checkBullet(context); - /** @type {string} */ - const bulletOther = node.ordered - ? checkBulletOrderedOther(context) - : checkBulletOther(context); - const bulletLastUsed = context.bulletLastUsed; - let useDifferentMarker = false; - - if ( - parent && - // Explicit `other` set. - (node.ordered - ? context.options.bulletOrderedOther - : context.options.bulletOther) && - bulletLastUsed && - bullet === bulletLastUsed - ) { - useDifferentMarker = true; - } - - if (!node.ordered) { - const firstListItem = node.children ? node.children[0] : undefined; - - // If there’s an empty first list item directly in two list items, - // we have to use a different bullet: - // - // ```markdown - // * - * - // ``` - // - // …because otherwise it would become one big thematic break. - if ( - // Bullet could be used as a thematic break marker: - (bullet === '*' || bullet === '-') && - // Empty first list item: - firstListItem && - (!firstListItem.children || !firstListItem.children[0]) && - // Directly in two other list items: - context.stack[context.stack.length - 1] === 'list' && - context.stack[context.stack.length - 2] === 'listItem' && - context.stack[context.stack.length - 3] === 'list' && - context.stack[context.stack.length - 4] === 'listItem' && - // That are each the first child. - context.indexStack[context.indexStack.length - 1] === 0 && - context.indexStack[context.indexStack.length - 2] === 0 && - context.indexStack[context.indexStack.length - 3] === 0 && - context.indexStack[context.indexStack.length - 4] === 0 - ) { - useDifferentMarker = true; - } - - // If there’s a thematic break at the start of the first list item, - // we have to use a different bullet: - // - // ```markdown - // * --- - // ``` - // - // …because otherwise it would become one big thematic break. - if (checkRule(context) === bullet && firstListItem) { - let index = -1; - - while (++index < node.children.length) { - const item = node.children[index]; - - if ( - item && - item.type === 'listItem' && - item.children && - item.children[0] && - item.children[0].type === 'thematicBreak' - ) { - useDifferentMarker = true; - break - } - } - } - } - - if (useDifferentMarker) { - bullet = bulletOther; - } - - context.bulletCurrent = bullet; - const value = containerFlow(node, context); - context.bulletLastUsed = bullet; - context.bulletCurrent = bulletCurrent; - exit(); - return value -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkListItemIndent(context) { - const style = context.options.listItemIndent || 'tab'; - - // To do: remove in a major. - // @ts-expect-error: deprecated. - if (style === 1 || style === '1') { - return 'one' - } - - if (style !== 'tab' && style !== 'one' && style !== 'mixed') { - throw new Error( - 'Cannot serialize items with `' + - style + - '` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`' - ) - } - - return style -} - -/** - * @typedef {import('mdast').ListItem} ListItem - * @typedef {import('mdast').List} List - * @typedef {import('../util/indent-lines.js').Map} Map - * @typedef {import('../types.js').Options} Options - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {ListItem} node - */ -function listItem(node, parent, context) { - const listItemIndent = checkListItemIndent(context); - let bullet = context.bulletCurrent || checkBullet(context); - - // Add the marker value for ordered lists. - if (parent && parent.type === 'list' && parent.ordered) { - bullet = - (typeof parent.start === 'number' && parent.start > -1 - ? parent.start - : 1) + - (context.options.incrementListMarker === false - ? 0 - : parent.children.indexOf(node)) + - bullet; - } - - let size = bullet.length + 1; - - if ( - listItemIndent === 'tab' || - (listItemIndent === 'mixed' && - ((parent && parent.type === 'list' && parent.spread) || node.spread)) - ) { - size = Math.ceil(size / 4) * 4; - } - - const exit = context.enter('listItem'); - const value = indentLines(containerFlow(node, context), map); - exit(); - - return value - - /** @type {Map} */ - function map(line, index, blank) { - if (index) { - return (blank ? '' : ' '.repeat(size)) + line - } - - return (blank ? bullet : bullet + ' '.repeat(size - bullet.length)) + line - } -} - -/** - * @typedef {import('mdast').Paragraph} Paragraph - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Paragraph} node - */ -function paragraph(node, _, context) { - const exit = context.enter('paragraph'); - const subexit = context.enter('phrasing'); - const value = containerPhrasing(node, context, {before: '\n', after: '\n'}); - subexit(); - exit(); - return value -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Root} node - */ -function root(node, _, context) { - return containerFlow(node, context) -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkStrong(context) { - const marker = context.options.strong || '*'; - - if (marker !== '*' && marker !== '_') { - throw new Error( - 'Cannot serialize strong with `' + - marker + - '` for `options.strong`, expected `*`, or `_`' - ) - } - - return marker -} - -/** - * @typedef {import('mdast').Strong} Strong - * @typedef {import('../types.js').Handle} Handle - */ - -strong.peek = strongPeek; - -// To do: there are cases where emphasis cannot “form” depending on the -// previous or next character of sequences. -// There’s no way around that though, except for injecting zero-width stuff. -// Do we need to safeguard against that? -/** - * @type {Handle} - * @param {Strong} node - */ -function strong(node, _, context) { - const marker = checkStrong(context); - const exit = context.enter('strong'); - const value = containerPhrasing(node, context, { - before: marker, - after: marker - }); - exit(); - return marker + marker + value + marker + marker -} - -/** - * @type {Handle} - * @param {Strong} _ - */ -function strongPeek(_, _1, context) { - return context.options.strong || '*' -} - -/** - * @typedef {import('mdast').Text} Text - * @typedef {import('../types.js').Handle} Handle - */ - -/** - * @type {Handle} - * @param {Text} node - */ -function text$1(node, _, context, safeOptions) { - return safe(context, node.value, safeOptions) -} - -/** - * @typedef {import('../types.js').Context} Context - * @typedef {import('../types.js').Options} Options - */ - -/** - * @param {Context} context - * @returns {Exclude} - */ -function checkRuleRepetition(context) { - const repetition = context.options.ruleRepetition || 3; - - if (repetition < 3) { - throw new Error( - 'Cannot serialize rules with repetition `' + - repetition + - '` for `options.ruleRepetition`, expected `3` or more' - ) - } - - return repetition -} - -/** - * @typedef {import('../types.js').Handle} Handle - * @typedef {import('mdast').ThematicBreak} ThematicBreak - */ - -/** - * @type {Handle} - * @param {ThematicBreak} _ - */ -function thematicBreak(_, _1, context) { - const value = ( - checkRule(context) + (context.options.ruleSpaces ? ' ' : '') - ).repeat(checkRuleRepetition(context)); - - return context.options.ruleSpaces ? value.slice(0, -1) : value -} - -const handle = { - blockquote, - break: hardBreak, - code: code$1, - definition, - emphasis, - hardBreak, - heading, - html, - image, - imageReference, - inlineCode, - link, - linkReference, - list, - listItem, - paragraph, - root, - strong, - text: text$1, - thematicBreak -}; - -/** - * @typedef {import('./types.js').Join} Join - */ - -/** @type {Array.} */ -const join = [joinDefaults]; - -/** @type {Join} */ -function joinDefaults(left, right, parent, context) { - // Indented code after list or another indented code. - if ( - right.type === 'code' && - formatCodeAsIndented(right, context) && - (left.type === 'list' || - (left.type === right.type && formatCodeAsIndented(left, context))) - ) { - return false - } - - // Two lists with the same marker. - if ( - left.type === 'list' && - left.type === right.type && - Boolean(left.ordered) === Boolean(right.ordered) && - !(left.ordered - ? context.options.bulletOrderedOther - : context.options.bulletOther) - ) { - return false - } - - // Join children of a list or an item. - // In which case, `parent` has a `spread` field. - if ('spread' in parent && typeof parent.spread === 'boolean') { - if ( - left.type === 'paragraph' && - // Two paragraphs. - (left.type === right.type || - right.type === 'definition' || - // Paragraph followed by a setext heading. - (right.type === 'heading' && formatHeadingAsSetext(right, context))) - ) { - return - } - - return parent.spread ? 1 : 0 - } -} - -/** - * @typedef {import('./types.js').Unsafe} Unsafe - */ - -/** @type {Array.} */ -const unsafe = [ - {character: '\t', after: '[\\r\\n]', inConstruct: 'phrasing'}, - {character: '\t', before: '[\\r\\n]', inConstruct: 'phrasing'}, - { - character: '\t', - inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] - }, - { - character: '\r', - inConstruct: [ - 'codeFencedLangGraveAccent', - 'codeFencedLangTilde', - 'codeFencedMetaGraveAccent', - 'codeFencedMetaTilde', - 'destinationLiteral', - 'headingAtx' - ] - }, - { - character: '\n', - inConstruct: [ - 'codeFencedLangGraveAccent', - 'codeFencedLangTilde', - 'codeFencedMetaGraveAccent', - 'codeFencedMetaTilde', - 'destinationLiteral', - 'headingAtx' - ] - }, - {character: ' ', after: '[\\r\\n]', inConstruct: 'phrasing'}, - {character: ' ', before: '[\\r\\n]', inConstruct: 'phrasing'}, - { - character: ' ', - inConstruct: ['codeFencedLangGraveAccent', 'codeFencedLangTilde'] - }, - // An exclamation mark can start an image, if it is followed by a link or - // a link reference. - {character: '!', after: '\\[', inConstruct: 'phrasing'}, - // A quote can break out of a title. - {character: '"', inConstruct: 'titleQuote'}, - // A number sign could start an ATX heading if it starts a line. - {atBreak: true, character: '#'}, - {character: '#', inConstruct: 'headingAtx', after: '(?:[\r\n]|$)'}, - // Dollar sign and percentage are not used in markdown. - // An ampersand could start a character reference. - {character: '&', after: '[#A-Za-z]', inConstruct: 'phrasing'}, - // An apostrophe can break out of a title. - {character: "'", inConstruct: 'titleApostrophe'}, - // A left paren could break out of a destination raw. - {character: '(', inConstruct: 'destinationRaw'}, - {before: '\\]', character: '(', inConstruct: 'phrasing'}, - // A right paren could start a list item or break out of a destination - // raw. - {atBreak: true, before: '\\d+', character: ')'}, - {character: ')', inConstruct: 'destinationRaw'}, - // An asterisk can start thematic breaks, list items, emphasis, strong. - {atBreak: true, character: '*'}, - {character: '*', inConstruct: 'phrasing'}, - // A plus sign could start a list item. - {atBreak: true, character: '+'}, - // A dash can start thematic breaks, list items, and setext heading - // underlines. - {atBreak: true, character: '-'}, - // A dot could start a list item. - {atBreak: true, before: '\\d+', character: '.', after: '(?:[ \t\r\n]|$)'}, - // Slash, colon, and semicolon are not used in markdown for constructs. - // A less than can start html (flow or text) or an autolink. - // HTML could start with an exclamation mark (declaration, cdata, comment), - // slash (closing tag), question mark (instruction), or a letter (tag). - // An autolink also starts with a letter. - // Finally, it could break out of a destination literal. - {atBreak: true, character: '<', after: '[!/?A-Za-z]'}, - {character: '<', after: '[!/?A-Za-z]', inConstruct: 'phrasing'}, - {character: '<', inConstruct: 'destinationLiteral'}, - // An equals to can start setext heading underlines. - {atBreak: true, character: '='}, - // A greater than can start block quotes and it can break out of a - // destination literal. - {atBreak: true, character: '>'}, - {character: '>', inConstruct: 'destinationLiteral'}, - // Question mark and at sign are not used in markdown for constructs. - // A left bracket can start definitions, references, labels, - {atBreak: true, character: '['}, - {character: '[', inConstruct: ['phrasing', 'label', 'reference']}, - // A backslash can start an escape (when followed by punctuation) or a - // hard break (when followed by an eol). - // Note: typical escapes are handled in `safe`! - {character: '\\', after: '[\\r\\n]', inConstruct: 'phrasing'}, - // A right bracket can exit labels. - {character: ']', inConstruct: ['label', 'reference']}, - // Caret is not used in markdown for constructs. - // An underscore can start emphasis, strong, or a thematic break. - {atBreak: true, character: '_'}, - {before: '[^A-Za-z]', character: '_', inConstruct: 'phrasing'}, - {character: '_', after: '[^A-Za-z]', inConstruct: 'phrasing'}, - // A grave accent can start code (fenced or text), or it can break out of - // a grave accent code fence. - {atBreak: true, character: '`'}, - { - character: '`', - inConstruct: [ - 'codeFencedLangGraveAccent', - 'codeFencedMetaGraveAccent', - 'phrasing' - ] - }, - // Left brace, vertical bar, right brace are not used in markdown for - // constructs. - // A tilde can start code (fenced). - {atBreak: true, character: '~'} -]; - -/** - * @typedef {import('./types.js').Node} Node - * @typedef {import('./types.js').Options} Options - * @typedef {import('./types.js').Context} Context - * @typedef {import('./types.js').Handle} Handle - * @typedef {import('./types.js').Join} Join - * @typedef {import('./types.js').Unsafe} Unsafe - */ - -/** - * @param {Node} tree - * @param {Options} [options] - * @returns {string} - */ -function toMarkdown(tree, options = {}) { - /** @type {Context} */ - // @ts-expect-error: we’ll add `handle` later. - const context = { - enter, - stack: [], - unsafe: [], - join: [], - handlers: {}, - options: {}, - indexStack: [] - }; - - configure(context, {unsafe, join, handlers: handle}); - configure(context, options); - - if (context.options.tightDefinitions) { - configure(context, {join: [joinDefinition]}); - } - - /** @type {Handle} */ - context.handle = zwitch('type', { - invalid, - // @ts-expect-error: hush. - unknown, - // @ts-expect-error: hush. - handlers: context.handlers - }); - - let result = context.handle(tree, null, context, {before: '\n', after: '\n'}); - - if ( - result && - result.charCodeAt(result.length - 1) !== 10 && - result.charCodeAt(result.length - 1) !== 13 - ) { - result += '\n'; - } - - return result - - /** @type {Context['enter']} */ - function enter(name) { - context.stack.push(name); - return exit - - function exit() { - context.stack.pop(); - } - } -} - -/** - * @type {Handle} - * @param {unknown} value - */ -function invalid(value) { - throw new Error('Cannot handle value `' + value + '`, expected node') -} - -/** - * @type {Handle} - * @param {Node} node - */ -function unknown(node) { - throw new Error('Cannot handle unknown node `' + node.type + '`') -} - -/** @type {Join} */ -function joinDefinition(left, right) { - // No blank line between adjacent definitions. - if (left.type === 'definition' && left.type === right.type) { - return 0 - } -} - -/** - * @typedef {import('mdast').Root|import('mdast').Content} Node - * @typedef {import('mdast-util-to-markdown').Options} Options - */ - -/** @type {import('unified').Plugin<[Options]|void[], Node, string>} */ -function remarkStringify(options) { - /** @type {import('unified').CompilerFunction} */ - const compiler = (tree) => { - // Assume options. - const settings = /** @type {Options} */ (this.data('settings')); - - return toMarkdown( - tree, - Object.assign({}, settings, options, { - // Note: this option is not in the readme. - // The goal is for it to be set by plugins on `data` instead of being - // passed by users. - extensions: this.data('toMarkdownExtensions') || [] - }) - ) - }; - - Object.assign(this, {Compiler: compiler}); -} - -const remark = unified().use(remarkParse).use(remarkStringify).freeze(); - -const name$1 = "remark"; -const version$1 = "14.0.1"; -const description$1 = "Markdown processor powered by plugins part of the unified collective"; -const license = "MIT"; -const keywords = [ - "unified", - "remark", - "markdown", - "mdast", - "abstract", - "syntax", - "tree", - "ast", - "parse", - "stringify", - "serialize", - "compile", - "process" -]; -const homepage = "https://remark.js.org"; -const repository = "https://github.com/remarkjs/remark/tree/main/packages/remark"; -const bugs = "https://github.com/remarkjs/remark/issues"; -const funding = { - type: "opencollective", - url: "https://opencollective.com/unified" -}; -const author = "Titus Wormer (https://wooorm.com)"; -const contributors = [ - "Titus Wormer (https://wooorm.com)" -]; -const sideEffects = false; -const type = "module"; -const main$1 = "index.js"; -const types = "index.d.ts"; -const files = [ - "index.d.ts", - "index.js" -]; -const dependencies$1 = { - "@types/mdast": "^3.0.0", - "remark-parse": "^10.0.0", - "remark-stringify": "^10.0.0", - unified: "^10.0.0" -}; -const scripts$1 = { - test: "node --conditions development test.js", - build: "rimraf \"*.d.ts\" && tsc && type-coverage" -}; -const xo = false; -const typeCoverage = { - atLeast: 100, - detail: true, - strict: true, - ignoreCatch: true -}; -var proc = { - name: name$1, - version: version$1, - description: description$1, - license: license, - keywords: keywords, - homepage: homepage, - repository: repository, - bugs: bugs, - funding: funding, - author: author, - contributors: contributors, - sideEffects: sideEffects, - type: type, - main: main$1, - types: types, - files: files, - dependencies: dependencies$1, - scripts: scripts$1, - xo: xo, - typeCoverage: typeCoverage -}; - -const name = "node-lint-md-cli-rollup"; -const description = "remark packaged for Node.js Markdown linting"; -const version = "2.0.2"; -const devDependencies = { - "@rollup/plugin-commonjs": "^20.0.0", - "@rollup/plugin-json": "^4.1.0", - "@rollup/plugin-node-resolve": "^13.0.4", - rollup: "^2.56.3", - shx: "^0.3.3" -}; -const dependencies = { - "markdown-extensions": "^1.1.1", - remark: "^14.0.1", - "remark-gfm": "^2.0.0", - "remark-preset-lint-node": "^3.0.1", - "unified-args": "^9.0.2" -}; -const main = "dist/index.js"; -const scripts = { - build: "npx rollup -c", - "build-node": "npm run build && npx shx cp dist/index.mjs ../lint-md.mjs" -}; -var cli = { - name: name, - description: description, - version: version, - devDependencies: devDependencies, - dependencies: dependencies, - main: main, - scripts: scripts -}; - -/** - * @typedef {import('unist').Point} Point - * @typedef {import('vfile').VFile} VFile - * - * @typedef {Pick} PositionalPoint - * @typedef {Required} FullPoint - * @typedef {NonNullable} Offset - */ - -/** - * Get transform functions for the given `document`. - * - * @param {string|Uint8Array|VFile} file - */ -function location(file) { - var value = String(file); - /** @type {Array.} */ - var indices = []; - var search = /\r?\n|\r/g; - - while (search.test(value)) { - indices.push(search.lastIndex); - } - - indices.push(value.length + 1); - - return {toPoint, toOffset} - - /** - * Get the line and column-based `point` for `offset` in the bound indices. - * Returns a point with `undefined` values when given invalid or out of bounds - * input. - * - * @param {Offset} offset - * @returns {FullPoint} - */ - function toPoint(offset) { - var index = -1; - - if (offset > -1 && offset < indices[indices.length - 1]) { - while (++index < indices.length) { - if (indices[index] > offset) { - return { - line: index + 1, - column: offset - (indices[index - 1] || 0) + 1, - offset - } - } - } - } - - return {line: undefined, column: undefined, offset: undefined} - } - - /** - * Get the `offset` for a line and column-based `point` in the bound indices. - * Returns `-1` when given invalid or out of bounds input. - * - * @param {PositionalPoint} point - * @returns {Offset} - */ - function toOffset(point) { - var line = point && point.line; - var column = point && point.column; - /** @type {number} */ - var offset; - - if ( - typeof line === 'number' && - typeof column === 'number' && - !Number.isNaN(line) && - !Number.isNaN(column) && - line - 1 in indices - ) { - offset = (indices[line - 2] || 0) + column - 1 || 0; - } - - return offset > -1 && offset < indices[indices.length - 1] ? offset : -1 - } -} - -/** - * @param {string} d - * @returns {string} - */ -function color(d) { - return '\u001B[33m' + d + '\u001B[39m' -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - */ - -/** - * Continue traversing as normal - */ -const CONTINUE = true; -/** - * Do not traverse this node’s children - */ -const SKIP = 'skip'; -/** - * Stop traversing immediately - */ -const EXIT = false; - -const visitParents = - /** - * @type {( - * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) - * )} - */ - ( - /** - * Visit children of tree which pass a test - * - * @param {Node} tree Abstract syntax tree to walk - * @param {Test} test test Test node - * @param {Visitor} visitor Function to run for each node - * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - // @ts-ignore no visitor given, so `visitor` is test. - visitor = test; - test = null; - } - - var is = convert(test); - var step = reverse ? -1 : 1; - - factory(tree, null, [])(); - - /** - * @param {Node} node - * @param {number?} index - * @param {Array.} parents - */ - function factory(node, index, parents) { - /** @type {Object.} */ - var value = typeof node === 'object' && node !== null ? node : {}; - /** @type {string} */ - var name; - - if (typeof value.type === 'string') { - name = - typeof value.tagName === 'string' - ? value.tagName - : typeof value.name === 'string' - ? value.name - : undefined; - - Object.defineProperty(visit, 'name', { - value: - 'node (' + - color(value.type + (name ? '<' + name + '>' : '')) + - ')' - }); - } - - return visit - - function visit() { - /** @type {ActionTuple} */ - var result = []; - /** @type {ActionTuple} */ - var subresult; - /** @type {number} */ - var offset; - /** @type {Array.} */ - var grandparents; - - if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult(visitor(node, parents)); - - if (result[0] === EXIT) { - return result - } - } - - if (node.children && result[0] !== SKIP) { - // @ts-ignore looks like a parent. - offset = (reverse ? node.children.length : -1) + step; - // @ts-ignore looks like a parent. - grandparents = parents.concat(node); - - // @ts-ignore looks like a parent. - while (offset > -1 && offset < node.children.length) { - subresult = factory(node.children[offset], offset, grandparents)(); - - if (subresult[0] === EXIT) { - return subresult - } - - offset = - typeof subresult[1] === 'number' ? subresult[1] : offset + step; - } - } - - return result - } - } - } - ); - -/** - * @param {VisitorResult} value - * @returns {ActionTuple} - */ -function toResult(value) { - if (Array.isArray(value)) { - return value - } - - if (typeof value === 'number') { - return [CONTINUE, value] - } - - return [value] -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist-util-is').Test} Test - * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult - */ - -const visit = - /** - * @type {( - * ((tree: Node, test: T['type']|Partial|import('unist-util-is').TestFunctionPredicate|Array.|import('unist-util-is').TestFunctionPredicate>, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, test: Test, visitor: Visitor, reverse?: boolean) => void) & - * ((tree: Node, visitor: Visitor, reverse?: boolean) => void) - * )} - */ - ( - /** - * Visit children of tree which pass a test - * - * @param {Node} tree Abstract syntax tree to walk - * @param {Test} test test Test node - * @param {Visitor} visitor Function to run for each node - * @param {boolean} [reverse] Fisit the tree in reverse, defaults to false - */ - function (tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } - - visitParents(tree, test, overload, reverse); - - /** - * @param {Node} node - * @param {Array.} parents - */ - function overload(node, parents) { - var parent = parents[parents.length - 1]; - return visitor( - node, - parent ? parent.children.indexOf(node) : null, - parent - ) - } - } - ); - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('unist').Parent} Parent - * @typedef {import('unist').Point} Point - * @typedef {import('unist-util-is').Test} Test - * @typedef {import('vfile').VFile} VFile - * @typedef {import('vfile-message').VFileMessage} VFileMessage - * - * @typedef {OptionsWithoutReset|OptionsWithReset} Options - * @typedef {OptionsBaseFields & OptionsWithoutResetFields} OptionsWithoutReset - * @typedef {OptionsBaseFields & OptionsWithResetFields} OptionsWithReset - * - * @typedef OptionsWithoutResetFields - * @property {false} [reset] - * Whether to treat all messages as turned off initially. - * @property {string[]} [disable] - * List of `ruleId`s to turn off. - * - * @typedef OptionsWithResetFields - * @property {true} reset - * Whether to treat all messages as turned off initially. - * @property {string[]} [enable] - * List of `ruleId`s to initially turn on. - * - * @typedef OptionsBaseFields - * @property {string} name - * Name of markers that can control the message sources. - * - * For example, `{name: 'alpha'}` controls `alpha` markers: - * - * ```html - * - * ``` - * @property {MarkerParser} marker - * Parse a possible marker to a comment marker object (Marker). - * If the marker isn't a marker, should return `null`. - * @property {Test} [test] - * Test for possible markers - * @property {string[]} [known] - * List of allowed `ruleId`s. When given a warning is shown - * when someone tries to control an unknown rule. - * - * For example, `{name: 'alpha', known: ['bravo']}` results in a warning if - * `charlie` is configured: - * - * ```html - * - * ``` - * @property {string|string[]} [source] - * Sources that can be controlled with `name` markers. - * Defaults to `name`. - * - * @callback MarkerParser - * Parse a possible comment marker node to a Marker. - * @param {Node} node - * Node to parse - * - * @typedef Marker - * A comment marker. - * @property {string} name - * Name of marker. - * @property {string} attributes - * Value after name. - * @property {Record} parameters - * Parsed attributes. - * @property {Node} node - * Reference to given node. - * - * @typedef Mark - * @property {Point|undefined} point - * @property {boolean} state - */ - -const own$2 = {}.hasOwnProperty; - -/** - * @type {import('unified').Plugin<[Options]>} - * @returns {(tree: Node, file: VFile) => void} - */ -function messageControl(options) { - if (!options || typeof options !== 'object' || !options.name) { - throw new Error( - 'Expected `name` in `options`, got `' + (options || {}).name + '`' - ) - } - - if (!options.marker) { - throw new Error( - 'Expected `marker` in `options`, got `' + options.marker + '`' - ) - } - - const enable = 'enable' in options && options.enable ? options.enable : []; - const disable = 'disable' in options && options.disable ? options.disable : []; - let reset = options.reset; - const sources = - typeof options.source === 'string' - ? [options.source] - : options.source || [options.name]; - - return transformer - - /** - * @param {Node} tree - * @param {VFile} file - */ - function transformer(tree, file) { - const toOffset = location(file).toOffset; - const initial = !reset; - const gaps = detectGaps(tree, file); - /** @type {Record} */ - const scope = {}; - /** @type {Mark[]} */ - const globals = []; - - visit(tree, options.test, visitor); - - file.messages = file.messages.filter((m) => filter(m)); - - /** - * @param {Node} node - * @param {number|null} position - * @param {Parent|null} parent - */ - function visitor(node, position, parent) { - /** @type {Marker|null} */ - const mark = options.marker(node); - - if (!mark || mark.name !== options.name) { - return - } - - const ruleIds = mark.attributes.split(/\s/g); - const point = mark.node.position && mark.node.position.start; - const next = - (parent && position !== null && parent.children[position + 1]) || - undefined; - const tail = (next && next.position && next.position.end) || undefined; - let index = -1; - - /** @type {string} */ - // @ts-expect-error: we’ll check for unknown values next. - const verb = ruleIds.shift(); - - if (verb !== 'enable' && verb !== 'disable' && verb !== 'ignore') { - file.fail( - 'Unknown keyword `' + - verb + - '`: expected ' + - "`'enable'`, `'disable'`, or `'ignore'`", - mark.node - ); - } - - // Apply to all rules. - if (ruleIds.length > 0) { - while (++index < ruleIds.length) { - const ruleId = ruleIds[index]; - - if (isKnown(ruleId, verb, mark.node)) { - toggle(point, verb === 'enable', ruleId); - - if (verb === 'ignore') { - toggle(tail, true, ruleId); - } - } - } - } else if (verb === 'ignore') { - toggle(point, false); - toggle(tail, true); - } else { - toggle(point, verb === 'enable'); - reset = verb !== 'enable'; - } - } - - /** - * @param {VFileMessage} message - * @returns {boolean} - */ - function filter(message) { - let gapIndex = gaps.length; - - // Keep messages from a different source. - if (!message.source || !sources.includes(message.source)) { - return true - } - - // We only ignore messages if they‘re disabled, *not* when they’re not in - // the document. - if (!message.line) { - message.line = 1; - } - - if (!message.column) { - message.column = 1; - } - - // Check whether the warning is inside a gap. - // @ts-expect-error: we just normalized `null` to `number`s. - const offset = toOffset(message); - - while (gapIndex--) { - if (gaps[gapIndex][0] <= offset && gaps[gapIndex][1] > offset) { - return false - } - } - - // Check whether allowed by specific and global states. - return ( - (!message.ruleId || - check(message, scope[message.ruleId], message.ruleId)) && - check(message, globals) - ) - } - - /** - * Helper to check (and possibly warn) if a `ruleId` is unknown. - * - * @param {string} ruleId - * @param {string} verb - * @param {Node} node - * @returns {boolean} - */ - function isKnown(ruleId, verb, node) { - const result = options.known ? options.known.includes(ruleId) : true; - - if (!result) { - file.message( - 'Unknown rule: cannot ' + verb + " `'" + ruleId + "'`", - node - ); - } - - return result - } - - /** - * Get the latest state of a rule. - * When without `ruleId`, gets global state. - * - * @param {string|undefined} ruleId - * @returns {boolean} - */ - function getState(ruleId) { - const ranges = ruleId ? scope[ruleId] : globals; - - if (ranges && ranges.length > 0) { - return ranges[ranges.length - 1].state - } - - if (!ruleId) { - return !reset - } - - return reset ? enable.includes(ruleId) : !disable.includes(ruleId) - } - - /** - * Handle a rule. - * - * @param {Point|undefined} point - * @param {boolean} state - * @param {string|undefined} [ruleId] - * @returns {void} - */ - function toggle(point, state, ruleId) { - let markers = ruleId ? scope[ruleId] : globals; - - if (!markers) { - markers = []; - scope[String(ruleId)] = markers; - } - - const previousState = getState(ruleId); - - if (state !== previousState) { - markers.push({state, point}); - } - - // Toggle all known rules. - if (!ruleId) { - for (ruleId in scope) { - if (own$2.call(scope, ruleId)) { - toggle(point, state, ruleId); - } - } - } - } - - /** - * Check all `ranges` for `message`. - * - * @param {VFileMessage} message - * @param {Mark[]|undefined} ranges - * @param {string|undefined} [ruleId] - * @returns {boolean} - */ - function check(message, ranges, ruleId) { - if (ranges && ranges.length > 0) { - // Check the state at the message’s position. - let index = ranges.length; - - while (index--) { - const range = ranges[index]; - - if ( - message.line && - message.column && - range.point && - range.point.line && - range.point.column && - (range.point.line < message.line || - (range.point.line === message.line && - range.point.column <= message.column)) - ) { - return range.state === true - } - } - } - - // The first marker ocurred after the first message, so we check the - // initial state. - if (!ruleId) { - return Boolean(initial || reset) - } - - return reset ? enable.includes(ruleId) : !disable.includes(ruleId) - } - } -} - -/** - * Detect gaps in `tree`. - * - * @param {Node} tree - * @param {VFile} file - */ -function detectGaps(tree, file) { - /** @type {Node[]} */ - // @ts-expect-error: fine. - const children = tree.children || []; - const lastNode = children[children.length - 1]; - /** @type {[number, number][]} */ - const gaps = []; - let offset = 0; - /** @type {boolean|undefined} */ - let gap; - - // Find all gaps. - visit(tree, one); - - // Get the end of the document. - // This detects if the last node was the last node. - // If not, there’s an extra gap between the last node and the end of the - // document. - if ( - lastNode && - lastNode.position && - lastNode.position.end && - offset === lastNode.position.end.offset && - file.toString().slice(offset).trim() !== '' - ) { - update(); - - update( - tree && - tree.position && - tree.position.end && - tree.position.end.offset && - tree.position.end.offset - 1 - ); - } - - return gaps - - /** - * @param {Node} node - */ - function one(node) { - update(node.position && node.position.start && node.position.start.offset); - - if (!('children' in node)) { - update(node.position && node.position.end && node.position.end.offset); - } - } - - /** - * Detect a new position. - * - * @param {number|undefined} [latest] - * @returns {void} - */ - function update(latest) { - if (latest === null || latest === undefined) { - gap = true; - } else if (offset < latest) { - if (gap) { - gaps.push([offset, latest]); - gap = undefined; - } - - offset = latest; - } - } -} - -/** - * @typedef {string|number|boolean} MarkerParameterValue - * @typedef {Object.} MarkerParameters - * - * @typedef HtmlNode - * @property {'html'} type - * @property {string} value - * - * @typedef CommentNode - * @property {'comment'} type - * @property {string} value - * - * @typedef Marker - * @property {string} name - * @property {string} attributes - * @property {MarkerParameters|null} parameters - * @property {HtmlNode|CommentNode} node - */ - -var commentExpression = /\s*([a-zA-Z\d-]+)(\s+([\s\S]*))?\s*/; - -var markerExpression = new RegExp( - '(\\s*\\s*)' -); - -/** - * Parse a comment marker. - * @param {unknown} node - * @returns {Marker|null} - */ -function commentMarker(node) { - /** @type {RegExpMatchArray} */ - var match; - /** @type {number} */ - var offset; - /** @type {MarkerParameters} */ - var parameters; - - if ( - node && - typeof node === 'object' && - // @ts-ignore hush - (node.type === 'html' || node.type === 'comment') - ) { - // @ts-ignore hush - match = node.value.match( - // @ts-ignore hush - node.type === 'comment' ? commentExpression : markerExpression - ); - - // @ts-ignore hush - if (match && match[0].length === node.value.length) { - // @ts-ignore hush - offset = node.type === 'comment' ? 1 : 2; - parameters = parseParameters(match[offset + 1] || ''); - - if (parameters) { - return { - name: match[offset], - attributes: match[offset + 2] || '', - parameters, - // @ts-ignore hush - node - } - } - } - } - - return null -} - -/** - * Parse `value` into an object. - * - * @param {string} value - * @returns {MarkerParameters|null} - */ -function parseParameters(value) { - /** @type {MarkerParameters} */ - var parameters = {}; - - return value - .replace( - /\s+([-\w]+)(?:=(?:"((?:\\[\s\S]|[^"])+)"|'((?:\\[\s\S]|[^'])+)'|((?:\\[\s\S]|[^"'\s])+)))?/gi, - replacer - ) - .replace(/\s+/g, '') - ? null - : parameters - - /** - * @param {string} _ - * @param {string} $1 - * @param {string} $2 - * @param {string} $3 - * @param {string} $4 - */ - // eslint-disable-next-line max-params - function replacer(_, $1, $2, $3, $4) { - /** @type {MarkerParameterValue} */ - var value = $2 || $3 || $4 || ''; - - if (value === 'true' || value === '') { - value = true; - } else if (value === 'false') { - value = false; - } else if (!Number.isNaN(Number(value))) { - value = Number(value); - } - - parameters[$1] = value; - - return '' - } -} - -/** - * @typedef {import('mdast').Root} Root - * @typedef {import('vfile').VFile} VFile - * @typedef {import('unified-message-control')} MessageControl - * @typedef {Omit|Omit} Options - */ - -const test = [ - 'html', // Comments are `html` nodes in mdast. - 'comment' // In MDX, comments have their own node. -]; - -/** - * Plugin to enable, disable, and ignore messages. - * - * @type {import('unified').Plugin<[Options], Root>} - * @returns {(node: Root, file: VFile) => void} - */ -function remarkMessageControl(options) { - return messageControl( - Object.assign({marker: commentMarker, test}, options) - ) -} - -/** - * @typedef {import('mdast').Root} Root - */ - -/** - * The core plugin for `remark-lint`. - * This adds support for ignoring stuff from messages (``). - * All rules are in their own packages and presets. - * - * @type {import('unified').Plugin} - */ -function remarkLint() { - this.use(lintMessageControl); -} - -/** @type {import('unified').Plugin} */ -function lintMessageControl() { - return remarkMessageControl({name: 'lint', source: 'remark-lint'}) -} - -/** - * @typedef {import('unist').Node} Node - * @typedef {import('vfile').VFile} VFile - * - * @typedef {0|1|2} Severity - * @typedef {'warn'|'on'|'off'|'error'} Label - * @typedef {[Severity, ...unknown[]]} SeverityTuple - * - * @callback Rule - * @param {Node} tree - * @param {VFile} file - * @param {unknown} options - * @returns {void} - */ - -const primitives = new Set(['string', 'number', 'boolean']); - -/** - * @param {string} id - * @param {Rule} rule - */ -function lintRule(id, rule) { - const parts = id.split(':'); - // Possibly useful if externalised later. - /* c8 ignore next */ - const source = parts[1] ? parts[0] : undefined; - const ruleId = parts[1]; - - Object.defineProperty(plugin, 'name', {value: id}); - - return plugin - - /** @type {import('unified').Plugin<[unknown]|void[]>} */ - function plugin(raw) { - const [severity, options] = coerce$1(ruleId, raw); - - if (!severity) return - - const fatal = severity === 2; - - return (tree, file, next) => { - let index = file.messages.length - 1; - - wrap(rule, (error) => { - const messages = file.messages; - - // Add the error, if not already properly added. - // Only happens for incorrect plugins. - /* c8 ignore next 6 */ - // @ts-expect-error: errors could be `messages`. - if (error && !messages.includes(error)) { - try { - file.fail(error); - } catch {} - } - - while (++index < messages.length) { - Object.assign(messages[index], {ruleId, source, fatal}); - } - - next(); - })(tree, file, options); - } - } -} - -/** - * Coerce a value to a severity--options tuple. - * - * @param {string} name - * @param {unknown} value - * @returns {SeverityTuple} - */ -function coerce$1(name, value) { - /** @type {unknown[]} */ - let result; - - if (typeof value === 'boolean') { - result = [value]; - } else if (value === null || value === undefined) { - result = [1]; - } else if ( - Array.isArray(value) && - // `isArray(unknown)` is turned into `any[]`: - // type-coverage:ignore-next-line - primitives.has(typeof value[0]) - ) { - // `isArray(unknown)` is turned into `any[]`: - // type-coverage:ignore-next-line - result = [...value]; - } else { - result = [1, value]; - } - - let level = result[0]; - - if (typeof level === 'boolean') { - level = level ? 1 : 0; - } else if (typeof level === 'string') { - if (level === 'off') { - level = 0; - } else if (level === 'on' || level === 'warn') { - level = 1; - } else if (level === 'error') { - level = 2; - } else { - level = 1; - result = [level, result]; - } - } - - if (typeof level !== 'number' || level < 0 || level > 2) { - throw new Error( - 'Incorrect severity `' + - level + - '` for `' + - name + - '`, ' + - 'expected 0, 1, or 2' - ) - } - - result[0] = level; - - // @ts-expect-error: it’s now a valid tuple. - return result -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module final-newline - * @fileoverview - * Warn when a line feed at the end of a file is missing. - * Empty files are allowed. - * - * See [StackExchange](https://unix.stackexchange.com/questions/18743) for why. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * always adds a final line feed to files. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * ## Example - * - * ##### `ok.md` - * - * ###### In - * - * Note: `␊` represents LF. - * - * ```markdown - * Alpha␊ - * ``` - * - * ###### Out - * - * No messages. - * - * ##### `not-ok.md` - * - * ###### In - * - * Note: The below file does not have a final newline. - * - * ```markdown - * Bravo - * ``` - * - * ###### Out - * - * ```text - * 1:1: Missing newline character at end of file - * ``` - */ - -const remarkLintFinalNewline = lintRule( - 'remark-lint:final-newline', - /** @type {import('unified-lint-rule').Rule} */ - (_, file) => { - const value = String(file); - const last = value.length - 1; - - if (last > -1 && value.charAt(last) !== '\n') { - file.message('Missing newline character at end of file'); - } - } -); - -var remarkLintFinalNewline$1 = remarkLintFinalNewline; - -var pluralize = {exports: {}}; - -/* global define */ - -(function (module, exports) { -(function (root, pluralize) { - /* istanbul ignore else */ - if (typeof commonjsRequire === 'function' && 'object' === 'object' && 'object' === 'object') { - // Node. - module.exports = pluralize(); - } else { - // Browser global. - root.pluralize = pluralize(); - } -})(commonjsGlobal, function () { - // Rule storage - pluralize and singularize need to be run sequentially, - // while other rules can be optimized using an object for instant lookups. - var pluralRules = []; - var singularRules = []; - var uncountables = {}; - var irregularPlurals = {}; - var irregularSingles = {}; - - /** - * Sanitize a pluralization rule to a usable regular expression. - * - * @param {(RegExp|string)} rule - * @return {RegExp} - */ - function sanitizeRule (rule) { - if (typeof rule === 'string') { - return new RegExp('^' + rule + '$', 'i'); - } - - return rule; - } - - /** - * Pass in a word token to produce a function that can replicate the case on - * another word. - * - * @param {string} word - * @param {string} token - * @return {Function} - */ - function restoreCase (word, token) { - // Tokens are an exact match. - if (word === token) return token; - - // Lower cased words. E.g. "hello". - if (word === word.toLowerCase()) return token.toLowerCase(); - - // Upper cased words. E.g. "WHISKY". - if (word === word.toUpperCase()) return token.toUpperCase(); - - // Title cased words. E.g. "Title". - if (word[0] === word[0].toUpperCase()) { - return token.charAt(0).toUpperCase() + token.substr(1).toLowerCase(); - } - - // Lower cased words. E.g. "test". - return token.toLowerCase(); - } - - /** - * Interpolate a regexp string. - * - * @param {string} str - * @param {Array} args - * @return {string} - */ - function interpolate (str, args) { - return str.replace(/\$(\d{1,2})/g, function (match, index) { - return args[index] || ''; - }); - } - - /** - * Replace a word using a rule. - * - * @param {string} word - * @param {Array} rule - * @return {string} - */ - function replace (word, rule) { - return word.replace(rule[0], function (match, index) { - var result = interpolate(rule[1], arguments); - - if (match === '') { - return restoreCase(word[index - 1], result); - } - - return restoreCase(match, result); - }); - } - - /** - * Sanitize a word by passing in the word and sanitization rules. - * - * @param {string} token - * @param {string} word - * @param {Array} rules - * @return {string} - */ - function sanitizeWord (token, word, rules) { - // Empty string or doesn't need fixing. - if (!token.length || uncountables.hasOwnProperty(token)) { - return word; - } - - var len = rules.length; - - // Iterate over the sanitization rules and use the first one to match. - while (len--) { - var rule = rules[len]; - - if (rule[0].test(word)) return replace(word, rule); - } - - return word; - } - - /** - * Replace a word with the updated word. - * - * @param {Object} replaceMap - * @param {Object} keepMap - * @param {Array} rules - * @return {Function} - */ - function replaceWord (replaceMap, keepMap, rules) { - return function (word) { - // Get the correct token and case restoration functions. - var token = word.toLowerCase(); - - // Check against the keep object map. - if (keepMap.hasOwnProperty(token)) { - return restoreCase(word, token); - } - - // Check against the replacement map for a direct word replacement. - if (replaceMap.hasOwnProperty(token)) { - return restoreCase(word, replaceMap[token]); - } - - // Run all the rules against the word. - return sanitizeWord(token, word, rules); - }; - } - - /** - * Check if a word is part of the map. - */ - function checkWord (replaceMap, keepMap, rules, bool) { - return function (word) { - var token = word.toLowerCase(); - - if (keepMap.hasOwnProperty(token)) return true; - if (replaceMap.hasOwnProperty(token)) return false; - - return sanitizeWord(token, token, rules) === token; - }; - } - - /** - * Pluralize or singularize a word based on the passed in count. - * - * @param {string} word The word to pluralize - * @param {number} count How many of the word exist - * @param {boolean} inclusive Whether to prefix with the number (e.g. 3 ducks) - * @return {string} - */ - function pluralize (word, count, inclusive) { - var pluralized = count === 1 - ? pluralize.singular(word) : pluralize.plural(word); - - return (inclusive ? count + ' ' : '') + pluralized; - } - - /** - * Pluralize a word. - * - * @type {Function} - */ - pluralize.plural = replaceWord( - irregularSingles, irregularPlurals, pluralRules - ); - - /** - * Check if a word is plural. - * - * @type {Function} - */ - pluralize.isPlural = checkWord( - irregularSingles, irregularPlurals, pluralRules - ); - - /** - * Singularize a word. - * - * @type {Function} - */ - pluralize.singular = replaceWord( - irregularPlurals, irregularSingles, singularRules - ); - - /** - * Check if a word is singular. - * - * @type {Function} - */ - pluralize.isSingular = checkWord( - irregularPlurals, irregularSingles, singularRules - ); - - /** - * Add a pluralization rule to the collection. - * - * @param {(string|RegExp)} rule - * @param {string} replacement - */ - pluralize.addPluralRule = function (rule, replacement) { - pluralRules.push([sanitizeRule(rule), replacement]); - }; - - /** - * Add a singularization rule to the collection. - * - * @param {(string|RegExp)} rule - * @param {string} replacement - */ - pluralize.addSingularRule = function (rule, replacement) { - singularRules.push([sanitizeRule(rule), replacement]); - }; - - /** - * Add an uncountable word rule. - * - * @param {(string|RegExp)} word - */ - pluralize.addUncountableRule = function (word) { - if (typeof word === 'string') { - uncountables[word.toLowerCase()] = true; - return; - } - - // Set singular and plural references for the word. - pluralize.addPluralRule(word, '$0'); - pluralize.addSingularRule(word, '$0'); - }; - - /** - * Add an irregular word definition. - * - * @param {string} single - * @param {string} plural - */ - pluralize.addIrregularRule = function (single, plural) { - plural = plural.toLowerCase(); - single = single.toLowerCase(); - - irregularSingles[single] = plural; - irregularPlurals[plural] = single; - }; - - /** - * Irregular rules. - */ - [ - // Pronouns. - ['I', 'we'], - ['me', 'us'], - ['he', 'they'], - ['she', 'they'], - ['them', 'them'], - ['myself', 'ourselves'], - ['yourself', 'yourselves'], - ['itself', 'themselves'], - ['herself', 'themselves'], - ['himself', 'themselves'], - ['themself', 'themselves'], - ['is', 'are'], - ['was', 'were'], - ['has', 'have'], - ['this', 'these'], - ['that', 'those'], - // Words ending in with a consonant and `o`. - ['echo', 'echoes'], - ['dingo', 'dingoes'], - ['volcano', 'volcanoes'], - ['tornado', 'tornadoes'], - ['torpedo', 'torpedoes'], - // Ends with `us`. - ['genus', 'genera'], - ['viscus', 'viscera'], - // Ends with `ma`. - ['stigma', 'stigmata'], - ['stoma', 'stomata'], - ['dogma', 'dogmata'], - ['lemma', 'lemmata'], - ['schema', 'schemata'], - ['anathema', 'anathemata'], - // Other irregular rules. - ['ox', 'oxen'], - ['axe', 'axes'], - ['die', 'dice'], - ['yes', 'yeses'], - ['foot', 'feet'], - ['eave', 'eaves'], - ['goose', 'geese'], - ['tooth', 'teeth'], - ['quiz', 'quizzes'], - ['human', 'humans'], - ['proof', 'proofs'], - ['carve', 'carves'], - ['valve', 'valves'], - ['looey', 'looies'], - ['thief', 'thieves'], - ['groove', 'grooves'], - ['pickaxe', 'pickaxes'], - ['passerby', 'passersby'] - ].forEach(function (rule) { - return pluralize.addIrregularRule(rule[0], rule[1]); - }); - - /** - * Pluralization rules. - */ - [ - [/s?$/i, 's'], - [/[^\u0000-\u007F]$/i, '$0'], - [/([^aeiou]ese)$/i, '$1'], - [/(ax|test)is$/i, '$1es'], - [/(alias|[^aou]us|t[lm]as|gas|ris)$/i, '$1es'], - [/(e[mn]u)s?$/i, '$1s'], - [/([^l]ias|[aeiou]las|[ejzr]as|[iu]am)$/i, '$1'], - [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1i'], - [/(alumn|alg|vertebr)(?:a|ae)$/i, '$1ae'], - [/(seraph|cherub)(?:im)?$/i, '$1im'], - [/(her|at|gr)o$/i, '$1oes'], - [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor)(?:a|um)$/i, '$1a'], - [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)(?:a|on)$/i, '$1a'], - [/sis$/i, 'ses'], - [/(?:(kni|wi|li)fe|(ar|l|ea|eo|oa|hoo)f)$/i, '$1$2ves'], - [/([^aeiouy]|qu)y$/i, '$1ies'], - [/([^ch][ieo][ln])ey$/i, '$1ies'], - [/(x|ch|ss|sh|zz)$/i, '$1es'], - [/(matr|cod|mur|sil|vert|ind|append)(?:ix|ex)$/i, '$1ices'], - [/\b((?:tit)?m|l)(?:ice|ouse)$/i, '$1ice'], - [/(pe)(?:rson|ople)$/i, '$1ople'], - [/(child)(?:ren)?$/i, '$1ren'], - [/eaux$/i, '$0'], - [/m[ae]n$/i, 'men'], - ['thou', 'you'] - ].forEach(function (rule) { - return pluralize.addPluralRule(rule[0], rule[1]); - }); - - /** - * Singularization rules. - */ - [ - [/s$/i, ''], - [/(ss)$/i, '$1'], - [/(wi|kni|(?:after|half|high|low|mid|non|night|[^\w]|^)li)ves$/i, '$1fe'], - [/(ar|(?:wo|[ae])l|[eo][ao])ves$/i, '$1f'], - [/ies$/i, 'y'], - [/\b([pl]|zomb|(?:neck|cross)?t|coll|faer|food|gen|goon|group|lass|talk|goal|cut)ies$/i, '$1ie'], - [/\b(mon|smil)ies$/i, '$1ey'], - [/\b((?:tit)?m|l)ice$/i, '$1ouse'], - [/(seraph|cherub)im$/i, '$1'], - [/(x|ch|ss|sh|zz|tto|go|cho|alias|[^aou]us|t[lm]as|gas|(?:her|at|gr)o|[aeiou]ris)(?:es)?$/i, '$1'], - [/(analy|diagno|parenthe|progno|synop|the|empha|cri|ne)(?:sis|ses)$/i, '$1sis'], - [/(movie|twelve|abuse|e[mn]u)s$/i, '$1'], - [/(test)(?:is|es)$/i, '$1is'], - [/(alumn|syllab|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat)(?:us|i)$/i, '$1us'], - [/(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|quor)a$/i, '$1um'], - [/(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat)a$/i, '$1on'], - [/(alumn|alg|vertebr)ae$/i, '$1a'], - [/(cod|mur|sil|vert|ind)ices$/i, '$1ex'], - [/(matr|append)ices$/i, '$1ix'], - [/(pe)(rson|ople)$/i, '$1rson'], - [/(child)ren$/i, '$1'], - [/(eau)x?$/i, '$1'], - [/men$/i, 'man'] - ].forEach(function (rule) { - return pluralize.addSingularRule(rule[0], rule[1]); - }); - - /** - * Uncountable rules. - */ - [ - // Singular words with no plurals. - 'adulthood', - 'advice', - 'agenda', - 'aid', - 'aircraft', - 'alcohol', - 'ammo', - 'analytics', - 'anime', - 'athletics', - 'audio', - 'bison', - 'blood', - 'bream', - 'buffalo', - 'butter', - 'carp', - 'cash', - 'chassis', - 'chess', - 'clothing', - 'cod', - 'commerce', - 'cooperation', - 'corps', - 'debris', - 'diabetes', - 'digestion', - 'elk', - 'energy', - 'equipment', - 'excretion', - 'expertise', - 'firmware', - 'flounder', - 'fun', - 'gallows', - 'garbage', - 'graffiti', - 'hardware', - 'headquarters', - 'health', - 'herpes', - 'highjinks', - 'homework', - 'housework', - 'information', - 'jeans', - 'justice', - 'kudos', - 'labour', - 'literature', - 'machinery', - 'mackerel', - 'mail', - 'media', - 'mews', - 'moose', - 'music', - 'mud', - 'manga', - 'news', - 'only', - 'personnel', - 'pike', - 'plankton', - 'pliers', - 'police', - 'pollution', - 'premises', - 'rain', - 'research', - 'rice', - 'salmon', - 'scissors', - 'series', - 'sewage', - 'shambles', - 'shrimp', - 'software', - 'species', - 'staff', - 'swine', - 'tennis', - 'traffic', - 'transportation', - 'trout', - 'tuna', - 'wealth', - 'welfare', - 'whiting', - 'wildebeest', - 'wildlife', - 'you', - /pok[eé]mon$/i, - // Regexes. - /[^aeiou]ese$/i, // "chinese", "japanese" - /deer$/i, // "deer", "reindeer" - /fish$/i, // "fish", "blowfish", "angelfish" - /measles$/i, - /o[iu]s$/i, // "carnivorous" - /pox$/i, // "chickpox", "smallpox" - /sheep$/i - ].forEach(pluralize.addUncountableRule); - - return pluralize; -}); -}(pluralize)); - -var plural = pluralize.exports; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module list-item-bullet-indent - * @fileoverview - * Warn when list item bullets are indented. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * removes all indentation before bullets. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * Paragraph. - * - * * List item - * * List item - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Paragraph. - * - * ·* List item - * ·* List item - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:2: Incorrect indentation before bullet: remove 1 space - * 4:2: Incorrect indentation before bullet: remove 1 space - */ - -const remarkLintListItemBulletIndent = lintRule( - 'remark-lint:list-item-bullet-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'list', (list, _, grandparent) => { - let index = -1; - - while (++index < list.children.length) { - const item = list.children[index]; - - if ( - grandparent && - grandparent.type === 'root' && - grandparent.position && - typeof grandparent.position.start.column === 'number' && - item.position && - typeof item.position.start.column === 'number' - ) { - const indent = - item.position.start.column - grandparent.position.start.column; - - if (indent) { - file.message( - 'Incorrect indentation before bullet: remove ' + - indent + - ' ' + - plural('space', indent), - item.position.start - ); - } - } - } - }); - } -); - -var remarkLintListItemBulletIndent$1 = remarkLintListItemBulletIndent; - -/** - * @typedef {import('unist').Position} Position - * @typedef {import('unist').Point} Point - * - * @typedef {Partial} PointLike - * - * @typedef {Object} PositionLike - * @property {PointLike} [start] - * @property {PointLike} [end] - * - * @typedef {Object} NodeLike - * @property {PositionLike} [position] - */ - -var pointStart = point('start'); -var pointEnd = point('end'); - -/** - * Get the positional info of `node`. - * - * @param {'start'|'end'} type - */ -function point(type) { - return point - - /** - * Get the positional info of `node`. - * - * @param {NodeLike} [node] - * @returns {Point} - */ - function point(node) { - /** @type {Point} */ - // @ts-ignore looks like a point - var point = (node && node.position && node.position[type]) || {}; - - return { - line: point.line || null, - column: point.column || null, - offset: point.offset > -1 ? point.offset : null - } - } -} - -/** - * @typedef {Object} PointLike - * @property {number} [line] - * @property {number} [column] - * @property {number} [offset] - * - * @typedef {Object} PositionLike - * @property {PointLike} [start] - * @property {PointLike} [end] - * - * @typedef {Object} NodeLike - * @property {PositionLike} [position] - */ - -/** - * Check if `node` is *generated*. - * - * @param {NodeLike} [node] - * @returns {boolean} - */ -function generated(node) { - return ( - !node || - !node.position || - !node.position.start || - !node.position.start.line || - !node.position.start.column || - !node.position.end || - !node.position.end.line || - !node.position.end.column - ) -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module list-item-indent - * @fileoverview - * Warn when the spacing between a list item’s bullet and its content violates - * a given style. - * - * Options: `'tab-size'`, `'mixed'`, or `'space'`, default: `'tab-size'`. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * uses `'tab-size'` (named `'tab'` there) by default to ensure Markdown is - * seen the same way across vendors. - * This can be configured with the - * [`listItemIndent`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionslistitemindent) - * option. - * This rule’s `'space'` option is named `'1'` there. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * *···List - * ····item. - * - * Paragraph. - * - * 11.·List - * ····item. - * - * Paragraph. - * - * *···List - * ····item. - * - * *···List - * ····item. - * - * @example - * {"name": "ok.md", "setting": "mixed"} - * - * *·List item. - * - * Paragraph. - * - * 11.·List item - * - * Paragraph. - * - * *···List - * ····item. - * - * *···List - * ····item. - * - * @example - * {"name": "ok.md", "setting": "space"} - * - * *·List item. - * - * Paragraph. - * - * 11.·List item - * - * Paragraph. - * - * *·List - * ··item. - * - * *·List - * ··item. - * - * @example - * {"name": "not-ok.md", "setting": "space", "label": "input"} - * - * *···List - * ····item. - * - * @example - * {"name": "not-ok.md", "setting": "space", "label": "output"} - * - * 1:5: Incorrect list-item indent: remove 2 spaces - * - * @example - * {"name": "not-ok.md", "setting": "tab-size", "label": "input"} - * - * *·List - * ··item. - * - * @example - * {"name": "not-ok.md", "setting": "tab-size", "label": "output"} - * - * 1:3: Incorrect list-item indent: add 2 spaces - * - * @example - * {"name": "not-ok.md", "setting": "mixed", "label": "input"} - * - * *···List item. - * - * @example - * {"name": "not-ok.md", "setting": "mixed", "label": "output"} - * - * 1:5: Incorrect list-item indent: remove 2 spaces - * - * @example - * {"name": "not-ok.md", "setting": "💩", "label": "output", "positionless": true} - * - * 1:1: Incorrect list-item indent style `💩`: use either `'tab-size'`, `'space'`, or `'mixed'` - */ - -const remarkLintListItemIndent = lintRule( - 'remark-lint:list-item-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'tab-size') => { - const value = String(file); - - if (option !== 'tab-size' && option !== 'space' && option !== 'mixed') { - file.fail( - 'Incorrect list-item indent style `' + - option + - "`: use either `'tab-size'`, `'space'`, or `'mixed'`" - ); - } - - visit$1(tree, 'list', (node) => { - if (generated(node)) return - - const spread = node.spread; - let index = -1; - - while (++index < node.children.length) { - const item = node.children[index]; - const head = item.children[0]; - const final = pointStart(head); - - const marker = value - .slice(pointStart(item).offset, final.offset) - .replace(/\[[x ]?]\s*$/i, ''); - - const bulletSize = marker.replace(/\s+$/, '').length; - - const style = - option === 'tab-size' || (option === 'mixed' && spread) - ? Math.ceil(bulletSize / 4) * 4 - : bulletSize + 1; - - if (marker.length !== style) { - const diff = style - marker.length; - const abs = Math.abs(diff); - - file.message( - 'Incorrect list-item indent: ' + - (diff > 0 ? 'add' : 'remove') + - ' ' + - abs + - ' ' + - plural('space', abs), - final - ); - } - } - }); - } -); - -var remarkLintListItemIndent$1 = remarkLintListItemIndent; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-auto-link-without-protocol - * @fileoverview - * Warn for autolinks without protocol. - * Autolinks are URLs enclosed in `<` (less than) and `>` (greater than) - * characters. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * adds a protocol where needed. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * - * - * - * Most Markdown vendors don’t recognize the following as a link: - * - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:14: All automatic links must start with a protocol - */ - -// Protocol expression. -// See: . -const protocol = /^[a-z][a-z+.-]+:\/?/i; - -const remarkLintNoAutoLinkWithoutProtocol = lintRule( - 'remark-lint:no-auto-link-without-protocol', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'link', (node) => { - if ( - !generated(node) && - pointStart(node).column === pointStart(node.children[0]).column - 1 && - pointEnd(node).column === - pointEnd(node.children[node.children.length - 1]).column + 1 && - !protocol.test(toString(node)) - ) { - file.message('All automatic links must start with a protocol', node); - } - }); - } -); - -var remarkLintNoAutoLinkWithoutProtocol$1 = remarkLintNoAutoLinkWithoutProtocol; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-blockquote-without-marker - * @fileoverview - * Warn when blank lines without `>` (greater than) markers are found in a - * block quote. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * adds markers to every line in a block quote. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * > Foo… - * > …bar… - * > …baz. - * - * @example - * {"name": "ok-tabs.md"} - * - * >»Foo… - * >»…bar… - * >»…baz. - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * > Foo… - * …bar… - * > …baz. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 2:1: Missing marker in block quote - * - * @example - * {"name": "not-ok-tabs.md", "label": "input"} - * - * >»Foo… - * »…bar… - * …baz. - * - * @example - * {"name": "not-ok-tabs.md", "label": "output"} - * - * 2:1: Missing marker in block quote - * 3:1: Missing marker in block quote - */ - -const remarkLintNoBlockquoteWithoutMarker = lintRule( - 'remark-lint:no-blockquote-without-marker', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - const loc = location(file); - - visit$1(tree, 'blockquote', (node) => { - let index = -1; - - while (++index < node.children.length) { - const child = node.children[index]; - - if (child.type === 'paragraph' && !generated(child)) { - const end = pointEnd(child).line; - const column = pointStart(child).column; - let line = pointStart(child).line; - - // Skip past the first line. - while (++line <= end) { - const offset = loc.toOffset({line, column}); - - if (/>[\t ]+$/.test(value.slice(offset - 5, offset))) { - continue - } - - // Roughly here. - file.message('Missing marker in block quote', { - line, - column: column - 2 - }); - } - } - } - }); - } -); - -var remarkLintNoBlockquoteWithoutMarker$1 = remarkLintNoBlockquoteWithoutMarker; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-literal-urls - * @fileoverview - * Warn for literal URLs in text. - * URLs are treated as links in some Markdown vendors, but not in others. - * To make sure they are always linked, wrap them in `<` (less than) and `>` - * (greater than). - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * never creates literal URLs and always uses `<` (less than) and `>` - * (greater than). - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * http://foo.bar/baz - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 1:1-1:19: Don’t use literal URLs without angle brackets - */ - -const remarkLintNoLiteralUrls = lintRule( - 'remark-lint:no-literal-urls', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'link', (node) => { - const value = toString(node); - - if ( - !generated(node) && - pointStart(node).column === pointStart(node.children[0]).column && - pointEnd(node).column === - pointEnd(node.children[node.children.length - 1]).column && - (node.url === 'mailto:' + value || node.url === value) - ) { - file.message('Don’t use literal URLs without angle brackets', node); - } - }); - } -); - -var remarkLintNoLiteralUrls$1 = remarkLintNoLiteralUrls; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module ordered-list-marker-style - * @fileoverview - * Warn when the list item marker style of ordered lists violate a given style. - * - * Options: `'consistent'`, `'.'`, or `')'`, default: `'consistent'`. - * - * `'consistent'` detects the first used list style and warns when subsequent - * lists use different styles. - * - * @example - * {"name": "ok.md"} - * - * 1. Foo - * - * - * 1. Bar - * - * Unordered lists are not affected by this rule. - * - * * Foo - * - * @example - * {"name": "ok.md", "setting": "."} - * - * 1. Foo - * - * 2. Bar - * - * @example - * {"name": "ok.md", "setting": ")"} - * - * 1) Foo - * - * 2) Bar - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * 1. Foo - * - * 2) Bar - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:1-3:8: Marker style should be `.` - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect ordered list item marker style `💩`: use either `'.'` or `')'` - */ - -const remarkLintOrderedListMarkerStyle = lintRule( - 'remark-lint:ordered-list-marker-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== 'consistent' && option !== '.' && option !== ')') { - file.fail( - 'Incorrect ordered list item marker style `' + - option + - "`: use either `'.'` or `')'`" - ); - } - - visit$1(tree, 'list', (node) => { - let index = -1; - - if (!node.ordered) return - - while (++index < node.children.length) { - const child = node.children[index]; - - if (!generated(child)) { - const marker = /** @type {Marker} */ ( - value - .slice( - pointStart(child).offset, - pointStart(child.children[0]).offset - ) - .replace(/\s|\d/g, '') - .replace(/\[[x ]?]\s*$/i, '') - ); - - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message('Marker style should be `' + option + '`', child); - } - } - } - }); - } -); - -var remarkLintOrderedListMarkerStyle$1 = remarkLintOrderedListMarkerStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module hard-break-spaces - * @fileoverview - * Warn when too many spaces are used to create a hard break. - * - * @example - * {"name": "ok.md"} - * - * Lorem ipsum·· - * dolor sit amet - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Lorem ipsum··· - * dolor sit amet. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:12-2:1: Use two spaces for hard line breaks - */ - -const remarkLintHardBreakSpaces = lintRule( - 'remark-lint:hard-break-spaces', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - - visit$1(tree, 'break', (node) => { - if (!generated(node)) { - const slice = value - .slice(pointStart(node).offset, pointEnd(node).offset) - .split('\n', 1)[0] - .replace(/\r$/, ''); - - if (slice.length > 2) { - file.message('Use two spaces for hard line breaks', node); - } - } - }); - } -); - -var remarkLintHardBreakSpaces$1 = remarkLintHardBreakSpaces; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-duplicate-definitions - * @fileoverview - * Warn when duplicate definitions are found. - * - * @example - * {"name": "ok.md"} - * - * [foo]: bar - * [baz]: qux - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [foo]: bar - * [foo]: qux - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 2:1-2:11: Do not use definitions with the same identifier (1:1) - */ - -const remarkLintNoDuplicateDefinitions = lintRule( - 'remark-lint:no-duplicate-definitions', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - /** @type {Record} */ - const map = Object.create(null); - - visit$1(tree, (node) => { - if ( - (node.type === 'definition' || node.type === 'footnoteDefinition') && - !generated(node) - ) { - const identifier = node.identifier; - const duplicate = map[identifier]; - - if (duplicate) { - file.message( - 'Do not use definitions with the same identifier (' + - duplicate + - ')', - node - ); - } - - map[identifier] = stringifyPosition$1(pointStart(node)); - } - }); - } -); - -var remarkLintNoDuplicateDefinitions$1 = remarkLintNoDuplicateDefinitions; - -/** - * @typedef {import('mdast').Heading} Heading - * @typedef {'atx'|'atx-closed'|'setext'} Style - */ - -/** - * @param {Heading} node - * @param {Style} [relative] - * @returns {Style|null} - */ -function headingStyle(node, relative) { - var last = node.children[node.children.length - 1]; - var depth = node.depth; - var pos = node && node.position && node.position.end; - var final = last && last.position && last.position.end; - - if (!pos) { - return null - } - - // This can only occur for `'atx'` and `'atx-closed'` headings. - // This might incorrectly match `'atx'` headings with lots of trailing white - // space as an `'atx-closed'` heading. - if (!last) { - if (pos.column - 1 <= depth * 2) { - return consolidate(depth, relative) - } - - return 'atx-closed' - } - - if (final.line + 1 === pos.line) { - return 'setext' - } - - if (final.column + depth < pos.column) { - return 'atx-closed' - } - - return consolidate(depth, relative) -} - -/** - * Get the probable style of an atx-heading, depending on preferred style. - * - * @param {number} depth - * @param {Style} relative - * @returns {Style|null} - */ -function consolidate(depth, relative) { - return depth < 3 - ? 'atx' - : relative === 'atx' || relative === 'setext' - ? relative - : null -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-heading-content-indent - * @fileoverview - * Warn when content of headings is indented. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * removes all unneeded padding around content in headings. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * #·Foo - * - * ## Bar·## - * - * ##·Baz - * - * Setext headings are not affected. - * - * Baz - * === - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * #··Foo - * - * ## Bar··## - * - * ##··Baz - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:4: Remove 1 space before this heading’s content - * 3:7: Remove 1 space after this heading’s content - * 5:7: Remove 1 space before this heading’s content - * - * @example - * {"name": "empty-heading.md"} - * - * #·· - */ - -const remarkLintNoHeadingContentIndent = lintRule( - 'remark-lint:no-heading-content-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'heading', (node) => { - if (generated(node)) { - return - } - - const type = headingStyle(node, 'atx'); - - if (type === 'atx' || type === 'atx-closed') { - const head = pointStart(node.children[0]).column; - - // Ignore empty headings. - if (!head) { - return - } - - const diff = head - pointStart(node).column - 1 - node.depth; - - if (diff) { - file.message( - 'Remove ' + - Math.abs(diff) + - ' ' + - plural('space', Math.abs(diff)) + - ' before this heading’s content', - pointStart(node.children[0]) - ); - } - } - - // Closed ATX headings always must have a space between their content and - // the final hashes, thus, there is no `add x spaces`. - if (type === 'atx-closed') { - const final = pointEnd(node.children[node.children.length - 1]); - const diff = pointEnd(node).column - final.column - 1 - node.depth; - - if (diff) { - file.message( - 'Remove ' + - diff + - ' ' + - plural('space', diff) + - ' after this heading’s content', - final - ); - } - } - }); - } -); - -var remarkLintNoHeadingContentIndent$1 = remarkLintNoHeadingContentIndent; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-inline-padding - * @fileoverview - * Warn when phrasing content is padded with spaces between their markers and - * content. - * - * Warns for emphasis, strong, delete, image, and link. - * - * @example - * {"name": "ok.md"} - * - * Alpha [bravo](http://echo.fox/trot) - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Alpha [ bravo ](http://echo.fox/trot) - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:7-1:38: Don’t pad `link` with inner spaces - */ - -const remarkLintNoInlinePadding = lintRule( - 'remark-lint:no-inline-padding', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - // Note: `emphasis`, `strong`, `delete` (GFM) can’t have padding anymore - // since CM. - visit$1(tree, (node) => { - if ( - (node.type === 'link' || node.type === 'linkReference') && - !generated(node) - ) { - const value = toString(node); - - if (value.charAt(0) === ' ' || value.charAt(value.length - 1) === ' ') { - file.message('Don’t pad `' + node.type + '` with inner spaces', node); - } - } - }); - } -); - -var remarkLintNoInlinePadding$1 = remarkLintNoInlinePadding; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-shortcut-reference-image - * @fileoverview - * Warn when shortcut reference images are used. - * - * Shortcut references render as images when a definition is found, and as - * plain text without definition. - * Sometimes, you don’t intend to create an image from the reference, but this - * rule still warns anyway. - * In that case, you can escape the reference like so: `!\[foo]`. - * - * @example - * {"name": "ok.md"} - * - * ![foo][] - * - * [foo]: http://foo.bar/baz.png - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * ![foo] - * - * [foo]: http://foo.bar/baz.png - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:7: Use the trailing [] on reference images - */ - -const remarkLintNoShortcutReferenceImage = lintRule( - 'remark-lint:no-shortcut-reference-image', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'imageReference', (node) => { - if (!generated(node) && node.referenceType === 'shortcut') { - file.message('Use the trailing [] on reference images', node); - } - }); - } -); - -var remarkLintNoShortcutReferenceImage$1 = remarkLintNoShortcutReferenceImage; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module no-shortcut-reference-link - * @fileoverview - * Warn when shortcut reference links are used. - * - * Shortcut references render as links when a definition is found, and as - * plain text without definition. - * Sometimes, you don’t intend to create a link from the reference, but this - * rule still warns anyway. - * In that case, you can escape the reference like so: `\[foo]`. - * - * @example - * {"name": "ok.md"} - * - * [foo][] - * - * [foo]: http://foo.bar/baz - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [foo] - * - * [foo]: http://foo.bar/baz - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:6: Use the trailing `[]` on reference links - */ - -const remarkLintNoShortcutReferenceLink = lintRule( - 'remark-lint:no-shortcut-reference-link', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - visit$1(tree, 'linkReference', (node) => { - if (!generated(node) && node.referenceType === 'shortcut') { - file.message('Use the trailing `[]` on reference links', node); - } - }); - } -); - -var remarkLintNoShortcutReferenceLink$1 = remarkLintNoShortcutReferenceLink; - -/** - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * @module no-undefined-references - * @fileoverview - * Warn when references to undefined definitions are found. - * - * Options: `Object`, optional. - * - * The object can have an `allow` field, set to an array of strings that may - * appear between `[` and `]`, but that should not be treated as link - * identifiers. - * - * @example - * {"name": "ok.md"} - * - * [foo][] - * - * Just a [ bracket. - * - * Typically, you’d want to use escapes (with a backslash: \\) to escape what - * could turn into a \[reference otherwise]. - * - * Just two braces can’t link: []. - * - * [foo]: https://example.com - * - * @example - * {"name": "ok-allow.md", "setting": {"allow": ["...", "…"]}} - * - * > Eliding a portion of a quoted passage […] is acceptable. - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [bar] - * - * [baz][] - * - * [text][qux] - * - * Spread [over - * lines][] - * - * > in [a - * > block quote][] - * - * [asd][a - * - * Can include [*emphasis*]. - * - * Multiple pairs: [a][b][c]. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:6: Found reference to undefined definition - * 3:1-3:8: Found reference to undefined definition - * 5:1-5:12: Found reference to undefined definition - * 7:8-8:9: Found reference to undefined definition - * 10:6-11:17: Found reference to undefined definition - * 13:1-13:6: Found reference to undefined definition - * 15:13-15:25: Found reference to undefined definition - * 17:17-17:23: Found reference to undefined definition - * 17:23-17:26: Found reference to undefined definition - */ - -const remarkLintNoUndefinedReferences = lintRule( - 'remark-lint:no-undefined-references', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = {}) => { - const contents = String(file); - const loc = location(file); - const lineEnding = /(\r?\n|\r)[\t ]*(>[\t ]*)*/g; - const allow = new Set( - (option.allow || []).map((d) => normalizeIdentifier(d)) - ); - /** @type {Record} */ - const map = Object.create(null); - - visit$1(tree, (node) => { - if ( - (node.type === 'definition' || node.type === 'footnoteDefinition') && - !generated(node) - ) { - map[normalizeIdentifier(node.identifier)] = true; - } - }); - - visit$1(tree, (node) => { - // CM specifiers that references only form when defined. - // Still, they could be added by plugins, so let’s keep it. - /* c8 ignore next 10 */ - if ( - (node.type === 'imageReference' || - node.type === 'linkReference' || - node.type === 'footnoteReference') && - !generated(node) && - !(normalizeIdentifier(node.identifier) in map) && - !allow.has(normalizeIdentifier(node.identifier)) - ) { - file.message('Found reference to undefined definition', node); - } - - if (node.type === 'paragraph' || node.type === 'heading') { - findInPhrasing(node); - } - }); - - /** - * @param {Heading|Paragraph} node - */ - function findInPhrasing(node) { - /** @type {Range[]} */ - let ranges = []; - - visit$1(node, (child) => { - // Ignore the node itself. - if (child === node) return - - // Can’t have links in links, so reset ranges. - if (child.type === 'link' || child.type === 'linkReference') { - ranges = []; - return SKIP$1 - } - - // Enter non-text. - if (child.type !== 'text') return - - const start = pointStart(child).offset; - const end = pointEnd(child).offset; - - // Bail if there’s no positional info. - if (typeof start !== 'number' || typeof end !== 'number') { - return EXIT$1 - } - - const source = contents.slice(start, end); - /** @type {Array.<[number, string]>} */ - const lines = [[start, '']]; - let last = 0; - - lineEnding.lastIndex = 0; - let match = lineEnding.exec(source); - - while (match) { - const index = match.index; - lines[lines.length - 1][1] = source.slice(last, index); - last = index + match[0].length; - lines.push([start + last, '']); - match = lineEnding.exec(source); - } - - lines[lines.length - 1][1] = source.slice(last); - let lineIndex = -1; - - while (++lineIndex < lines.length) { - const line = lines[lineIndex][1]; - let index = 0; - - while (index < line.length) { - const code = line.charCodeAt(index); - - // Skip past escaped brackets. - if (code === 92) { - const next = line.charCodeAt(index + 1); - index++; - - if (next === 91 || next === 93) { - index++; - } - } - // Opening bracket. - else if (code === 91) { - ranges.push([lines[lineIndex][0] + index]); - index++; - } - // Close bracket. - else if (code === 93) { - // No opening. - if (ranges.length === 0) { - index++; - } else if (line.charCodeAt(index + 1) === 91) { - index++; - - // Collapsed or full. - let range = ranges.pop(); - - // Range should always exist. - // eslint-disable-next-line max-depth - if (range) { - range.push(lines[lineIndex][0] + index); - - // This is the end of a reference already. - // eslint-disable-next-line max-depth - if (range.length === 4) { - handleRange(range); - range = []; - } - - range.push(lines[lineIndex][0] + index); - ranges.push(range); - index++; - } - } else { - index++; - - // Shortcut or typical end of a reference. - const range = ranges.pop(); - - // Range should always exist. - // eslint-disable-next-line max-depth - if (range) { - range.push(lines[lineIndex][0] + index); - handleRange(range); - } - } - } - // Anything else. - else { - index++; - } - } - } - }); - - let index = -1; - - while (++index < ranges.length) { - handleRange(ranges[index]); - } - - return SKIP$1 - - /** - * @param {Range} range - */ - function handleRange(range) { - if (range.length === 1) return - if (range.length === 3) range.length = 2; - - // No need to warn for just `[]`. - if (range.length === 2 && range[0] + 2 === range[1]) return - - const offset = range.length === 4 && range[2] + 2 !== range[3] ? 2 : 0; - const id = contents - .slice(range[0 + offset] + 1, range[1 + offset] - 1) - .replace(lineEnding, ' '); - const pos = { - start: loc.toPoint(range[0]), - end: loc.toPoint(range[range.length - 1]) - }; - - if ( - !generated({position: pos}) && - !(normalizeIdentifier(id) in map) && - !allow.has(normalizeIdentifier(id)) - ) { - file.message('Found reference to undefined definition', pos); - } - } - } - } -); - -var remarkLintNoUndefinedReferences$1 = remarkLintNoUndefinedReferences; - -/** - * @author Titus Wormer - * @copyright 2016 Titus Wormer - * @license MIT - * @module no-unused-definitions - * @fileoverview - * Warn when unused definitions are found. - * - * @example - * {"name": "ok.md"} - * - * [foo][] - * - * [foo]: https://example.com - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [bar]: https://example.com - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:27: Found unused definition - */ - -const own$1 = {}.hasOwnProperty; - -const remarkLintNoUnusedDefinitions = lintRule( - 'remark-lint:no-unused-definitions', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - /** @type {Record} */ - const map = Object.create(null); - - visit$1(tree, (node) => { - if ( - (node.type === 'definition' || node.type === 'footnoteDefinition') && - !generated(node) - ) { - map[node.identifier.toUpperCase()] = {node, used: false}; - } - }); - - visit$1(tree, (node) => { - if ( - node.type === 'imageReference' || - node.type === 'linkReference' || - node.type === 'footnoteReference' - ) { - const info = map[node.identifier.toUpperCase()]; - - if (!generated(node) && info) { - info.used = true; - } - } - }); - - /** @type {string} */ - let identifier; - - for (identifier in map) { - if (own$1.call(map, identifier)) { - const entry = map[identifier]; - - if (!entry.used) { - file.message('Found unused definition', entry.node); - } - } - } - } -); - -var remarkLintNoUnusedDefinitions$1 = remarkLintNoUnusedDefinitions; - -/** - * @fileoverview - * remark preset to configure `remark-lint` with settings that prevent - * mistakes or stuff that fails across vendors. - */ - -/** @type {Preset} */ -const remarkPresetLintRecommended = { - plugins: [ - remarkLint, - // Unix compatibility. - remarkLintFinalNewline$1, - // Rendering across vendors differs greatly if using other styles. - remarkLintListItemBulletIndent$1, - [remarkLintListItemIndent$1, 'tab-size'], - // Differs or unsupported across vendors. - remarkLintNoAutoLinkWithoutProtocol$1, - remarkLintNoBlockquoteWithoutMarker$1, - remarkLintNoLiteralUrls$1, - [remarkLintOrderedListMarkerStyle$1, '.'], - // Mistakes. - remarkLintHardBreakSpaces$1, - remarkLintNoDuplicateDefinitions$1, - remarkLintNoHeadingContentIndent$1, - remarkLintNoInlinePadding$1, - remarkLintNoShortcutReferenceImage$1, - remarkLintNoShortcutReferenceLink$1, - remarkLintNoUndefinedReferences$1, - remarkLintNoUnusedDefinitions$1 - ] -}; - -var remarkPresetLintRecommended$1 = remarkPresetLintRecommended; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module blockquote-indentation - * @fileoverview - * Warn when block quotes are indented too much or too little. - * - * Options: `number` or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used indentation and will warn when - * other block quotes use a different indentation. - * - * @example - * {"name": "ok.md", "setting": 4} - * - * > Hello - * - * Paragraph. - * - * > World - * @example - * {"name": "ok.md", "setting": 2} - * - * > Hello - * - * Paragraph. - * - * > World - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * > Hello - * - * Paragraph. - * - * > World - * - * Paragraph. - * - * > World - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 5:5: Remove 1 space between block quote and content - * 9:3: Add 1 space between block quote and content - */ - -const remarkLintBlockquoteIndentation = lintRule( - 'remark-lint:blockquote-indentation', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - visit$1(tree, 'blockquote', (node) => { - if (generated(node) || node.children.length === 0) { - return - } - - if (option === 'consistent') { - option = check(node); - } else { - const diff = option - check(node); - - if (diff !== 0) { - const abs = Math.abs(diff); - - file.message( - (diff > 0 ? 'Add' : 'Remove') + - ' ' + - abs + - ' ' + - plural('space', abs) + - ' between block quote and content', - pointStart(node.children[0]) - ); - } - } - }); - } -); - -var remarkLintBlockquoteIndentation$1 = remarkLintBlockquoteIndentation; - -/** - * @param {Blockquote} node - * @returns {number} - */ -function check(node) { - return pointStart(node.children[0]).column - pointStart(node).column -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module checkbox-character-style - * @fileoverview - * Warn when list item checkboxes violate a given style. - * - * Options: `Object` or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used checked and unchecked checkbox - * styles and warns when subsequent checkboxes use different styles. - * - * Styles can also be passed in like so: - * - * ```js - * {checked: 'x', unchecked: ' '} - * ``` - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats checked checkboxes using `x` (lowercase X) and unchecked checkboxes - * as `·` (a single space). - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "setting": {"checked": "x"}, "gfm": true} - * - * - [x] List item - * - [x] List item - * - * @example - * {"name": "ok.md", "setting": {"checked": "X"}, "gfm": true} - * - * - [X] List item - * - [X] List item - * - * @example - * {"name": "ok.md", "setting": {"unchecked": " "}, "gfm": true} - * - * - [ ] List item - * - [ ] List item - * - [ ]·· - * - [ ] - * - * @example - * {"name": "ok.md", "setting": {"unchecked": "\t"}, "gfm": true} - * - * - [»] List item - * - [»] List item - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * - [x] List item - * - [X] List item - * - [ ] List item - * - [»] List item - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 2:5: Checked checkboxes should use `x` as a marker - * 4:5: Unchecked checkboxes should use ` ` as a marker - * - * @example - * {"setting": {"unchecked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} - * - * 1:1: Incorrect unchecked checkbox marker `💩`: use either `'\t'`, or `' '` - * - * @example - * {"setting": {"checked": "💩"}, "name": "not-ok.md", "label": "output", "positionless": true, "gfm": true} - * - * 1:1: Incorrect checked checkbox marker `💩`: use either `'x'`, or `'X'` - */ - -const remarkLintCheckboxCharacterStyle = lintRule( - 'remark-lint:checkbox-character-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - /** @type {'x'|'X'|'consistent'} */ - let checked = 'consistent'; - /** @type {' '|'\x09'|'consistent'} */ - let unchecked = 'consistent'; - - if (typeof option === 'object') { - checked = option.checked || 'consistent'; - unchecked = option.unchecked || 'consistent'; - } - - if (unchecked !== 'consistent' && unchecked !== ' ' && unchecked !== '\t') { - file.fail( - 'Incorrect unchecked checkbox marker `' + - unchecked + - "`: use either `'\\t'`, or `' '`" - ); - } - - if (checked !== 'consistent' && checked !== 'x' && checked !== 'X') { - file.fail( - 'Incorrect checked checkbox marker `' + - checked + - "`: use either `'x'`, or `'X'`" - ); - } - - visit$1(tree, 'listItem', (node) => { - const head = node.children[0]; - const point = pointStart(head); - - // Exit early for items without checkbox. - // A list item cannot be checked and empty, according to GFM. - if ( - typeof node.checked !== 'boolean' || - !head || - typeof point.offset !== 'number' - ) { - return - } - - // Move back to before `] `. - point.offset -= 2; - point.column -= 2; - - // Assume we start with a checkbox, because well, `checked` is set. - const match = /\[([\t Xx])]/.exec( - value.slice(point.offset - 2, point.offset + 1) - ); - - // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. - /* c8 ignore next */ - if (!match) return - - const style = node.checked ? checked : unchecked; - - if (style === 'consistent') { - if (node.checked) { - // @ts-expect-error: valid marker. - checked = match[1]; - } else { - // @ts-expect-error: valid marker. - unchecked = match[1]; - } - } else if (match[1] !== style) { - file.message( - (node.checked ? 'Checked' : 'Unchecked') + - ' checkboxes should use `' + - style + - '` as a marker', - point - ); - } - }); - } -); - -var remarkLintCheckboxCharacterStyle$1 = remarkLintCheckboxCharacterStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module checkbox-content-indent - * @fileoverview - * Warn when list item checkboxes are followed by too much whitespace. - * - * @example - * {"name": "ok.md", "gfm": true} - * - * - [ ] List item - * + [x] List Item - * * [X] List item - * - [ ] List item - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * - [ ] List item - * + [x] List item - * * [X] List item - * - [ ] List item - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 2:7-2:8: Checkboxes should be followed by a single character - * 3:7-3:9: Checkboxes should be followed by a single character - * 4:7-4:10: Checkboxes should be followed by a single character - */ - -const remarkLintCheckboxContentIndent = lintRule( - 'remark-lint:checkbox-content-indent', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - const loc = location(file); - - visit$1(tree, 'listItem', (node) => { - const head = node.children[0]; - const point = pointStart(head); - - // Exit early for items without checkbox. - // A list item cannot be checked and empty, according to GFM. - if ( - typeof node.checked !== 'boolean' || - !head || - typeof point.offset !== 'number' - ) { - return - } - - // Assume we start with a checkbox, because well, `checked` is set. - const match = /\[([\t xX])]/.exec( - value.slice(point.offset - 4, point.offset + 1) - ); - - // Failsafe to make sure we don‘t crash if there actually isn’t a checkbox. - /* c8 ignore next */ - if (!match) return - - // Move past checkbox. - const initial = point.offset; - let final = initial; - - while (/[\t ]/.test(value.charAt(final))) final++; - - if (final - initial > 0) { - file.message('Checkboxes should be followed by a single character', { - start: loc.toPoint(initial), - end: loc.toPoint(final) - }); - } - }); - } -); - -var remarkLintCheckboxContentIndent$1 = remarkLintCheckboxContentIndent; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module code-block-style - * @fileoverview - * Warn when code blocks do not adhere to a given style. - * - * Options: `'consistent'`, `'fenced'`, or `'indented'`, default: `'consistent'`. - * - * `'consistent'` detects the first used code block style and warns when - * subsequent code blocks uses different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats code blocks using a fence if they have a language flag and - * indentation if not. - * Pass - * [`fences: true`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfences) - * to always use fences for code blocks. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"setting": "indented", "name": "ok.md"} - * - * alpha() - * - * Paragraph. - * - * bravo() - * - * @example - * {"setting": "indented", "name": "not-ok.md", "label": "input"} - * - * ``` - * alpha() - * ``` - * - * Paragraph. - * - * ``` - * bravo() - * ``` - * - * @example - * {"setting": "indented", "name": "not-ok.md", "label": "output"} - * - * 1:1-3:4: Code blocks should be indented - * 7:1-9:4: Code blocks should be indented - * - * @example - * {"setting": "fenced", "name": "ok.md"} - * - * ``` - * alpha() - * ``` - * - * Paragraph. - * - * ``` - * bravo() - * ``` - * - * @example - * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "input"} - * - * alpha() - * - * Paragraph. - * - * bravo() - * - * @example - * {"setting": "fenced", "name": "not-ok-fenced.md", "label": "output"} - * - * 1:1-1:12: Code blocks should be fenced - * 5:1-5:12: Code blocks should be fenced - * - * @example - * {"name": "not-ok-consistent.md", "label": "input"} - * - * alpha() - * - * Paragraph. - * - * ``` - * bravo() - * ``` - * - * @example - * {"name": "not-ok-consistent.md", "label": "output"} - * - * 5:1-7:4: Code blocks should be indented - * - * @example - * {"setting": "💩", "name": "not-ok-incorrect.md", "label": "output", "positionless": true} - * - * 1:1: Incorrect code block style `💩`: use either `'consistent'`, `'fenced'`, or `'indented'` - */ - -const remarkLintCodeBlockStyle = lintRule( - 'remark-lint:code-block-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if ( - option !== 'consistent' && - option !== 'fenced' && - option !== 'indented' - ) { - file.fail( - 'Incorrect code block style `' + - option + - "`: use either `'consistent'`, `'fenced'`, or `'indented'`" - ); - } - - visit$1(tree, 'code', (node) => { - if (generated(node)) { - return - } - - const initial = pointStart(node).offset; - const final = pointEnd(node).offset; - - const current = - node.lang || /^\s*([~`])\1{2,}/.test(value.slice(initial, final)) - ? 'fenced' - : 'indented'; - - if (option === 'consistent') { - option = current; - } else if (option !== current) { - file.message('Code blocks should be ' + option, node); - } - }); - } -); - -var remarkLintCodeBlockStyle$1 = remarkLintCodeBlockStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module definition-spacing - * @fileoverview - * Warn when consecutive whitespace is used in a definition. - * - * @example - * {"name": "ok.md"} - * - * [example domain]: http://example.com "Example Domain" - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * [example····domain]: http://example.com "Example Domain" - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-1:57: Do not use consecutive whitespace in definition labels - */ - -const label = /^\s*\[((?:\\[\s\S]|[^[\]])+)]/; - -const remarkLintDefinitionSpacing = lintRule( - 'remark-lint:definition-spacing', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - - visit$1(tree, (node) => { - if (node.type === 'definition' || node.type === 'footnoteDefinition') { - const start = pointStart(node).offset; - const end = pointEnd(node).offset; - - if (typeof start === 'number' && typeof end === 'number') { - const match = value.slice(start, end).match(label); - - if (match && /[ \t\n]{2,}/.test(match[1])) { - file.message( - 'Do not use consecutive whitespace in definition labels', - node - ); - } - } - } - }); - } -); - -var remarkLintDefinitionSpacing$1 = remarkLintDefinitionSpacing; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module fenced-code-flag - * @fileoverview - * Check fenced code block flags. - * - * Options: `Array.` or `Object`, optional. - * - * Providing an array is as passing `{flags: Array}`. - * - * The object can have an array of `'flags'` which are allowed: other flags - * will not be allowed. - * An `allowEmpty` field (`boolean`, default: `false`) can be set to allow - * code blocks without language flags. - * - * @example - * {"name": "ok.md"} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * ``` - * alpha() - * ``` - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:1-3:4: Missing code language flag - * - * @example - * {"name": "ok.md", "setting": {"allowEmpty": true}} - * - * ``` - * alpha() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "input"} - * - * ``` - * alpha() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": {"allowEmpty": false}, "label": "output"} - * - * 1:1-3:4: Missing code language flag - * - * @example - * {"name": "ok.md", "setting": ["alpha"]} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "ok.md", "setting": {"flags":["alpha"]}} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": ["charlie"], "label": "input"} - * - * ```alpha - * bravo() - * ``` - * - * @example - * {"name": "not-ok.md", "setting": ["charlie"], "label": "output"} - * - * 1:1-3:4: Incorrect code language flag - */ - -const fence = /^ {0,3}([~`])\1{2,}/; - -const remarkLintFencedCodeFlag = lintRule( - 'remark-lint:fenced-code-flag', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option) => { - const value = String(file); - let allowEmpty = false; - /** @type {string[]} */ - let allowed = []; - - if (typeof option === 'object') { - if (Array.isArray(option)) { - allowed = option; - } else { - allowEmpty = Boolean(option.allowEmpty); - - if (option.flags) { - allowed = option.flags; - } - } - } - - visit$1(tree, 'code', (node) => { - if (!generated(node)) { - if (node.lang) { - if (allowed.length > 0 && !allowed.includes(node.lang)) { - file.message('Incorrect code language flag', node); - } - } else { - const slice = value.slice( - pointStart(node).offset, - pointEnd(node).offset - ); - - if (!allowEmpty && fence.test(slice)) { - file.message('Missing code language flag', node); - } - } - } - }); - } -); - -var remarkLintFencedCodeFlag$1 = remarkLintFencedCodeFlag; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module fenced-code-marker - * @fileoverview - * Warn for violating fenced code markers. - * - * Options: `` '`' ``, `'~'`, or `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used fenced code marker style and warns - * when subsequent fenced code blocks use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats fences using ``'`'`` (grave accent) by default. - * Pass - * [`fence: '~'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsfence) - * to use `~` (tilde) instead. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * Indented code blocks are not affected by this rule: - * - * bravo() - * - * @example - * {"name": "ok.md", "setting": "`"} - * - * ```alpha - * bravo() - * ``` - * - * ``` - * charlie() - * ``` - * - * @example - * {"name": "ok.md", "setting": "~"} - * - * ~~~alpha - * bravo() - * ~~~ - * - * ~~~ - * charlie() - * ~~~ - * - * @example - * {"name": "not-ok-consistent-tick.md", "label": "input"} - * - * ```alpha - * bravo() - * ``` - * - * ~~~ - * charlie() - * ~~~ - * - * @example - * {"name": "not-ok-consistent-tick.md", "label": "output"} - * - * 5:1-7:4: Fenced code should use `` ` `` as a marker - * - * @example - * {"name": "not-ok-consistent-tilde.md", "label": "input"} - * - * ~~~alpha - * bravo() - * ~~~ - * - * ``` - * charlie() - * ``` - * - * @example - * {"name": "not-ok-consistent-tilde.md", "label": "output"} - * - * 5:1-7:4: Fenced code should use `~` as a marker - * - * @example - * {"name": "not-ok-incorrect.md", "setting": "💩", "label": "output", "positionless": true} - * - * 1:1: Incorrect fenced code marker `💩`: use either `'consistent'`, `` '`' ``, or `'~'` - */ - -const remarkLintFencedCodeMarker = lintRule( - 'remark-lint:fenced-code-marker', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const contents = String(file); - - if (option !== 'consistent' && option !== '~' && option !== '`') { - file.fail( - 'Incorrect fenced code marker `' + - option + - "`: use either `'consistent'`, `` '`' ``, or `'~'`" - ); - } - - visit$1(tree, 'code', (node) => { - const start = pointStart(node).offset; - - if (typeof start === 'number') { - const marker = contents - .slice(start, start + 4) - .replace(/^\s+/, '') - .charAt(0); - - // Ignore unfenced code blocks. - if (marker === '~' || marker === '`') { - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message( - 'Fenced code should use `' + - (option === '~' ? option : '` ` `') + - '` as a marker', - node - ); - } - } - } - }); - } -); - -var remarkLintFencedCodeMarker$1 = remarkLintFencedCodeMarker; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module file-extension - * @fileoverview - * Warn when the file extension differ from the preferred extension. - * - * Does not warn when given documents have no file extensions (such as - * `AUTHORS` or `LICENSE`). - * - * Options: `string`, default: `'md'` — Expected file extension. - * - * @example - * {"name": "readme.md"} - * - * @example - * {"name": "readme"} - * - * @example - * {"name": "readme.mkd", "label": "output", "positionless": true} - * - * 1:1: Incorrect extension: use `md` - * - * @example - * {"name": "readme.mkd", "setting": "mkd"} - */ - -const remarkLintFileExtension = lintRule( - 'remark-lint:file-extension', - /** @type {import('unified-lint-rule').Rule} */ - (_, file, option = 'md') => { - const ext = file.extname; - - if (ext && ext.slice(1) !== option) { - file.message('Incorrect extension: use `' + option + '`'); - } - } -); - -var remarkLintFileExtension$1 = remarkLintFileExtension; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module final-definition - * @fileoverview - * Warn when definitions are placed somewhere other than at the end of - * the file. - * - * @example - * {"name": "ok.md"} - * - * Paragraph. - * - * [example]: http://example.com "Example Domain" - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * Paragraph. - * - * [example]: http://example.com "Example Domain" - * - * Another paragraph. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:1-3:47: Move definitions to the end of the file (after the node at line `5`) - * - * @example - * {"name": "ok-comments.md"} - * - * Paragraph. - * - * [example-1]: http://example.com/one/ - * - * - * - * [example-2]: http://example.com/two/ - */ - -const remarkLintFinalDefinition = lintRule( - 'remark-lint:final-definition', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - let last = 0; - - visit$1( - tree, - (node) => { - // Ignore generated and HTML comment nodes. - if ( - node.type === 'root' || - generated(node) || - (node.type === 'html' && /^\s*".length)); - - validateMeta(node, file, meta); - } catch (e) { - file.message(e, node); - } - }); -} - -const remarkLintNodejsYamlComments = lintRule( - "remark-lint:nodejs-yaml-comments", - validateYAMLComments -); - -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'); -} - -const remarkLintProhibitedStrings = lintRule('remark-lint:prohibited-strings', prohibitedStrings); - -function testProhibited (val, content) { - let regexpFlags = 'g'; - let no = val.no; - - if (!no) { - no = escapeStringRegexp(val.yes); - regexpFlags += 'i'; - } - - let regexpString = '(? { - const results = testProhibited(val, content); - if (results.length) { - results.forEach(({ result, index, yes }) => { - const message = val.yes ? `Use "${yes}" instead of "${result}"` : `Do not use "${result}"`; - file.message(message, { - start: myLocation.toPoint(initial + index), - end: myLocation.toPoint(initial + index + [...result].length) - }); - }); - } - }); - } -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module rule-style - * @fileoverview - * Warn when the thematic breaks (horizontal rules) violate a given or - * detected style. - * - * Options: `string`, either a corect thematic breaks such as `***`, or - * `'consistent'`, default: `'consistent'`. - * - * `'consistent'` detects the first used thematic break style and warns when - * subsequent rules use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * has three settings that define how rules are created: - * - * * [`rule`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrule) - * (default: `*`) — Marker to use - * * [`ruleRepetition`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulerepetition) - * (default: `3`) — Number of markers to use - * * [`ruleSpaces`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsrulespaces) - * (default: `true`) — Whether to pad markers with spaces - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "setting": "* * *"} - * - * * * * - * - * * * * - * - * @example - * {"name": "ok.md", "setting": "_______"} - * - * _______ - * - * _______ - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * *** - * - * * * * - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 3:1-3:6: Rules should use `***` - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect preferred rule style: provide a correct markdown rule or `'consistent'` - */ - -const remarkLintRuleStyle = lintRule( - 'remark-lint:rule-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== 'consistent' && /[^-_* ]/.test(option)) { - file.fail( - "Incorrect preferred rule style: provide a correct markdown rule or `'consistent'`" - ); - } - - visit$1(tree, 'thematicBreak', (node) => { - const initial = pointStart(node).offset; - const final = pointEnd(node).offset; - - if (typeof initial === 'number' && typeof final === 'number') { - const rule = value.slice(initial, final); - - if (option === 'consistent') { - option = rule; - } else if (rule !== option) { - file.message('Rules should use `' + option + '`', node); - } - } - }); - } -); - -var remarkLintRuleStyle$1 = remarkLintRuleStyle; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module strong-marker - * @fileoverview - * Warn for violating importance (strong) markers. - * - * Options: `'consistent'`, `'*'`, or `'_'`, default: `'consistent'`. - * - * `'consistent'` detects the first used importance style and warns when - * subsequent importance sequences use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats importance using an `*` (asterisk) by default. - * Pass - * [`strong: '_'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsstrong) - * to use `_` (underscore) instead. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * **foo** and **bar**. - * - * @example - * {"name": "also-ok.md"} - * - * __foo__ and __bar__. - * - * @example - * {"name": "ok.md", "setting": "*"} - * - * **foo**. - * - * @example - * {"name": "ok.md", "setting": "_"} - * - * __foo__. - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * **foo** and __bar__. - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 1:13-1:20: Strong should use `*` as a marker - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect strong marker `💩`: use either `'consistent'`, `'*'`, or `'_'` - */ - -const remarkLintStrongMarker = lintRule( - 'remark-lint:strong-marker', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== '*' && option !== '_' && option !== 'consistent') { - file.fail( - 'Incorrect strong marker `' + - option + - "`: use either `'consistent'`, `'*'`, or `'_'`" - ); - } - - visit$1(tree, 'strong', (node) => { - const start = pointStart(node).offset; - - if (typeof start === 'number') { - const marker = /** @type {Marker} */ (value.charAt(start)); - - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message('Strong should use `' + option + '` as a marker', node); - } - } - }); - } -); - -var remarkLintStrongMarker$1 = remarkLintStrongMarker; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module table-cell-padding - * @fileoverview - * Warn when table cells are incorrectly padded. - * - * Options: `'consistent'`, `'padded'`, or `'compact'`, default: `'consistent'`. - * - * `'consistent'` detects the first used cell padding style and warns when - * subsequent cells use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats tables with padding by default. - * Pass - * [`spacedTable: false`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsspacedtable) - * to not use padding. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "setting": "padded", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * @example - * {"name": "not-ok.md", "label": "input", "setting": "padded", "gfm": true} - * - * | A | B | - * | :----|----: | - * | Alpha|Bravo | - * - * | C | D | - * | :----- | ---: | - * |Charlie | Delta| - * - * Too much padding isn’t good either: - * - * | E | F | G | H | - * | :---- | -------- | :----: | -----: | - * | Echo | Foxtrot | Golf | Hotel | - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "padded", "gfm": true} - * - * 3:8: Cell should be padded - * 3:9: Cell should be padded - * 7:2: Cell should be padded - * 7:17: Cell should be padded - * 13:9: Cell should be padded with 1 space, not 2 - * 13:20: Cell should be padded with 1 space, not 2 - * 13:21: Cell should be padded with 1 space, not 2 - * 13:29: Cell should be padded with 1 space, not 2 - * 13:30: Cell should be padded with 1 space, not 2 - * - * @example - * {"name": "ok.md", "setting": "compact", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * @example - * {"name": "not-ok.md", "label": "input", "setting": "compact", "gfm": true} - * - * | A | B | - * | -----| -----| - * | Alpha| Bravo| - * - * |C | D| - * |:------|-----:| - * |Charlie|Delta | - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "compact", "gfm": true} - * - * 3:2: Cell should be compact - * 3:11: Cell should be compact - * 7:16: Cell should be compact - * - * @example - * {"name": "ok-padded.md", "setting": "consistent", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * | C | D | - * | ------- | ----- | - * | Charlie | Delta | - * - * @example - * {"name": "not-ok-padded.md", "label": "input", "setting": "consistent", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * | C | D | - * | :----- | ----: | - * |Charlie | Delta | - * - * @example - * {"name": "not-ok-padded.md", "label": "output", "setting": "consistent", "gfm": true} - * - * 7:2: Cell should be padded - * - * @example - * {"name": "ok-compact.md", "setting": "consistent", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * |C |D | - * |-------|-----| - * |Charlie|Delta| - * - * @example - * {"name": "not-ok-compact.md", "label": "input", "setting": "consistent", "gfm": true} - * - * |A |B | - * |-----|-----| - * |Alpha|Bravo| - * - * |C | D| - * |:------|-----:| - * |Charlie|Delta | - * - * @example - * {"name": "not-ok-compact.md", "label": "output", "setting": "consistent", "gfm": true} - * - * 7:16: Cell should be compact - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true, "gfm": true} - * - * 1:1: Incorrect table cell padding style `💩`, expected `'padded'`, `'compact'`, or `'consistent'` - * - * @example - * {"name": "empty.md", "label": "input", "setting": "padded", "gfm": true} - * - * - * - * | | Alpha | Bravo| - * | ------ | ----- | ---: | - * | Charlie| | Echo| - * - * @example - * {"name": "empty.md", "label": "output", "setting": "padded", "gfm": true} - * - * 3:25: Cell should be padded - * 5:10: Cell should be padded - * 5:25: Cell should be padded - * - * @example - * {"name": "missing-body.md", "setting": "padded", "gfm": true} - * - * - * - * | Alpha | Bravo | Charlie | - * | ----- | ------- | ------- | - * | Delta | - * | Echo | Foxtrot | - */ - -const remarkLintTableCellPadding = lintRule( - 'remark-lint:table-cell-padding', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - if ( - option !== 'padded' && - option !== 'compact' && - option !== 'consistent' - ) { - file.fail( - 'Incorrect table cell padding style `' + - option + - "`, expected `'padded'`, `'compact'`, or `'consistent'`" - ); - } - - visit$1(tree, 'table', (node) => { - const rows = node.children; - // To do: fix types to always have `align` defined. - /* c8 ignore next */ - const align = node.align || []; - /** @type {number[]} */ - const sizes = Array.from({length: align.length}); - /** @type {Entry[]} */ - const entries = []; - let index = -1; - - // Check rows. - while (++index < rows.length) { - const row = rows[index]; - let column = -1; - - // Check fences (before, between, and after cells). - while (++column < row.children.length) { - const cell = row.children[column]; - - if (cell.children.length > 0) { - const cellStart = pointStart(cell).offset; - const cellEnd = pointEnd(cell).offset; - const contentStart = pointStart(cell.children[0]).offset; - const contentEnd = pointEnd( - cell.children[cell.children.length - 1] - ).offset; - - if ( - typeof cellStart !== 'number' || - typeof cellEnd !== 'number' || - typeof contentStart !== 'number' || - typeof contentEnd !== 'number' - ) { - continue - } - - entries.push({ - node: cell, - start: contentStart - cellStart - (column ? 0 : 1), - end: cellEnd - contentEnd - 1, - column - }); - - // Detect max space per column. - sizes[column] = Math.max( - sizes[column] || 0, - contentEnd - contentStart - ); - } - } - } - - const style = - option === 'consistent' - ? entries[0] && (!entries[0].start || !entries[0].end) - ? 0 - : 1 - : option === 'padded' - ? 1 - : 0; - - index = -1; - - while (++index < entries.length) { - checkSide('start', entries[index], style, sizes); - checkSide('end', entries[index], style, sizes); - } - - return SKIP$1 - }); - - /** - * @param {'start'|'end'} side - * @param {Entry} entry - * @param {0|1} style - * @param {number[]} sizes - */ - function checkSide(side, entry, style, sizes) { - const cell = entry.node; - const column = entry.column; - const spacing = entry[side]; - - if (spacing === undefined || spacing === style) { - return - } - - let reason = 'Cell should be '; - - if (style === 0) { - // Ignore every cell except the biggest in the column. - if (size(cell) < sizes[column]) { - return - } - - reason += 'compact'; - } else { - reason += 'padded'; - - if (spacing > style) { - // May be right or center aligned. - if (size(cell) < sizes[column]) { - return - } - - reason += ' with 1 space, not ' + spacing; - } - } - - /** @type {Point} */ - let point; - - if (side === 'start') { - point = pointStart(cell); - if (!column) { - point.column++; - - if (typeof point.offset === 'number') { - point.offset++; - } - } - } else { - point = pointEnd(cell); - point.column--; - - if (typeof point.offset === 'number') { - point.offset--; - } - } - - file.message(reason, point); - } - } -); - -var remarkLintTableCellPadding$1 = remarkLintTableCellPadding; - -/** - * @param {TableCell} node - * @returns {number} - */ -function size(node) { - const head = pointStart(node.children[0]).offset; - const tail = pointEnd(node.children[node.children.length - 1]).offset; - // Only called when we’re sure offsets exist. - /* c8 ignore next */ - return typeof head === 'number' && typeof tail === 'number' ? tail - head : 0 -} - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module table-pipes - * @fileoverview - * Warn when table rows are not fenced with pipes. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * creates fenced rows with initial and final pipes by default. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md", "gfm": true} - * - * | A | B | - * | ----- | ----- | - * | Alpha | Bravo | - * - * @example - * {"name": "not-ok.md", "label": "input", "gfm": true} - * - * A | B - * ----- | ----- - * Alpha | Bravo - * - * @example - * {"name": "not-ok.md", "label": "output", "gfm": true} - * - * 1:1: Missing initial pipe in table fence - * 1:10: Missing final pipe in table fence - * 3:1: Missing initial pipe in table fence - * 3:14: Missing final pipe in table fence - */ - -const reasonStart = 'Missing initial pipe in table fence'; -const reasonEnd = 'Missing final pipe in table fence'; - -const remarkLintTablePipes = lintRule( - 'remark-lint:table-pipes', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file) => { - const value = String(file); - - visit$1(tree, 'table', (node) => { - let index = -1; - - while (++index < node.children.length) { - const row = node.children[index]; - const start = pointStart(row); - const end = pointEnd(row); - - if ( - typeof start.offset === 'number' && - value.charCodeAt(start.offset) !== 124 - ) { - file.message(reasonStart, start); - } - - if ( - typeof end.offset === 'number' && - value.charCodeAt(end.offset - 1) !== 124 - ) { - file.message(reasonEnd, end); - } - } - }); - } -); - -var remarkLintTablePipes$1 = remarkLintTablePipes; - -/** - * @author Titus Wormer - * @copyright 2015 Titus Wormer - * @license MIT - * @module unordered-list-marker-style - * @fileoverview - * Warn when the list item marker style of unordered lists violate a given - * style. - * - * Options: `'consistent'`, `'-'`, `'*'`, or `'+'`, default: `'consistent'`. - * - * `'consistent'` detects the first used list style and warns when subsequent - * lists use different styles. - * - * ## Fix - * - * [`remark-stringify`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify) - * formats unordered lists using `-` (hyphen-minus) by default. - * Pass - * [`bullet: '*'` or `bullet: '+'`](https://github.com/remarkjs/remark/tree/HEAD/packages/remark-stringify#optionsbullet) - * to use `*` (asterisk) or `+` (plus sign) instead. - * - * See [Using remark to fix your Markdown](https://github.com/remarkjs/remark-lint#using-remark-to-fix-your-markdown) - * on how to automatically fix warnings for this rule. - * - * @example - * {"name": "ok.md"} - * - * By default (`'consistent'`), if the file uses only one marker, - * that’s OK. - * - * * Foo - * * Bar - * * Baz - * - * Ordered lists are not affected. - * - * 1. Foo - * 2. Bar - * 3. Baz - * - * @example - * {"name": "ok.md", "setting": "*"} - * - * * Foo - * - * @example - * {"name": "ok.md", "setting": "-"} - * - * - Foo - * - * @example - * {"name": "ok.md", "setting": "+"} - * - * + Foo - * - * @example - * {"name": "not-ok.md", "label": "input"} - * - * * Foo - * - Bar - * + Baz - * - * @example - * {"name": "not-ok.md", "label": "output"} - * - * 2:1-2:6: Marker style should be `*` - * 3:1-3:6: Marker style should be `*` - * - * @example - * {"name": "not-ok.md", "label": "output", "setting": "💩", "positionless": true} - * - * 1:1: Incorrect unordered list item marker style `💩`: use either `'-'`, `'*'`, or `'+'` - */ - -const markers = new Set(['-', '*', '+']); - -const remarkLintUnorderedListMarkerStyle = lintRule( - 'remark-lint:unordered-list-marker-style', - /** @type {import('unified-lint-rule').Rule} */ - (tree, file, option = 'consistent') => { - const value = String(file); - - if (option !== 'consistent' && !markers.has(option)) { - file.fail( - 'Incorrect unordered list item marker style `' + - option + - "`: use either `'-'`, `'*'`, or `'+'`" - ); - } - - visit$1(tree, 'list', (node) => { - if (node.ordered) return - - let index = -1; - - while (++index < node.children.length) { - const child = node.children[index]; - - if (!generated(child)) { - const marker = /** @type {Marker} */ ( - value - .slice( - pointStart(child).offset, - pointStart(child.children[0]).offset - ) - .replace(/\[[x ]?]\s*$/i, '') - .replace(/\s/g, '') - ); - - if (option === 'consistent') { - option = marker; - } else if (marker !== option) { - file.message('Marker style should be `' + option + '`', child); - } - } - } - }); - } -); - -var remarkLintUnorderedListMarkerStyle$1 = remarkLintUnorderedListMarkerStyle; - -// @see https://github.com/nodejs/node/blob/HEAD/doc/guides/doc-style-guide.md - -// Add in rules alphabetically -const plugins = [ - // Leave preset at the top so it can be overridden - remarkPresetLintRecommended$1, - [remarkLintBlockquoteIndentation$1, 2], - [remarkLintCheckboxCharacterStyle$1, { checked: "x", unchecked: " " }], - remarkLintCheckboxContentIndent$1, - [remarkLintCodeBlockStyle$1, "fenced"], - remarkLintDefinitionSpacing$1, - [ - remarkLintFencedCodeFlag$1, - { - flags: [ - "bash", - "c", - "cjs", - "coffee", - "console", - "cpp", - "diff", - "http", - "js", - "json", - "markdown", - "mjs", - "powershell", - "r", - "text", - ], - }, - ], - [remarkLintFencedCodeMarker$1, "`"], - [remarkLintFileExtension$1, "md"], - remarkLintFinalDefinition$1, - [remarkLintFirstHeadingLevel$1, 1], - [remarkLintHeadingStyle$1, "atx"], - [remarkLintListItemIndent$1, "space"], - remarkLintMaximumLineLength$1, - remarkLintNoConsecutiveBlankLines$1, - remarkLintNoFileNameArticles$1, - remarkLintNoFileNameConsecutiveDashes$1, - remarkLintNofileNameOuterDashes$1, - remarkLintNoHeadingIndent$1, - remarkLintNoMultipleToplevelHeadings$1, - remarkLintNoShellDollars$1, - remarkLintNoTableIndentation$1, - remarkLintNoTabs$1, - remarkLintNoTrailingSpaces, - remarkLintNodejsLinks, - remarkLintNodejsYamlComments, - [ - remarkLintProhibitedStrings, - [ - { yes: "End-of-Life" }, - { yes: "GitHub" }, - { no: "hostname", yes: "host name" }, - { yes: "JavaScript" }, - { no: "[Ll]ong[ -][Tt]erm [Ss]upport", yes: "Long Term Support" }, - { no: "Node", yes: "Node.js", ignoreNextTo: "-API" }, - { yes: "Node.js" }, - { no: "Node[Jj][Ss]", yes: "Node.js" }, - { no: "Node\\.js's?", yes: "the Node.js" }, - { no: "[Nn]ote that", yes: "" }, - { yes: "RFC" }, - { no: "[Rr][Ff][Cc]\\d+", yes: "RFC " }, - { yes: "Unix" }, - { yes: "V8" }, - ], - ], - remarkLintRuleStyle$1, - [remarkLintStrongMarker$1, "*"], - [remarkLintTableCellPadding$1, "padded"], - remarkLintTablePipes$1, - [remarkLintUnorderedListMarkerStyle$1, "*"], -]; - -const remarkPresetLintNode = { plugins }; - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').ConstructRecord} ConstructRecord - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').Previous} Previous - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Event} Event - * @typedef {import('micromark-util-types').Code} Code - */ -const www = { - tokenize: tokenizeWww, - partial: true -}; -const domain = { - tokenize: tokenizeDomain, - partial: true -}; -const path = { - tokenize: tokenizePath, - partial: true -}; -const punctuation = { - tokenize: tokenizePunctuation, - partial: true -}; -const namedCharacterReference = { - tokenize: tokenizeNamedCharacterReference, - partial: true -}; -const wwwAutolink = { - tokenize: tokenizeWwwAutolink, - previous: previousWww -}; -const httpAutolink = { - tokenize: tokenizeHttpAutolink, - previous: previousHttp -}; -const emailAutolink = { - tokenize: tokenizeEmailAutolink, - previous: previousEmail -}; -/** @type {ConstructRecord} */ - -const text = {}; -/** @type {Extension} */ - -const gfmAutolinkLiteral = { - text -}; -let code = 48; // Add alphanumerics. - -while (code < 123) { - text[code] = emailAutolink; - code++; - if (code === 58) code = 65; - else if (code === 91) code = 97; -} - -text[43] = emailAutolink; -text[45] = emailAutolink; -text[46] = emailAutolink; -text[95] = emailAutolink; -text[72] = [emailAutolink, httpAutolink]; -text[104] = [emailAutolink, httpAutolink]; -text[87] = [emailAutolink, wwwAutolink]; -text[119] = [emailAutolink, wwwAutolink]; -/** @type {Tokenizer} */ - -function tokenizeEmailAutolink(effects, ok, nok) { - const self = this; - /** @type {boolean} */ - - let hasDot; - /** @type {boolean|undefined} */ - - let hasDigitInLastSegment; - return start - /** @type {State} */ - - function start(code) { - if ( - !gfmAtext(code) || - !previousEmail(self.previous) || - previousUnbalanced(self.events) - ) { - return nok(code) - } - - effects.enter('literalAutolink'); - effects.enter('literalAutolinkEmail'); - return atext(code) - } - /** @type {State} */ - - function atext(code) { - if (gfmAtext(code)) { - effects.consume(code); - return atext - } - - if (code === 64) { - effects.consume(code); - return label - } - - return nok(code) - } - /** @type {State} */ - - function label(code) { - if (code === 46) { - return effects.check(punctuation, done, dotContinuation)(code) - } - - if (code === 45 || code === 95) { - return effects.check(punctuation, nok, dashOrUnderscoreContinuation)(code) - } - - if (asciiAlphanumeric(code)) { - if (!hasDigitInLastSegment && asciiDigit(code)) { - hasDigitInLastSegment = true; - } - - effects.consume(code); - return label - } - - return done(code) - } - /** @type {State} */ - - function dotContinuation(code) { - effects.consume(code); - hasDot = true; - hasDigitInLastSegment = undefined; - return label - } - /** @type {State} */ - - function dashOrUnderscoreContinuation(code) { - effects.consume(code); - return afterDashOrUnderscore - } - /** @type {State} */ - - function afterDashOrUnderscore(code) { - if (code === 46) { - return effects.check(punctuation, nok, dotContinuation)(code) - } - - return label(code) - } - /** @type {State} */ - - function done(code) { - if (hasDot && !hasDigitInLastSegment) { - effects.exit('literalAutolinkEmail'); - effects.exit('literalAutolink'); - return ok(code) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeWwwAutolink(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - if ( - (code !== 87 && code !== 119) || - !previousWww(self.previous) || - previousUnbalanced(self.events) - ) { - return nok(code) - } - - effects.enter('literalAutolink'); - effects.enter('literalAutolinkWww'); // For `www.` we check instead of attempt, because when it matches, GH - // treats it as part of a domain (yes, it says a valid domain must come - // after `www.`, but that’s not how it’s implemented by them). - - return effects.check( - www, - effects.attempt(domain, effects.attempt(path, done), nok), - nok - )(code) - } - /** @type {State} */ - - function done(code) { - effects.exit('literalAutolinkWww'); - effects.exit('literalAutolink'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeHttpAutolink(effects, ok, nok) { - const self = this; - return start - /** @type {State} */ - - function start(code) { - if ( - (code !== 72 && code !== 104) || - !previousHttp(self.previous) || - previousUnbalanced(self.events) - ) { - return nok(code) - } - - effects.enter('literalAutolink'); - effects.enter('literalAutolinkHttp'); - effects.consume(code); - return t1 - } - /** @type {State} */ - - function t1(code) { - if (code === 84 || code === 116) { - effects.consume(code); - return t2 - } - - return nok(code) - } - /** @type {State} */ - - function t2(code) { - if (code === 84 || code === 116) { - effects.consume(code); - return p - } - - return nok(code) - } - /** @type {State} */ - - function p(code) { - if (code === 80 || code === 112) { - effects.consume(code); - return s - } - - return nok(code) - } - /** @type {State} */ - - function s(code) { - if (code === 83 || code === 115) { - effects.consume(code); - return colon - } - - return colon(code) - } - /** @type {State} */ - - function colon(code) { - if (code === 58) { - effects.consume(code); - return slash1 - } - - return nok(code) - } - /** @type {State} */ - - function slash1(code) { - if (code === 47) { - effects.consume(code); - return slash2 - } - - return nok(code) - } - /** @type {State} */ - - function slash2(code) { - if (code === 47) { - effects.consume(code); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - return code === null || - asciiControl(code) || - unicodeWhitespace(code) || - unicodePunctuation(code) - ? nok(code) - : effects.attempt(domain, effects.attempt(path, done), nok)(code) - } - /** @type {State} */ - - function done(code) { - effects.exit('literalAutolinkHttp'); - effects.exit('literalAutolink'); - return ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeWww(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.consume(code); - return w2 - } - /** @type {State} */ - - function w2(code) { - if (code === 87 || code === 119) { - effects.consume(code); - return w3 - } - - return nok(code) - } - /** @type {State} */ - - function w3(code) { - if (code === 87 || code === 119) { - effects.consume(code); - return dot - } - - return nok(code) - } - /** @type {State} */ - - function dot(code) { - if (code === 46) { - effects.consume(code); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - return code === null || markdownLineEnding(code) ? nok(code) : ok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeDomain(effects, ok, nok) { - /** @type {boolean|undefined} */ - let hasUnderscoreInLastSegment; - /** @type {boolean|undefined} */ - - let hasUnderscoreInLastLastSegment; - return domain - /** @type {State} */ - - function domain(code) { - if (code === 38) { - return effects.check( - namedCharacterReference, - done, - punctuationContinuation - )(code) - } - - if (code === 46 || code === 95) { - return effects.check(punctuation, done, punctuationContinuation)(code) - } // GH documents that only alphanumerics (other than `-`, `.`, and `_`) can - // occur, which sounds like ASCII only, but they also support `www.點看.com`, - // so that’s Unicode. - // Instead of some new production for Unicode alphanumerics, markdown - // already has that for Unicode punctuation and whitespace, so use those. - - if ( - code === null || - asciiControl(code) || - unicodeWhitespace(code) || - (code !== 45 && unicodePunctuation(code)) - ) { - return done(code) - } - - effects.consume(code); - return domain - } - /** @type {State} */ - - function punctuationContinuation(code) { - if (code === 46) { - hasUnderscoreInLastLastSegment = hasUnderscoreInLastSegment; - hasUnderscoreInLastSegment = undefined; - effects.consume(code); - return domain - } - - if (code === 95) hasUnderscoreInLastSegment = true; - effects.consume(code); - return domain - } - /** @type {State} */ - - function done(code) { - if (!hasUnderscoreInLastLastSegment && !hasUnderscoreInLastSegment) { - return ok(code) - } - - return nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizePath(effects, ok) { - let balance = 0; - return inPath - /** @type {State} */ - - function inPath(code) { - if (code === 38) { - return effects.check( - namedCharacterReference, - ok, - continuedPunctuation - )(code) - } - - if (code === 40) { - balance++; - } - - if (code === 41) { - return effects.check( - punctuation, - parenAtPathEnd, - continuedPunctuation - )(code) - } - - if (pathEnd(code)) { - return ok(code) - } - - if (trailingPunctuation(code)) { - return effects.check(punctuation, ok, continuedPunctuation)(code) - } - - effects.consume(code); - return inPath - } - /** @type {State} */ - - function continuedPunctuation(code) { - effects.consume(code); - return inPath - } - /** @type {State} */ - - function parenAtPathEnd(code) { - balance--; - return balance < 0 ? ok(code) : continuedPunctuation(code) - } -} -/** @type {Tokenizer} */ - -function tokenizeNamedCharacterReference(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.consume(code); - return inside - } - /** @type {State} */ - - function inside(code) { - if (asciiAlpha(code)) { - effects.consume(code); - return inside - } - - if (code === 59) { - effects.consume(code); - return after - } - - return nok(code) - } - /** @type {State} */ - - function after(code) { - // If the named character reference is followed by the end of the path, it’s - // not continued punctuation. - return pathEnd(code) ? ok(code) : nok(code) - } -} -/** @type {Tokenizer} */ - -function tokenizePunctuation(effects, ok, nok) { - return start - /** @type {State} */ - - function start(code) { - effects.consume(code); - return after - } - /** @type {State} */ - - function after(code) { - // Check the next. - if (trailingPunctuation(code)) { - effects.consume(code); - return after - } // If the punctuation marker is followed by the end of the path, it’s not - // continued punctuation. - - return pathEnd(code) ? ok(code) : nok(code) - } -} -/** - * @param {Code} code - * @returns {boolean} - */ - -function trailingPunctuation(code) { - return ( - code === 33 || - code === 34 || - code === 39 || - code === 41 || - code === 42 || - code === 44 || - code === 46 || - code === 58 || - code === 59 || - code === 60 || - code === 63 || - code === 95 || - code === 126 - ) -} -/** - * @param {Code} code - * @returns {boolean} - */ - -function pathEnd(code) { - return code === null || code === 60 || markdownLineEndingOrSpace(code) -} -/** - * @param {Code} code - * @returns {boolean} - */ - -function gfmAtext(code) { - return ( - code === 43 || - code === 45 || - code === 46 || - code === 95 || - asciiAlphanumeric(code) - ) -} -/** @type {Previous} */ - -function previousWww(code) { - return ( - code === null || - code === 40 || - code === 42 || - code === 95 || - code === 126 || - markdownLineEndingOrSpace(code) - ) -} -/** @type {Previous} */ - -function previousHttp(code) { - return code === null || !asciiAlpha(code) -} -/** @type {Previous} */ - -function previousEmail(code) { - return code !== 47 && previousHttp(code) -} -/** - * @param {Event[]} events - * @returns {boolean} - */ - -function previousUnbalanced(events) { - let index = events.length; - let result = false; - - while (index--) { - const token = events[index][1]; - - if ( - (token.type === 'labelLink' || token.type === 'labelImage') && - !token._balanced - ) { - result = true; - break - } // @ts-expect-error If we’ve seen this token, and it was marked as not - // having any unbalanced bracket before it, we can exit. - - if (token._gfmAutolinkLiteralWalkedInto) { - result = false; - break - } - } - - if (events.length > 0 && !result) { - // @ts-expect-error Mark the last token as “walked into” w/o finding - // anything. - events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true; - } - - return result -} - -const characterReferences = {'"': 'quot', '&': 'amp', '<': 'lt', '>': 'gt'}; - -/** - * Encode only the dangerous HTML characters. - * - * This ensures that certain characters which have special meaning in HTML are - * dealt with. - * Technically, we can skip `>` and `"` in many cases, but CM includes them. - * - * @param {string} value - * @returns {string} - */ -function encode(value) { - return value.replace(/["&<>]/g, replace) - - /** - * @param {string} value - * @returns {string} - */ - function replace(value) { - // @ts-expect-error Hush, it’s fine. - return '&' + characterReferences[value] + ';' - } -} - -/** - * Make a value safe for injection as a URL. - * - * This encodes unsafe characters with percent-encoding and skips already - * encoded sequences (see `normalizeUri` below). - * Further unsafe characters are encoded as character references (see - * `micromark-util-encode`). - * - * Then, a regex of allowed protocols can be given, in which case the URL is - * sanitized. - * For example, `/^(https?|ircs?|mailto|xmpp)$/i` can be used for `a[href]`, - * or `/^https?$/i` for `img[src]`. - * If the URL includes an unknown protocol (one not matched by `protocol`, such - * as a dangerous example, `javascript:`), the value is ignored. - * - * @param {string|undefined} url - * @param {RegExp} [protocol] - * @returns {string} - */ -function sanitizeUri(url, protocol) { - const value = encode(normalizeUri(url || '')); - - if (!protocol) { - return value - } - - const colon = value.indexOf(':'); - const questionMark = value.indexOf('?'); - const numberSign = value.indexOf('#'); - const slash = value.indexOf('/'); - - if ( - // If there is no protocol, it’s relative. - colon < 0 || // If the first colon is after a `?`, `#`, or `/`, it’s not a protocol. - (slash > -1 && colon > slash) || - (questionMark > -1 && colon > questionMark) || - (numberSign > -1 && colon > numberSign) || // It is a protocol, it should be allowed. - protocol.test(value.slice(0, colon)) - ) { - return value - } - - return '' -} -/** - * Normalize a URL (such as used in definitions). - * - * Encode unsafe characters with percent-encoding, skipping already encoded - * sequences. - * - * @param {string} value - * @returns {string} - */ - -function normalizeUri(value) { - /** @type {string[]} */ - const result = []; - let index = -1; - let start = 0; - let skip = 0; - - while (++index < value.length) { - const code = value.charCodeAt(index); - /** @type {string} */ - - let replace = ''; // A correct percent encoded value. - - if ( - code === 37 && - asciiAlphanumeric(value.charCodeAt(index + 1)) && - asciiAlphanumeric(value.charCodeAt(index + 2)) - ) { - skip = 2; - } // ASCII. - else if (code < 128) { - if (!/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(code))) { - replace = String.fromCharCode(code); - } - } // Astral. - else if (code > 55295 && code < 57344) { - const next = value.charCodeAt(index + 1); // A correct surrogate pair. - - if (code < 56320 && next > 56319 && next < 57344) { - replace = String.fromCharCode(code, next); - skip = 1; - } // Lone surrogate. - else { - replace = '\uFFFD'; - } - } // Unicode. - else { - replace = String.fromCharCode(code); - } - - if (replace) { - result.push(value.slice(start, index), encodeURIComponent(replace)); - start = index + skip + 1; - replace = ''; - } - - if (skip) { - index += skip; - skip = 0; - } - } - - return result.join('') + value.slice(start) -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - * @typedef {import('micromark-util-types').Handle} Handle - * @typedef {import('micromark-util-types').CompileContext} CompileContext - * @typedef {import('micromark-util-types').Token} Token - */ -/** @type {HtmlExtension} */ - -const gfmAutolinkLiteralHtml = { - exit: { - literalAutolinkEmail, - literalAutolinkHttp, - literalAutolinkWww - } -}; -/** @type {Handle} */ - -function literalAutolinkWww(token) { - anchorFromToken.call(this, token, 'http://'); -} -/** @type {Handle} */ - -function literalAutolinkEmail(token) { - anchorFromToken.call(this, token, 'mailto:'); -} -/** @type {Handle} */ - -function literalAutolinkHttp(token) { - anchorFromToken.call(this, token); -} -/** - * @this CompileContext - * @param {Token} token - * @param {string} [protocol] - * @returns {void} - */ - -function anchorFromToken(token, protocol) { - const url = this.sliceSerialize(token); - this.tag(''); - this.raw(this.encode(url)); - this.tag(''); -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -/** @type {HtmlExtension} */ -const gfmStrikethroughHtml = { - enter: { - strikethrough() { - this.tag(''); - } - }, - exit: { - strikethrough() { - this.tag(''); - } - } -}; - -/** - * @typedef {import('micromark-util-types').Extension} Extension - * @typedef {import('micromark-util-types').Resolver} Resolver - * @typedef {import('micromark-util-types').Tokenizer} Tokenizer - * @typedef {import('micromark-util-types').State} State - * @typedef {import('micromark-util-types').Token} Token - * @typedef {import('micromark-util-types').Event} Event - */ - -/** - * @param {Options} [options] - * @returns {Extension} - */ -function gfmStrikethrough(options = {}) { - let single = options.singleTilde; - const tokenizer = { - tokenize: tokenizeStrikethrough, - resolveAll: resolveAllStrikethrough - }; - - if (single === null || single === undefined) { - single = true; - } - - return { - text: { - [126]: tokenizer - }, - insideSpan: { - null: [tokenizer] - }, - attentionMarkers: { - null: [126] - } - } - /** - * Take events and resolve strikethrough. - * - * @type {Resolver} - */ - - function resolveAllStrikethrough(events, context) { - let index = -1; - /** @type {Token} */ - - let strikethrough; - /** @type {Token} */ - - let text; - /** @type {number} */ - - let open; - /** @type {Event[]} */ - - let nextEvents; // Walk through all events. - - while (++index < events.length) { - // Find a token that can close. - if ( - events[index][0] === 'enter' && - events[index][1].type === 'strikethroughSequenceTemporary' && - events[index][1]._close - ) { - open = index; // Now walk back to find an opener. - - while (open--) { - // Find a token that can open the closer. - if ( - events[open][0] === 'exit' && - events[open][1].type === 'strikethroughSequenceTemporary' && - events[open][1]._open && // If the sizes are the same: - events[index][1].end.offset - events[index][1].start.offset === - events[open][1].end.offset - events[open][1].start.offset - ) { - events[index][1].type = 'strikethroughSequence'; - events[open][1].type = 'strikethroughSequence'; - strikethrough = { - type: 'strikethrough', - start: Object.assign({}, events[open][1].start), - end: Object.assign({}, events[index][1].end) - }; - text = { - type: 'strikethroughText', - start: Object.assign({}, events[open][1].end), - end: Object.assign({}, events[index][1].start) - }; // Opening. - - nextEvents = [ - ['enter', strikethrough, context], - ['enter', events[open][1], context], - ['exit', events[open][1], context], - ['enter', text, context] - ]; // Between. - - splice( - nextEvents, - nextEvents.length, - 0, - resolveAll( - context.parser.constructs.insideSpan.null, - events.slice(open + 1, index), - context - ) - ); // Closing. - - splice(nextEvents, nextEvents.length, 0, [ - ['exit', text, context], - ['enter', events[index][1], context], - ['exit', events[index][1], context], - ['exit', strikethrough, context] - ]); - splice(events, open - 1, index - open + 3, nextEvents); - index = open + nextEvents.length - 2; - break - } - } - } - } - - index = -1; - - while (++index < events.length) { - if (events[index][1].type === 'strikethroughSequenceTemporary') { - events[index][1].type = 'data'; - } - } - - return events - } - /** @type {Tokenizer} */ - - function tokenizeStrikethrough(effects, ok, nok) { - const previous = this.previous; - const events = this.events; - let size = 0; - return start - /** @type {State} */ - - function start(code) { - if ( - code !== 126 || - (previous === 126 && - events[events.length - 1][1].type !== 'characterEscape') - ) { - return nok(code) - } - - effects.enter('strikethroughSequenceTemporary'); - return more(code) - } - /** @type {State} */ - - function more(code) { - const before = classifyCharacter(previous); - - if (code === 126) { - // If this is the third marker, exit. - if (size > 1) return nok(code) - effects.consume(code); - size++; - return more - } - - if (size < 2 && !single) return nok(code) - const token = effects.exit('strikethroughSequenceTemporary'); - const after = classifyCharacter(code); - token._open = !after || (after === 2 && Boolean(before)); - token._close = !before || (before === 2 && Boolean(after)); - return ok(code) - } - } -} - -/** - * @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension - */ - -/** - * @typedef {import('./syntax.js').Align} Align - */ -const alignment = { - null: '', - left: ' align="left"', - right: ' align="right"', - center: ' align="center"' -}; -/** @type {HtmlExtension} */ - -const gfmTableHtml = { - enter: { - table(token) { - this.lineEndingIfNeeded(); - this.tag('
'); // @ts-expect-error Custom. - - this.setData('tableAlign', token._align); - }, - - tableBody() { - // Clear slurping line ending from the delimiter row. - this.setData('slurpOneLineEnding'); - this.tag(''); - }, - - tableData() { - /** @type {string|undefined} */ - const align = // @ts-expect-error Custom. - alignment[this.getData('tableAlign')[this.getData('tableColumn')]]; - - if (align === undefined) { - // Capture results to ignore them. - this.buffer(); - } else { - this.lineEndingIfNeeded(); - this.tag(''); - } - }, - - tableHead() { - this.lineEndingIfNeeded(); - this.tag(''); - }, - - tableHeader() { - this.lineEndingIfNeeded(); - this.tag( - '' - ); - }, - - tableRow() { - this.setData('tableColumn', 0); - this.lineEndingIfNeeded(); - this.tag(''); - } - }, - exit: { - // Overwrite the default code text data handler to unescape escaped pipes when - // they are in tables. - codeTextData(token) { - let value = this.sliceSerialize(token); - - if (this.getData('tableAlign')) { - value = value.replace(/\\([\\|])/g, replace$1); - } - - this.raw(this.encode(value)); - }, - - table() { - this.setData('tableAlign'); // If there was no table body, make sure the slurping from the delimiter row - // is cleared. - - this.setData('slurpAllLineEndings'); - this.lineEndingIfNeeded(); - this.tag('
'); - }, - - tableBody() { - this.lineEndingIfNeeded(); - this.tag('
'); // @ts-expect-error Custom. + + this.setData('tableAlign', token._align); + }, + + tableBody() { + // Clear slurping line ending from the delimiter row. + this.setData('slurpOneLineEnding'); + this.tag(''); + }, + + tableData() { + /** @type {string|undefined} */ + const align = // @ts-expect-error Custom. + alignment[this.getData('tableAlign')[this.getData('tableColumn')]]; + + if (align === undefined) { + // Capture results to ignore them. + this.buffer(); + } else { + this.lineEndingIfNeeded(); + this.tag(''); + } + }, + + tableHead() { + this.lineEndingIfNeeded(); + this.tag(''); + }, + + tableHeader() { + this.lineEndingIfNeeded(); + this.tag( + '' + ); + }, + + tableRow() { + this.setData('tableColumn', 0); + this.lineEndingIfNeeded(); + this.tag(''); + } + }, + exit: { + // Overwrite the default code text data handler to unescape escaped pipes when + // they are in tables. + codeTextData(token) { + let value = this.sliceSerialize(token); + + if (this.getData('tableAlign')) { + value = value.replace(/\\([\\|])/g, replace$1); + } + + this.raw(this.encode(value)); + }, + + table() { + this.setData('tableAlign'); // If there was no table body, make sure the slurping from the delimiter row + // is cleared. + + this.setData('slurpAllLineEndings'); + this.lineEndingIfNeeded(); + this.tag('
'); + }, + + tableBody() { + this.lineEndingIfNeeded(); + this.tag('