[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2\njobs:\n  build:\n    docker:\n      - image: cimg/node:14.18.0\n\n    working_directory: ~/repo\n\n    steps:\n      - checkout\n\n      - restore_cache:\n          keys:\n            - v1-dependencies-{{ checksum \"package.json\" }}\n            - v1-dependencies-\n\n      - run: yarn install\n\n      - save_cache:\n          paths:\n            - node_modules\n          key: v1-dependencies-{{ checksum \"package.json\" }}\n\n      - run: yarn run test:ci\n      - run: yarn run lint\n"
  },
  {
    "path": ".eslintignore",
    "content": "lib/prepareMarkdown.mjs\nsrc/utils/prepareMarkdown.js\nsrc/utils/findUpSync.js\n*/**/*.d.ts"
  },
  {
    "path": ".eslintrc.json",
    "content": "{\n  \"extends\": [\"airbnb\", \"prettier\"],\n  \"rules\": {\n    \"no-console\": 0,\n    \"arrow-body-style\": 0,\n    \"no-restricted-syntax\": 0,\n    \"no-await-in-loop\": 0,\n    \"camelcase\": 0\n  },\n  \"env\": {\n    \"jest\": true,\n    \"node\": true\n  },\n  \"globals\": {\n    \"fetch\": true\n  }\n}\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: bug\nassignees: caderek\n\n---\n\n**Describe the bug**\nA clear and concise description of what the bug is.\n\n**To Reproduce**\nSteps to reproduce the behavior.\n\n**Expected behavior**\nA clear and concise description of what you expected to happen.\n\n**Screenshots**\nIf applicable, add screenshots to help explain your problem.\n\n**Desktop (please complete the following information):**\n - OS: [e.g. Linux, macOS, Windows]\n - Browser [e.g. Ubunto 18.04, Mojave, 10]\n\n**Additional context**\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/documentation.md",
    "content": "---\nname: Documentation\nabout: All docs related issues\ntitle: ''\nlabels: documentation\nassignees: caderek\n\n---\n\n**Describe what is missing, unclear or incorrect**\nA clear and concise description of what you want us to change/add.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: enhancement\nassignees: caderek\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "content": "---\nname: Question\nabout: All questions that do not require changes to the codebase\ntitle: ''\nlabels: help wanted\nassignees: caderek\n\n---\n\n**How can I help you?**\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\n.history\n.vscode\nexample-responses\nexample.txt\ncoverage\nbin\nassets/css/*.css\nassets/css/*.css.map"
  },
  {
    "path": ".gramma.json",
    "content": "{\n  \"api_url\": \"https://api.languagetool.org/v2/check\",\n  \"api_key\": \"\",\n  \"dictionary\": [\n    \"Asturian\",\n    \"Bugfix\",\n    \"CHANGELOG\",\n    \"CircleCI\",\n    \"Codacy\",\n    \"CommonJS\",\n    \"Config\",\n    \"Github\",\n    \"Gramma\",\n    \"Grammarbot\",\n    \"IIFE\",\n    \"JS\",\n    \"Moçambique\",\n    \"NPM\",\n    \"README\",\n    \"XXXXXXXX\",\n    \"YYYYYYYY\",\n    \"_blank\",\n    \"api\",\n    \"api_key\",\n    \"ast-ES\",\n    \"async\",\n    \"backend\",\n    \"boolean\",\n    \"br-FR\",\n    \"chmod\",\n    \"config\",\n    \"confused_words\",\n    \"const\",\n    \"correctText\",\n    \"da-DK\",\n    \"de\",\n    \"de-AT\",\n    \"de-CH\",\n    \"de-DE\",\n    \"dev\",\n    \"el-GR\",\n    \"eo\",\n    \"eslintignore\",\n    \"esm\",\n    \"esm-min\",\n    \"exampleReplacements\",\n    \"false_friends\",\n    \"foo\",\n    \"fr\",\n    \"gender_neutrality\",\n    \"gl-ES\",\n    \"gramma\",\n    \"grammarbot\",\n    \"gui\",\n    \"href\",\n    \"iife\",\n    \"img\",\n    \"init\",\n    \"io\",\n    \"ja-JP\",\n    \"js\",\n    \"json\",\n    \"km-KH\",\n    \"linter\",\n    \"nl\",\n    \"npm\",\n    \"npmignore\",\n    \"pid\",\n    \"preAO\",\n    \"prepareReplacements\",\n    \"replaceAll\",\n    \"rimraf\",\n    \"ro-RO\",\n    \"ru-RU\",\n    \"signup\",\n    \"sk-SK\",\n    \"sl-SI\",\n    \"src\",\n    \"stdin\",\n    \"stdout\",\n    \"stylesheet\",\n    \"sv\",\n    \"symlink\",\n    \"tl-PH\",\n    \"uk-UA\",\n    \"url\",\n    \"usedCfg\",\n    \"zh-CN\"\n  ],\n  \"language\": \"en-US\",\n  \"rules\": {\n    \"casing\": true,\n    \"colloquialisms\": true,\n    \"compounding\": true,\n    \"confused_words\": true,\n    \"false_friends\": true,\n    \"gender_neutrality\": true,\n    \"grammar\": true,\n    \"misc\": true,\n    \"punctuation\": true,\n    \"redundancy\": true,\n    \"regionalisms\": true,\n    \"repetitions\": true,\n    \"semantics\": true,\n    \"style\": true,\n    \"typography\": false,\n    \"typos\": true\n  }\n}\n"
  },
  {
    "path": ".husky/commit-msg",
    "content": "#!/bin/sh\n\nexec < /dev/tty\n\nnpx gramma hook $1\n"
  },
  {
    "path": ".husky/post-commit",
    "content": "#!/bin/sh\n\nnpx gramma hook cleanup\n"
  },
  {
    "path": ".husky/pre-commit",
    "content": "#!/bin/sh\n. \"$(dirname \"$0\")/_/husky.sh\"\n\nnpm test\n"
  },
  {
    "path": ".npmignore",
    "content": "_layouts\nnode_modules\n.history\n.circleci\nexample-responses\nexample.txt\ncoverage\nbin\n.husky\n.github\n.vscode\nlib\nassets/css\nassets/gramma-logo.svg\nassets/gramma-text.svg\nassets/banner.png\nassets/banner-small.png\nscripts\nexamples"
  },
  {
    "path": ".prettierrc",
    "content": "{\n  \"trailingComma\": \"all\",\n  \"tabWidth\": 2,\n  \"semi\": false,\n  \"singleQuote\": false,\n  \"arrowParens\": \"always\",\n  \"printWidth\": 80\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# CHANGELOG\n\n## 1.0.0\n\nFirst stable release.\n\n## 1.1.0\n\n- Added Git hook integration\n- Updated dependencies and documentation\n- Improved error handling\n\n## 1.2.0\n\n- Added Markdown support\n- Used api.languagetool.org as the default API\n\n## 1.3.0\n\n- Support for environment variables in config files\n- Local config works in subdirectories\n- Automatic markdown support for .md files\n- Better error handling\n- Improved documentation\n\n## 1.4.0\n\n- Automatically include changes to .gramma.json when executing Git hook\n- Standalone binaries migrated to Node 16\n\n## 1.4.1\n\n- Fixed JS API, added type definitions\n- Fixed hooks behavior with commit --verbose flag\n\n## 1.4.2 - 1.4.4\n\n- Isomorphic JS API (works on browser)\n\n## 1.4.5\n\n- Fixed CORS in JS API (browser)\n\n## 1.4.6 - 1.4.7\n\n- Bundles (esm, esm-min, iife)\n\n## 1.4.8\n\n- Fixed links in README\n\n## 1.5.0\n\n- When local server is installed but not running, Gramma will now try to use command-line interface for LanguageTool communication instead of spawning HTTP server (if possible).\n- Gramma will now automatically check for updates once a day.\n- Added validation for languages and rules parameters.\n\n## 1.6.0\n\n- Added `gramma server info` command.\n- Added option to set custom port when managing local server manually.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Copyright 2021 Maciej Cąderek\n\nPermission to use, copy, modify, and/or distribute this software\nfor any purpose with or without fee is hereby granted,\nprovided that the above copyright notice\nand this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES\nOF MERCHANTABILITY AND FITNESS.\nIN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,\nOR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,\nDATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,\nNEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n    <img src=\"assets/gramma-logo.png\" alt=\"gramma-logo\" />\n</div>\n<div align=\"center\">\n    <img src=\"assets/gramma-text.png\" alt=\"gramma-title\" />\n</div>\n\n<!-- Gramma is an interactive tool that helps you find and fix grammatical mistakes in files and text strings. You can also use it in a non-interactive way, as a simple linter for automation processes.\n\nGramma works on Linux, Windows, and macOS.\n\nGramma supports many languages. You can find a full list <a href=\"https://languagetool.org/languages\">here</a>.\n\nGramma works out-of-the-box, communicating with [languagetool.org](https://languagetool.org), but can also be easily configured to work with other compatible APIs, including local or remote [LanguageTool server](https://dev.languagetool.org/http-server). -->\n\n<div>&nbsp;</div>\n\n<div align=\"center\">\n<a href=\"https://circleci.com/gh/caderek/gramma/tree/master\" target=\"_blank\"><img src=\"https://img.shields.io/circleci/build/github/caderek/gramma.svg?labelColor=024160\" alt=\"CircleCI\"></a>\n<img src=\"https://img.shields.io/npm/v/gramma.svg?labelColor=024160&color=0081B8\" alt=\"npm version\">\n<img src=\"https://img.shields.io/node/v/gramma.svg?labelColor=024160&color=0081B8\" alt=\"node version\">\n<img src=\"https://img.shields.io/npm/l/gramma.svg?labelColor=024160&color=0081B8\" alt=\"npm license\">\n</div>\n \n<div>&nbsp;</div>\n\n<div align=\"center\">\n<img src=\"docs/example.gif\" alt=\"Example\" style=\"border-radius: 10px;\">\n</div>\n\n<div>&nbsp;</div>\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## Features\n\n- Provides advanced grammar checks via LanguageTool (remote API or local server).\n- Supports global and local (per-project) configuration.\n- Supports plain text and markdown.\n- Git integration!\n- Fully interactive!\n\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## Contents\n\n1. [Installation](#installation)\n   - [Via NPM (global)](#installation-npm)\n   - [Standalone binary](#installation-binary)\n   - [Dev tool for JS/TS projects](#installation-dev)\n   - [Local LanguageTool server (optional)](#installation-server)\n1. [Usage](#usage)\n   - [Check file](#usage-check)\n   - [Check string](#usage-listen)\n   - [Git commit with grammar check](#usage-commit)\n   - [Command-line options](#usage-options)\n   - [Usage inside VIM](#usage-vim)\n1. [Configuration](#config)\n   - [Introduction](#config-intro)\n   - [Local config](#config-local)\n   - [Git integration](#config-git)\n   - [Checker settings](#config-checker)\n   - [Customizing API server](#config-server)\n   - [Security](#config-security)\n1. [Managing a local server](#server)\n1. [JS API](#js)\n1. [License](#license)\n\n<a id='installation'></a>\n\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## Installation\n\n<a id='installation-npm'></a>\n\n### Via NPM\n\nIt is the recommended way if you have Node.js already installed (or you are willing to do so).\n\n```\nnpm i gramma -g\n```\n\n<hr/>\n\n<a id='installation-binary'></a>\n\n### Standalone binary\n\nIf you prefer a single binary file, you can download it for the most popular platforms:\n\n- [gramma-linux64-v1.6.0.zip](https://github.com/caderek/gramma/releases/download/v1.6.0/gramma-linux64-v1.6.0.zip)\n- [gramma-macos-v1.6.0.zip](https://github.com/caderek/gramma/releases/download/v1.6.0/gramma-macos-v1.6.0.zip)\n- [gramma-windows64-v1.6.0.zip](https://github.com/caderek/gramma/releases/download/v1.6.0/gramma-windows64-v1.6.0.zip)\n\nAfter downloading and unpacking the binary, add it to your PATH or create a symlink to your executable directory (depending on the platform).\n\n<hr/>\n\n<a id='installation-dev'></a>\n\n### Dev tool for JS/TS projects\n\nYou can install Gramma locally for your JS/TS project - this method gives you a separate, project specific config.\n\n```\nnpm i gramma -D\n```\n\nor\n\n```\nyarn add gramma -D\n```\n\nThen create the local config file:\n\n```\nnpx gramma init\n```\n\nYou will be asked if you want to integrate Gramma with Git (via hook). You can later manually toggle git hook via `npx gramma hook` command.\n\nGit hook also works with a non-default hooks path (Husky, etc.).\n\n<hr/>\n\n<a id='installation-server'></a>\n\n### Local LanguageTool server (optional)\n\nFor this to work, you have to install Java 1.8 or higher (you can find it [here](https://adoptium.net)). You can check if you have it installed already by running:\n\n```\njava -version\n```\n\nTo install the local server, use:\n\n```\ngramma server install\n```\n\nThat's it - Gramma will now use and manage the local server automatically.\n\n<a id='usage'></a>\n\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## Usage\n\n<a id='usage-check'></a>\n\n### Check file\n\nInteractive fix:\n\n```\ngramma check [file]\n```\n\nJust print potential mistakes and return status code:\n\n```\ngramma check -p [file]\n```\n\nExamples:\n\n```\ngramma check path/to/my_file.txt\n```\n\n```\ngramma check -p path/to/other/file.txt\n```\n\n<hr/>\n\n<a id='usage-listen'></a>\n\n### Check string\n\nInteractive fix:\n\n```\ngramma listen [text]\n```\n\nJust print potential mistakes and return status code:\n\n```\ngramma listen -p [text]\n```\n\nExamples:\n\n```\ngramma listen \"This sentence will be checked interactively.\"\n```\n\n```\ngramma listen -p \"Suggestions for this sentence will be printed.\"\n```\n\n<hr/>\n\n<a id='usage-commit'></a>\n\n### Git commit with grammar check\n\n_**TIP:** Instead of the commands below, you can use [Git integration](#config-git)._\n\nEquivalent to `git commit -m [message]`:\n\n```\ngramma commit [text]\n```\n\nEquivalent to `git commit -am [message]`:\n\n```\ngramma commit -a [text]\n```\n\nExamples:\n\n```\ngramma commit \"My commit message\"\n```\n\n```\ngramma commit -a \"Another commit message (files added)\"\n```\n\n<hr/>\n\n<a id='usage-options'></a>\n\n### Command-line options\n\n_Note: This section describes options for grammar-checking commands only. Other command-specific options are described in their specific sections of this document._\n\n- `-p / --print` - check text in the non-interactive mode\n- `-n / --no-colors` - when paired with the `-p` flag, removes colors from the output\n- `-d / --disable <rule>` - disable specific [rule](#available-rules)\n- `-e / --enable <rule>` - enable specific [rule](#available-rules)\n- `-l / --language <language_code>` - mark a text as written in provided [language](#available-languages)\n- `-m / --markdown` - treat the input as markdown (removes some false-positives)\n\nYou can enable or disable multiple rules in one command by using a corresponding option multiple times. You can also compound boolean options if you use their short version.\n\nExample:\n\n```\ngramma listen \"I like making mistkaes!\" -pn -d typos -d typography -e casing -l en-GB\n```\n\n<hr/>\n\n<a id='usage-vim'></a>\n\n### Usage inside VIM\n\nIf you are a VIM/Neovim user, you can use Gramma directly inside the editor:\n\nPrint the potential mistakes:\n\n```\n:w !gramma check /dev/stdin -pn\n```\n\nInteractive fix of the current file:\n\n```\n:terminal gramma check %\n```\n\nIt will open the interactive terminal inside VIM - to handle Gramma suggestions, enter the interactive mode (`a` or `i`) and use Gramma as usual. After you fix the mistakes and replace a file, press `Enter` to return to the editor.\n\n<details>\n  <summary style=\"outline: none; cursor: pointer\">Example GIF (click to expand)</summary>\n  <img src=\"https://raw.githubusercontent.com/caderek/gramma/master/docs/gramma-vim.gif\" alt=\"Gramma VIM example\" />\n</details>\n\n<a id='config'></a>\n\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## Configuration\n\n<a id='config-intro'></a>\n\n### Introduction\n\nWith Gramma, you can use a global and local configuration file. Gramma will use a proper config file following their priority:\n\n1. Command-line options\n2. Local config\n3. Global config\n\nGramma will automatically generate a global configuration file on the first run.\n\nYou can check the path to the global configuration file (as well as other paths used by Gramma) via the following command:\n\n```\ngramma paths\n```\n\nYou can change your settings by manually editing configuration files or running:\n\n```\ngramma config <setting> <value> [-g]\n```\n\n_Note: `-g` (`--global`) flag should be used when you want to alter the global config._\n\n<hr/>\n\n<a id='config-local'></a>\n\n### Local config\n\nYou can initialize local config by running the following command in your project's root directory:\n\n```\ngramma init\n```\n\nGramma creates the local configuration file in your working directory under `.gramma.json` name.\n\n<hr/>\n\n<a id='config-git'></a>\n\n### Git integration\n\nYou can toggle Git hook via:\n\n```\ngramma hook\n```\n\nIt will add/remove an entry in `commit-msg` hook.\n\nGramma follows the Git configuration file, so it should work with a non-standard hooks location.\n\n<hr/>\n\n<a id='config-checker'></a>\n\n### Checker settings\n\n#### Adding a word to the dictionary\n\nUsually, you will add custom words to the local or global dictionary via interactive menu during the fix process, but you can also make it via separate command:\n\n```\ngramma config dictionary <your_word> [-g]\n```\n\nExamples:\n\n```\ngramma config dictionary aws\ngramma config dictionary figma -g\n```\n\n#### Changing default language\n\n```\ngramma config language <language_code> [-g]\n```\n\nExamples:\n\n```\ngramma config language en-GB\ngramma config language pl-PL -g\n```\n\n<a id=\"available-languages\"></a>\n\n<details>\n  <summary style=\"outline: none; cursor: pointer\">Available languages (click to expand)</summary>\n  <table>\n      <tr>\n        <th>Code</th>\n        <th>Name</th>\n        <th>languagetool.org</th>\n        <th>grammarbot.io</th>\n        <th>local</th>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">auto</tt></td>\n        <td>automatic language detection</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <!--LANG-->\n      <tr>\n        <td><tt style=\"white-space: pre;\">ar</tt></td>\n        <td>Arabic</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ast-ES</tt></td>\n        <td>Asturian</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">be-BY</tt></td>\n        <td>Belarusian</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">br-FR</tt></td>\n        <td>Breton</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ca-ES</tt></td>\n        <td>Catalan</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ca-ES-valencia</tt></td>\n        <td>Catalan (Valencian)</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">zh-CN</tt></td>\n        <td>Chinese</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">da-DK</tt></td>\n        <td>Danish</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">nl</tt></td>\n        <td>Dutch</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">nl-BE</tt></td>\n        <td>Dutch (Belgium)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">en</tt></td>\n        <td>English</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">en-AU</tt></td>\n        <td>English (Australian)</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">en-CA</tt></td>\n        <td>English (Canadian)</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">en-GB</tt></td>\n        <td>English (GB)</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">en-NZ</tt></td>\n        <td>English (New Zealand)</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">en-ZA</tt></td>\n        <td>English (South African)</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">en-US</tt></td>\n        <td>English (US)</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">eo</tt></td>\n        <td>Esperanto</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">fr</tt></td>\n        <td>French</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">gl-ES</tt></td>\n        <td>Galician</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">de</tt></td>\n        <td>German</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">de-AT</tt></td>\n        <td>German (Austria)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">de-DE</tt></td>\n        <td>German (Germany)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">de-CH</tt></td>\n        <td>German (Swiss)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">el-GR</tt></td>\n        <td>Greek</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ga-IE</tt></td>\n        <td>Irish</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">it</tt></td>\n        <td>Italian</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ja-JP</tt></td>\n        <td>Japanese</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">km-KH</tt></td>\n        <td>Khmer</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">fa</tt></td>\n        <td>Persian</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">pl-PL</tt></td>\n        <td>Polish</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">pt</tt></td>\n        <td>Portuguese</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">pt-AO</tt></td>\n        <td>Portuguese (Angola preAO)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">pt-BR</tt></td>\n        <td>Portuguese (Brazil)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">pt-MZ</tt></td>\n        <td>Portuguese (Moçambique preAO)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">pt-PT</tt></td>\n        <td>Portuguese (Portugal)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ro-RO</tt></td>\n        <td>Romanian</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ru-RU</tt></td>\n        <td>Russian</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">de-DE-x-simple-language</tt></td>\n        <td>Simple German</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">sk-SK</tt></td>\n        <td>Slovak</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">sl-SI</tt></td>\n        <td>Slovenian</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">es</tt></td>\n        <td>Spanish</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">es-AR</tt></td>\n        <td>Spanish (voseo)</td>\n        <td>✔</td>\n        <td>-</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">sv</tt></td>\n        <td>Swedish</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">tl-PH</tt></td>\n        <td>Tagalog</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">ta-IN</tt></td>\n        <td>Tamil</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <tr>\n        <td><tt style=\"white-space: pre;\">uk-UA</tt></td>\n        <td>Ukrainian</td>\n        <td>✔</td>\n        <td>✔</td>\n        <td>✔</td>\n      </tr>\n      <!--/LANG-->\n  </table>\n</details>\n\n_Note: By default, Gramma uses US English (`en-US`)._\n\n#### Enabling and disabling rules\n\nEnabling a specific rule:\n\n```\ngramma config enable <rule_name> [-g]\n```\n\nDisabling a specific rule:\n\n```\ngramma config disable <rule_name> [-g]\n```\n\nExamples:\n\n```\ngramma config enable punctuation\ngramma config enable casing -g\n\ngramma config disable typography\ngramma config disable style -g\n```\n\n<a id=\"available-rules\"></a>\n\n<details>\n  <summary style=\"outline: none; cursor: pointer\">Available rules (click to expand)</summary>\n  <table>\n    <tr><th>Rule</th><th>Description</th></tr>\n    <tr><td><tt style=\"white-space: pre;\">casing</tt></td><td>Rules about detecting uppercase words where lowercase is required and vice versa.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">colloquialisms</tt></td><td>Colloquial style.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">compounding</tt></td><td>Rules about spelling terms as one word or as as separate words.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">confused_words</tt></td><td>Words that are easily confused, like 'there' and 'their' in English.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">false_friends</tt></td><td>False friends: words easily confused by language learners because a similar word exists in their native language.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">gender_neutrality</tt></td><td>Helps to ensure gender-neutral terms.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">grammar</tt></td><td>Basic grammar check.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">misc</tt></td><td>Miscellaneous rules that don't fit elsewhere.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">punctuation</tt></td><td>Punctuation mistakes.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">redundancy</tt></td><td>Redundant words.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">regionalisms</tt></td><td>Regionalisms: words used only in another language variant or used with different meanings.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">repetitions</tt></td><td>Repeated words.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">semantics</tt></td><td>Logic, content, and consistency problems.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">style</tt></td><td>General style issues not covered by other categories, like overly verbose wording.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">typography</tt></td><td>Problems like incorrectly used dash or quote characters.</td></tr>\n    <tr><td><tt style=\"white-space: pre;\">typos</tt></td><td>Spelling issues.</td></tr>\n  </table>\n</details>\n\n_Note: By default, all rules are enabled._\n\n<hr/>\n\n<a id='config-server'></a>\n\n### Customizing API server\n\n#### Defining custom API endpoint\n\nIf you want to use remote LanguageTool server, or use the one already installed in your system (not installed via `gramma server install`), you can define a custom API endpoint:\n\n```\ngramma config api_url <custom_api_endpoint> [-g]\n```\n\nExamples:\n\n```\ngramma config api_url https://my-custom-api-url.xyz/v2/check\ngramma config api_url http://localhost:8081/v2/check -g\n```\n\n#### Running local server only when needed\n\nIf you do not want the local server to run all the time, you can configure Gramma to run it only when needed (`run → check → close`). It is useful when you run Gramma only from time to time and want to lower the memory consumption:\n\n```\ngramma config server_once true -g\n\n```\n\nRevert:\n\n```\ngramma config server_once false -g\n```\n\n#### Adding API key\n\nIf you use a paid option on [grammarbot.io](https://www.grammarbot.io/) or [languagetool.org](https://languagetool.org), you will receive an API key that you can use in Gramma:\n\n```\ngramma config api_key <your_api_key> [-g]\n```\n\n<hr/>\n\n<a id='config-security'></a>\n\n### Security\n\nIf you need to store some sensitive data in your local config file (API key etc.) you can use environment variables directly in the config file (supports `.env` files).\n\nExample:\n\n```json\n{\n  \"api_url\": \"https://my-language-tool-api.com/v2/check\",\n  \"api_key\": \"${MY_ENV_VARIABLE}\",\n  ...other_settings\n}\n```\n\n_Note: The default API (`api.languagetool.org`) is generally [safe and does not store your texts](https://languagetool.org/pl/legal/privacy), but if you want to be extra careful, you should use a [local server](#installation-server) or custom API endpoint._\n\n<a id='server'></a>\n\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## Managing a local server\n\nIf you have [configured a local server](#installation-server), Gramma will manage the server automatically - nevertheless, there might be situations when you want to manage the server manually. Gramma simplifies this by exposing basic server commands:\n\n#### Starting the server\n\n```\ngramma server start\n```\n\nYou can also specify a custom port:\n\n```\ngramma server start --port <port_number>\n```\n\n_Note: When you use this command, Gramma will ignore the `server_once` config option. This is expected behavior - I assume that if you use this command, you want the server to actually run, not stop after the first check._\n\n#### Stopping the server\n\n```\ngramma server stop\n```\n\n#### Getting the server info\n\n```\ngramma server info\n```\n\n#### Getting the server PID\n\n```\ngramma server pid\n```\n\n_Note: You can use `gramma server info` instead - this command is kept to not break backward compatibility._\n\n#### Opening the built-in GUI\n\n```\ngramma server gui\n```\n\n<a id='js'></a>\n\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## JS API\n\nIn addition to command-line usage, you can use two exposed methods if you want to handle mistakes by yourself.\n\n#### Imports\n\nIf you use Node.js or a bundler for your browser build, you can use CommonJS or esm:\n\n```js\nconst gramma = require(\"gramma\")\n```\n\n```js\nimport gramma from \"gramma\"\n```\n\nIf you don't use a bundler and want to use gramma in the browser, there are some prebuild packages in [/bundle](https://github.com/caderek/gramma/tree/master/bundle) directory:\n\n- `gramma.esm.js` - ES Modules bundle\n- `gramma.esm.min.js` - minified ES Modules bundle\n- `gramma.min.js` - IIFE bundle exposing global `gramma` variable\n\nYou can also import ESM bundle directly from CDN:\n\n```html\n<script type=\"module\">\n  import gramma from \"https://cdn.skypack.dev/gramma\"\n</script>\n```\n\n<hr/>\n\n#### check() method\n\nReturns a promise with a check result.\n\n```js\nconst gramma = require(\"gramma\")\n\ngramma.check(\"Some text to check.\").then(console.log)\n```\n\nYou can also pass a second argument - an options object. Available options:\n\n- `api_url` - url to a non-default API server\n- `api_key` - server API key\n- `dictionary` - an array of words that should be whitelisted\n- `language` - language code to specify the text language\n- `rules` - object defining which rules should be disabled\n\n<details>\n<summary style=\"outline: none; cursor: pointer\">Default options object (click to expand)</summary>\n<pre>\n{\n  \"api_url\": \"https://api.languagetool.org/v2/check\",\n  \"api_key\": \"\",\n  \"dictionary\": [],\n  \"language\": \"en-US\",\n  \"rules\": {\n    \"casing\": true,\n    \"colloquialisms\": true,\n    \"compounding\": true,\n    \"confused_words\": true,\n    \"false_friends\": true,\n    \"gender_neutrality\": true,\n    \"grammar\": true,\n    \"misc\": true,\n    \"punctuation\": true,\n    \"redundancy\": true,\n    \"regionalisms\": true,\n    \"repetitions\": true,\n    \"semantics\": true,\n    \"style\": true,\n    \"typography\": true,\n    \"typos\": true\n  }\n}\n</pre>\n</details>\n\nYou can find all available values for each setting in the [configuration section](#config) of this document.\n\nExample with all options set:\n\n```js\nconst gramma = require(\"gramma\")\n\ngramma\n  .check(\"Some text to check.\", {\n    api_url: \"http://my-custom-language-tool-server.xyz/v2/check\",\n    api_key: \"SOME_API_KEY\",\n    dictionary: [\"npm\", \"gramma\"],\n    language: \"pl-PL\",\n    rules: {\n      typography: false,\n      casing: false,\n    },\n  })\n  .then(console.log)\n```\n\n<hr/>\n\n#### replaceAll() method\n\nReplace words with provided ones. It takes an array of objects in the following format:\n\n```js\nconst exampleReplacements = [\n  { offset: 6, length: 3, change: \"correct phrase\" },\n  { offset: 20, length: 7, change: \"another phrase\" },\n]\n```\n\nYou can find proper `offset` and `length` values in the object returned by the `check()` method.\n\nExample usage:\n\n```js\nconst gramma = require(\"gramma\")\n\n/** Your custom function **/\nconst prepareReplacements = (matches) => {\n  // your code...\n}\n\nconst fix = async (text) => {\n  const { matches } = await gramma.check(text)\n  const replacements = prepareReplacements(matches)\n\n  return gramma.replaceAll(text, replacements)\n}\n\nconst main = () => {\n  const correctText = await fix(\"Some text to check\")\n  console.log(correctText)\n}\n\nmain()\n```\n\n<a id='license'></a>\n\n<div><img src=\"assets/divider.png\" width=\"838\" alt=\"---\" class=\"divider\" /></div>\n\n## License\n\nThe project is under open, non-restrictive [ISC license](https://github.com/caderek/gramma/blob/master/LICENSE.md).\n"
  },
  {
    "path": "_config.yml",
    "content": "theme: jekyll-theme-cayman"
  },
  {
    "path": "_layouts/default.html",
    "content": "<!DOCTYPE html>\n<html lang=\"{{ site.lang | default: \"en-US\" }}\">\n  <head>\n\n    {% if site.google_analytics %}\n      <script async src=\"https://www.googletagmanager.com/gtag/js?id={{ site.google_analytics }}\"></script>\n      <script>\n        window.dataLayer = window.dataLayer || [];\n        function gtag(){dataLayer.push(arguments);}\n        gtag('js', new Date());\n        gtag('config', '{{ site.google_analytics }}');\n      </script>\n    {% endif %}\n    <meta charset=\"UTF-8\">\n    <!-- Primary Meta Tags -->\n    <title>Gramma - command-line grammar checker</title>\n    <meta name=\"title\" content=\"Gramma - command-line grammar checker\">\n    <meta name=\"description\" content=\"Advanced, multilingual grammar checks interactively in your terminal!\">\n\n    <!-- Open Graph / Facebook -->\n    <meta property=\"og:type\" content=\"website\">\n    <meta property=\"og:url\" content=\"https://caderek.github.io/gramma/\">\n    <meta property=\"og:title\" content=\"Gramma - command-line grammar checker\">\n    <meta property=\"og:description\" content=\"Advanced, multilingual grammar checks interactively in your terminal!\">\n    <meta property=\"og:image\" content=\"https://caderek.github.io/gramma/assets/banner.png\">\n\n    <!-- Twitter -->\n    <meta property=\"twitter:card\" content=\"summary_large_image\">\n    <meta property=\"twitter:url\" content=\"https://caderek.github.io/gramma/\">\n    <meta property=\"twitter:title\" content=\"Gramma - command-line grammar checker\">\n    <meta property=\"twitter:description\" content=\"Advanced, multilingual grammar checks interactively in your terminal!\">\n    <meta property=\"twitter:image\" content=\"https://caderek.github.io/gramma/assets/banner.png\">\n\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <meta name=\"theme-color\" content=\"#157878\">\n    <meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">\n    <link rel=\"stylesheet\" href=\"{{ '/assets/css/style.css?v=' | append: site.github.build_revision | relative_url }}\">\n    <!-- <link rel=\"stylesheet\" href=\"/assets/css/style.css\"> -->\n    <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/gh/devicons/devicon@v2.14.0/devicon.min.css\">\n  </head>\n  <body>\n    <div class=\"version\">v1.6.0</div>\n    <header class=\"page-header\" role=\"banner\">\n      <a href=\"https://github.com/caderek/gramma\" class=\"download__link\">\n      <div class=\"download\">\n        <i class=\"devicon-github-original\"></i>\n        <p>View on GitHub</p>\n      </div>\n      </a>\n      <a href=\"https://www.npmjs.com/package/gramma\" class=\"download__link\">\n      <div class=\"download\">\n        <i class=\"devicon-npm-original-wordmark\"></i>\n        <p>View on NPM</p>\n      </div>\n      </a>\n      <a href=\"https://github.com/caderek/gramma/releases/download/v1.6.0/gramma-linux64-v1.6.0.zip\" class=\"download__link\">\n      <div class=\"download\">\n        <i class=\"devicon-linux-plain\"></i>\n        <p>Download for Linux</p>\n      </div>\n      </a>\n      <a href=\"https://github.com/caderek/gramma/releases/download/v1.6.0/gramma-windows64-v1.6.0.zip\" class=\"download__link\">\n      <div class=\"download\">\n        <i class=\"devicon-windows8-original\"></i>\n        <p>Download for Windows</p>\n      </div>\n      </a>\n      <a href=\"https://github.com/caderek/gramma/releases/download/v1.6.0/gramma-macos-v1.6.0.zip\" class=\"download__link\">\n      <div class=\"download\">\n        <i class=\"devicon-apple-original\"></i>\n        <p>Download for macOS</p>\n      </div>\n      </a>\n    </header>\n\n    <main id=\"content\" class=\"main-content\" role=\"main\">\n      <div class=\"actions\">\n        <a class=\"github-button\" href=\"https://github.com/caderek/gramma\" data-icon=\"octicon-star\" data-size=\"large\" data-show-count=\"true\" aria-label=\"Star caderek/gramma on GitHub\">Star</a>\n        <a class=\"github-button\" href=\"https://github.com/caderek/gramma/subscription\" data-icon=\"octicon-eye\" data-size=\"large\" data-show-count=\"true\" aria-label=\"Watch caderek/gramma on GitHub\">Watch</a>\n        <a class=\"github-button\" href=\"https://github.com/caderek/gramma/issues\" data-icon=\"octicon-issue-opened\" data-size=\"large\" data-show-count=\"true\" aria-label=\"Issue caderek/gramma on GitHub\">Issue</a>\n      </div>\n\n      {{ content }}\n\n      <div class=\"actions actions--bottom\">\n        <a class=\"github-button\" href=\"https://github.com/caderek/gramma\" data-icon=\"octicon-star\" data-size=\"large\" data-show-count=\"true\" aria-label=\"Star caderek/gramma on GitHub\">Star</a>\n        <a class=\"github-button\" href=\"https://github.com/caderek/gramma/subscription\" data-icon=\"octicon-eye\" data-size=\"large\" data-show-count=\"true\" aria-label=\"Watch caderek/gramma on GitHub\">Watch</a>\n        <a class=\"github-button\" href=\"https://github.com/caderek/gramma/issues\" data-icon=\"octicon-issue-opened\" data-size=\"large\" data-show-count=\"true\" aria-label=\"Issue caderek/gramma on GitHub\">Issue</a>\n      </div>\n\n      <footer class=\"site-footer\">\n        {% if site.github.is_project_page %}\n          <span class=\"site-footer-owner\"><a href=\"{{ site.github.repository_url }}\">{{ site.github.repository_name }}</a> is maintained by <a href=\"{{ site.github.owner_url }}\">{{ site.github.owner_name }}</a>.</span>\n        {% endif %}\n        <span class=\"site-footer-credits\">This page was generated by <a href=\"https://pages.github.com\">GitHub Pages</a>.</span>\n      </footer>\n    </main>\n    <script async defer src=\"https://buttons.github.io/buttons.js\"></script>\n  </body>\n</html>"
  },
  {
    "path": "assets/css/style.scss",
    "content": "---\n---\n\n@import \"{{ site.theme }}\";\n\nbody {\n  margin: 0;\n}\n\n.page-header {\n  color: #fff;\n  text-align: center;\n  background-color: #0081b8;\n  background-image: linear-gradient(120deg, #0081b8, #b8e045);\n  padding: 15px;\n}\n\n.main-content h1,\n.main-content h4,\n.main-content h5,\n.main-content h6 {\n  color: #0f9250;\n}\n\n.main-content h2 {\n  color: white;\n  background: linear-gradient(to right, #0081b8, #b8e045);\n  padding: 5px 10px;\n  margin-top: 50px;\n}\n\n.main-content h3 {\n  color: black;\n  background: linear-gradient(to right, #b5ddee, #e8f3c7);\n  padding: 5px 10px;\n  margin-top: 30px;\n}\n\n.project-tagline {\n  font-family: monospace;\n}\n\n.download {\n  display: inline-block;\n  padding: 10px;\n  opacity: 0.8;\n  width: 200px;\n  text-align: center;\n  margin-top: 10px;\n  cursor: pointer;\n  transition-duration: 0.2s;\n}\n\n.download:hover {\n  opacity: 1;\n}\n\n.download i {\n  font-size: 50px;\n  margin: 10px;\n}\n\n.download__link,\n.download__link:visited {\n  text-decoration: none;\n  color: white;\n  outline: none;\n}\n\n.download__link:hover {\n  text-decoration: none;\n  color: white;\n}\n\n@media only screen and (max-width: 640px) {\n  .download {\n    display: block;\n    width: auto;\n    height: auto;\n    text-align: left;\n    margin: 0;\n  }\n\n  .download i {\n    font-size: 30px;\n    margin: 0 10px;\n  }\n\n  p {\n    display: initial;\n    position: relative;\n    top: -8px;\n  }\n}\n\n.divider {\n  display: none;\n}\n\n.version {\n  color: white;\n  position: absolute;\n  top: 10px;\n  right: 15px;\n  font-size: 20px;\n  opacity: 0.8;\n}\n\n.actions {\n  text-align: center;\n  padding: 0 10px 30px 10px;\n}\n\n.actions--bottom {\n  padding: 30px 10px 0 10px;\n}\n\n.site-footer {\n  text-align: center;\n}\n"
  },
  {
    "path": "bundle/gramma.esm.js",
    "content": "var __commonJS = (cb, mod) => function __require() {\n  return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n};\n\n// node_modules/whatwg-fetch/dist/fetch.umd.js\nvar require_fetch_umd = __commonJS({\n  \"node_modules/whatwg-fetch/dist/fetch.umd.js\"(exports, module) {\n    (function(global, factory) {\n      typeof exports === \"object\" && typeof module !== \"undefined\" ? factory(exports) : typeof define === \"function\" && define.amd ? define([\"exports\"], factory) : factory(global.WHATWGFetch = {});\n    })(exports, function(exports2) {\n      \"use strict\";\n      var global = typeof globalThis !== \"undefined\" && globalThis || typeof self !== \"undefined\" && self || typeof global !== \"undefined\" && global;\n      var support = {\n        searchParams: \"URLSearchParams\" in global,\n        iterable: \"Symbol\" in global && \"iterator\" in Symbol,\n        blob: \"FileReader\" in global && \"Blob\" in global && function() {\n          try {\n            new Blob();\n            return true;\n          } catch (e) {\n            return false;\n          }\n        }(),\n        formData: \"FormData\" in global,\n        arrayBuffer: \"ArrayBuffer\" in global\n      };\n      function isDataView(obj) {\n        return obj && DataView.prototype.isPrototypeOf(obj);\n      }\n      if (support.arrayBuffer) {\n        var viewClasses = [\n          \"[object Int8Array]\",\n          \"[object Uint8Array]\",\n          \"[object Uint8ClampedArray]\",\n          \"[object Int16Array]\",\n          \"[object Uint16Array]\",\n          \"[object Int32Array]\",\n          \"[object Uint32Array]\",\n          \"[object Float32Array]\",\n          \"[object Float64Array]\"\n        ];\n        var isArrayBufferView = ArrayBuffer.isView || function(obj) {\n          return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1;\n        };\n      }\n      function normalizeName(name) {\n        if (typeof name !== \"string\") {\n          name = String(name);\n        }\n        if (/[^a-z0-9\\-#$%&'*+.^_`|~!]/i.test(name) || name === \"\") {\n          throw new TypeError('Invalid character in header field name: \"' + name + '\"');\n        }\n        return name.toLowerCase();\n      }\n      function normalizeValue(value) {\n        if (typeof value !== \"string\") {\n          value = String(value);\n        }\n        return value;\n      }\n      function iteratorFor(items) {\n        var iterator = {\n          next: function() {\n            var value = items.shift();\n            return { done: value === void 0, value };\n          }\n        };\n        if (support.iterable) {\n          iterator[Symbol.iterator] = function() {\n            return iterator;\n          };\n        }\n        return iterator;\n      }\n      function Headers(headers) {\n        this.map = {};\n        if (headers instanceof Headers) {\n          headers.forEach(function(value, name) {\n            this.append(name, value);\n          }, this);\n        } else if (Array.isArray(headers)) {\n          headers.forEach(function(header) {\n            this.append(header[0], header[1]);\n          }, this);\n        } else if (headers) {\n          Object.getOwnPropertyNames(headers).forEach(function(name) {\n            this.append(name, headers[name]);\n          }, this);\n        }\n      }\n      Headers.prototype.append = function(name, value) {\n        name = normalizeName(name);\n        value = normalizeValue(value);\n        var oldValue = this.map[name];\n        this.map[name] = oldValue ? oldValue + \", \" + value : value;\n      };\n      Headers.prototype[\"delete\"] = function(name) {\n        delete this.map[normalizeName(name)];\n      };\n      Headers.prototype.get = function(name) {\n        name = normalizeName(name);\n        return this.has(name) ? this.map[name] : null;\n      };\n      Headers.prototype.has = function(name) {\n        return this.map.hasOwnProperty(normalizeName(name));\n      };\n      Headers.prototype.set = function(name, value) {\n        this.map[normalizeName(name)] = normalizeValue(value);\n      };\n      Headers.prototype.forEach = function(callback, thisArg) {\n        for (var name in this.map) {\n          if (this.map.hasOwnProperty(name)) {\n            callback.call(thisArg, this.map[name], name, this);\n          }\n        }\n      };\n      Headers.prototype.keys = function() {\n        var items = [];\n        this.forEach(function(value, name) {\n          items.push(name);\n        });\n        return iteratorFor(items);\n      };\n      Headers.prototype.values = function() {\n        var items = [];\n        this.forEach(function(value) {\n          items.push(value);\n        });\n        return iteratorFor(items);\n      };\n      Headers.prototype.entries = function() {\n        var items = [];\n        this.forEach(function(value, name) {\n          items.push([name, value]);\n        });\n        return iteratorFor(items);\n      };\n      if (support.iterable) {\n        Headers.prototype[Symbol.iterator] = Headers.prototype.entries;\n      }\n      function consumed(body) {\n        if (body.bodyUsed) {\n          return Promise.reject(new TypeError(\"Already read\"));\n        }\n        body.bodyUsed = true;\n      }\n      function fileReaderReady(reader) {\n        return new Promise(function(resolve, reject) {\n          reader.onload = function() {\n            resolve(reader.result);\n          };\n          reader.onerror = function() {\n            reject(reader.error);\n          };\n        });\n      }\n      function readBlobAsArrayBuffer(blob) {\n        var reader = new FileReader();\n        var promise = fileReaderReady(reader);\n        reader.readAsArrayBuffer(blob);\n        return promise;\n      }\n      function readBlobAsText(blob) {\n        var reader = new FileReader();\n        var promise = fileReaderReady(reader);\n        reader.readAsText(blob);\n        return promise;\n      }\n      function readArrayBufferAsText(buf) {\n        var view = new Uint8Array(buf);\n        var chars = new Array(view.length);\n        for (var i = 0; i < view.length; i++) {\n          chars[i] = String.fromCharCode(view[i]);\n        }\n        return chars.join(\"\");\n      }\n      function bufferClone(buf) {\n        if (buf.slice) {\n          return buf.slice(0);\n        } else {\n          var view = new Uint8Array(buf.byteLength);\n          view.set(new Uint8Array(buf));\n          return view.buffer;\n        }\n      }\n      function Body() {\n        this.bodyUsed = false;\n        this._initBody = function(body) {\n          this.bodyUsed = this.bodyUsed;\n          this._bodyInit = body;\n          if (!body) {\n            this._bodyText = \"\";\n          } else if (typeof body === \"string\") {\n            this._bodyText = body;\n          } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {\n            this._bodyBlob = body;\n          } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {\n            this._bodyFormData = body;\n          } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n            this._bodyText = body.toString();\n          } else if (support.arrayBuffer && support.blob && isDataView(body)) {\n            this._bodyArrayBuffer = bufferClone(body.buffer);\n            this._bodyInit = new Blob([this._bodyArrayBuffer]);\n          } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {\n            this._bodyArrayBuffer = bufferClone(body);\n          } else {\n            this._bodyText = body = Object.prototype.toString.call(body);\n          }\n          if (!this.headers.get(\"content-type\")) {\n            if (typeof body === \"string\") {\n              this.headers.set(\"content-type\", \"text/plain;charset=UTF-8\");\n            } else if (this._bodyBlob && this._bodyBlob.type) {\n              this.headers.set(\"content-type\", this._bodyBlob.type);\n            } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {\n              this.headers.set(\"content-type\", \"application/x-www-form-urlencoded;charset=UTF-8\");\n            }\n          }\n        };\n        if (support.blob) {\n          this.blob = function() {\n            var rejected = consumed(this);\n            if (rejected) {\n              return rejected;\n            }\n            if (this._bodyBlob) {\n              return Promise.resolve(this._bodyBlob);\n            } else if (this._bodyArrayBuffer) {\n              return Promise.resolve(new Blob([this._bodyArrayBuffer]));\n            } else if (this._bodyFormData) {\n              throw new Error(\"could not read FormData body as blob\");\n            } else {\n              return Promise.resolve(new Blob([this._bodyText]));\n            }\n          };\n          this.arrayBuffer = function() {\n            if (this._bodyArrayBuffer) {\n              var isConsumed = consumed(this);\n              if (isConsumed) {\n                return isConsumed;\n              }\n              if (ArrayBuffer.isView(this._bodyArrayBuffer)) {\n                return Promise.resolve(this._bodyArrayBuffer.buffer.slice(this._bodyArrayBuffer.byteOffset, this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength));\n              } else {\n                return Promise.resolve(this._bodyArrayBuffer);\n              }\n            } else {\n              return this.blob().then(readBlobAsArrayBuffer);\n            }\n          };\n        }\n        this.text = function() {\n          var rejected = consumed(this);\n          if (rejected) {\n            return rejected;\n          }\n          if (this._bodyBlob) {\n            return readBlobAsText(this._bodyBlob);\n          } else if (this._bodyArrayBuffer) {\n            return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer));\n          } else if (this._bodyFormData) {\n            throw new Error(\"could not read FormData body as text\");\n          } else {\n            return Promise.resolve(this._bodyText);\n          }\n        };\n        if (support.formData) {\n          this.formData = function() {\n            return this.text().then(decode);\n          };\n        }\n        this.json = function() {\n          return this.text().then(JSON.parse);\n        };\n        return this;\n      }\n      var methods = [\"DELETE\", \"GET\", \"HEAD\", \"OPTIONS\", \"POST\", \"PUT\"];\n      function normalizeMethod(method) {\n        var upcased = method.toUpperCase();\n        return methods.indexOf(upcased) > -1 ? upcased : method;\n      }\n      function Request(input, options) {\n        if (!(this instanceof Request)) {\n          throw new TypeError('Please use the \"new\" operator, this DOM object constructor cannot be called as a function.');\n        }\n        options = options || {};\n        var body = options.body;\n        if (input instanceof Request) {\n          if (input.bodyUsed) {\n            throw new TypeError(\"Already read\");\n          }\n          this.url = input.url;\n          this.credentials = input.credentials;\n          if (!options.headers) {\n            this.headers = new Headers(input.headers);\n          }\n          this.method = input.method;\n          this.mode = input.mode;\n          this.signal = input.signal;\n          if (!body && input._bodyInit != null) {\n            body = input._bodyInit;\n            input.bodyUsed = true;\n          }\n        } else {\n          this.url = String(input);\n        }\n        this.credentials = options.credentials || this.credentials || \"same-origin\";\n        if (options.headers || !this.headers) {\n          this.headers = new Headers(options.headers);\n        }\n        this.method = normalizeMethod(options.method || this.method || \"GET\");\n        this.mode = options.mode || this.mode || null;\n        this.signal = options.signal || this.signal;\n        this.referrer = null;\n        if ((this.method === \"GET\" || this.method === \"HEAD\") && body) {\n          throw new TypeError(\"Body not allowed for GET or HEAD requests\");\n        }\n        this._initBody(body);\n        if (this.method === \"GET\" || this.method === \"HEAD\") {\n          if (options.cache === \"no-store\" || options.cache === \"no-cache\") {\n            var reParamSearch = /([?&])_=[^&]*/;\n            if (reParamSearch.test(this.url)) {\n              this.url = this.url.replace(reParamSearch, \"$1_=\" + new Date().getTime());\n            } else {\n              var reQueryString = /\\?/;\n              this.url += (reQueryString.test(this.url) ? \"&\" : \"?\") + \"_=\" + new Date().getTime();\n            }\n          }\n        }\n      }\n      Request.prototype.clone = function() {\n        return new Request(this, { body: this._bodyInit });\n      };\n      function decode(body) {\n        var form = new FormData();\n        body.trim().split(\"&\").forEach(function(bytes) {\n          if (bytes) {\n            var split = bytes.split(\"=\");\n            var name = split.shift().replace(/\\+/g, \" \");\n            var value = split.join(\"=\").replace(/\\+/g, \" \");\n            form.append(decodeURIComponent(name), decodeURIComponent(value));\n          }\n        });\n        return form;\n      }\n      function parseHeaders(rawHeaders) {\n        var headers = new Headers();\n        var preProcessedHeaders = rawHeaders.replace(/\\r?\\n[\\t ]+/g, \" \");\n        preProcessedHeaders.split(\"\\r\").map(function(header) {\n          return header.indexOf(\"\\n\") === 0 ? header.substr(1, header.length) : header;\n        }).forEach(function(line) {\n          var parts = line.split(\":\");\n          var key = parts.shift().trim();\n          if (key) {\n            var value = parts.join(\":\").trim();\n            headers.append(key, value);\n          }\n        });\n        return headers;\n      }\n      Body.call(Request.prototype);\n      function Response(bodyInit, options) {\n        if (!(this instanceof Response)) {\n          throw new TypeError('Please use the \"new\" operator, this DOM object constructor cannot be called as a function.');\n        }\n        if (!options) {\n          options = {};\n        }\n        this.type = \"default\";\n        this.status = options.status === void 0 ? 200 : options.status;\n        this.ok = this.status >= 200 && this.status < 300;\n        this.statusText = options.statusText === void 0 ? \"\" : \"\" + options.statusText;\n        this.headers = new Headers(options.headers);\n        this.url = options.url || \"\";\n        this._initBody(bodyInit);\n      }\n      Body.call(Response.prototype);\n      Response.prototype.clone = function() {\n        return new Response(this._bodyInit, {\n          status: this.status,\n          statusText: this.statusText,\n          headers: new Headers(this.headers),\n          url: this.url\n        });\n      };\n      Response.error = function() {\n        var response = new Response(null, { status: 0, statusText: \"\" });\n        response.type = \"error\";\n        return response;\n      };\n      var redirectStatuses = [301, 302, 303, 307, 308];\n      Response.redirect = function(url, status) {\n        if (redirectStatuses.indexOf(status) === -1) {\n          throw new RangeError(\"Invalid status code\");\n        }\n        return new Response(null, { status, headers: { location: url } });\n      };\n      exports2.DOMException = global.DOMException;\n      try {\n        new exports2.DOMException();\n      } catch (err) {\n        exports2.DOMException = function(message, name) {\n          this.message = message;\n          this.name = name;\n          var error = Error(message);\n          this.stack = error.stack;\n        };\n        exports2.DOMException.prototype = Object.create(Error.prototype);\n        exports2.DOMException.prototype.constructor = exports2.DOMException;\n      }\n      function fetch2(input, init) {\n        return new Promise(function(resolve, reject) {\n          var request = new Request(input, init);\n          if (request.signal && request.signal.aborted) {\n            return reject(new exports2.DOMException(\"Aborted\", \"AbortError\"));\n          }\n          var xhr = new XMLHttpRequest();\n          function abortXhr() {\n            xhr.abort();\n          }\n          xhr.onload = function() {\n            var options = {\n              status: xhr.status,\n              statusText: xhr.statusText,\n              headers: parseHeaders(xhr.getAllResponseHeaders() || \"\")\n            };\n            options.url = \"responseURL\" in xhr ? xhr.responseURL : options.headers.get(\"X-Request-URL\");\n            var body = \"response\" in xhr ? xhr.response : xhr.responseText;\n            setTimeout(function() {\n              resolve(new Response(body, options));\n            }, 0);\n          };\n          xhr.onerror = function() {\n            setTimeout(function() {\n              reject(new TypeError(\"Network request failed\"));\n            }, 0);\n          };\n          xhr.ontimeout = function() {\n            setTimeout(function() {\n              reject(new TypeError(\"Network request failed\"));\n            }, 0);\n          };\n          xhr.onabort = function() {\n            setTimeout(function() {\n              reject(new exports2.DOMException(\"Aborted\", \"AbortError\"));\n            }, 0);\n          };\n          function fixUrl(url) {\n            try {\n              return url === \"\" && global.location.href ? global.location.href : url;\n            } catch (e) {\n              return url;\n            }\n          }\n          xhr.open(request.method, fixUrl(request.url), true);\n          if (request.credentials === \"include\") {\n            xhr.withCredentials = true;\n          } else if (request.credentials === \"omit\") {\n            xhr.withCredentials = false;\n          }\n          if (\"responseType\" in xhr) {\n            if (support.blob) {\n              xhr.responseType = \"blob\";\n            } else if (support.arrayBuffer && request.headers.get(\"Content-Type\") && request.headers.get(\"Content-Type\").indexOf(\"application/octet-stream\") !== -1) {\n              xhr.responseType = \"arraybuffer\";\n            }\n          }\n          if (init && typeof init.headers === \"object\" && !(init.headers instanceof Headers)) {\n            Object.getOwnPropertyNames(init.headers).forEach(function(name) {\n              xhr.setRequestHeader(name, normalizeValue(init.headers[name]));\n            });\n          } else {\n            request.headers.forEach(function(value, name) {\n              xhr.setRequestHeader(name, value);\n            });\n          }\n          if (request.signal) {\n            request.signal.addEventListener(\"abort\", abortXhr);\n            xhr.onreadystatechange = function() {\n              if (xhr.readyState === 4) {\n                request.signal.removeEventListener(\"abort\", abortXhr);\n              }\n            };\n          }\n          xhr.send(typeof request._bodyInit === \"undefined\" ? null : request._bodyInit);\n        });\n      }\n      fetch2.polyfill = true;\n      if (!global.fetch) {\n        global.fetch = fetch2;\n        global.Headers = Headers;\n        global.Request = Request;\n        global.Response = Response;\n      }\n      exports2.Headers = Headers;\n      exports2.Request = Request;\n      exports2.Response = Response;\n      exports2.fetch = fetch2;\n      Object.defineProperty(exports2, \"__esModule\", { value: true });\n    });\n  }\n});\n\n// node_modules/isomorphic-fetch/fetch-npm-browserify.js\nvar require_fetch_npm_browserify = __commonJS({\n  \"node_modules/isomorphic-fetch/fetch-npm-browserify.js\"(exports, module) {\n    require_fetch_umd();\n    module.exports = self.fetch.bind(self);\n  }\n});\n\n// node_modules/strict-uri-encode/index.js\nvar require_strict_uri_encode = __commonJS({\n  \"node_modules/strict-uri-encode/index.js\"(exports, module) {\n    \"use strict\";\n    module.exports = (str) => encodeURIComponent(str).replace(/[!'()*]/g, (x) => `%${x.charCodeAt(0).toString(16).toUpperCase()}`);\n  }\n});\n\n// node_modules/decode-uri-component/index.js\nvar require_decode_uri_component = __commonJS({\n  \"node_modules/decode-uri-component/index.js\"(exports, module) {\n    \"use strict\";\n    var token = \"%[a-f0-9]{2}\";\n    var singleMatcher = new RegExp(token, \"gi\");\n    var multiMatcher = new RegExp(\"(\" + token + \")+\", \"gi\");\n    function decodeComponents(components, split) {\n      try {\n        return decodeURIComponent(components.join(\"\"));\n      } catch (err) {\n      }\n      if (components.length === 1) {\n        return components;\n      }\n      split = split || 1;\n      var left = components.slice(0, split);\n      var right = components.slice(split);\n      return Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));\n    }\n    function decode(input) {\n      try {\n        return decodeURIComponent(input);\n      } catch (err) {\n        var tokens = input.match(singleMatcher);\n        for (var i = 1; i < tokens.length; i++) {\n          input = decodeComponents(tokens, i).join(\"\");\n          tokens = input.match(singleMatcher);\n        }\n        return input;\n      }\n    }\n    function customDecodeURIComponent(input) {\n      var replaceMap = {\n        \"%FE%FF\": \"\\uFFFD\\uFFFD\",\n        \"%FF%FE\": \"\\uFFFD\\uFFFD\"\n      };\n      var match = multiMatcher.exec(input);\n      while (match) {\n        try {\n          replaceMap[match[0]] = decodeURIComponent(match[0]);\n        } catch (err) {\n          var result = decode(match[0]);\n          if (result !== match[0]) {\n            replaceMap[match[0]] = result;\n          }\n        }\n        match = multiMatcher.exec(input);\n      }\n      replaceMap[\"%C2\"] = \"\\uFFFD\";\n      var entries = Object.keys(replaceMap);\n      for (var i = 0; i < entries.length; i++) {\n        var key = entries[i];\n        input = input.replace(new RegExp(key, \"g\"), replaceMap[key]);\n      }\n      return input;\n    }\n    module.exports = function(encodedURI) {\n      if (typeof encodedURI !== \"string\") {\n        throw new TypeError(\"Expected `encodedURI` to be of type `string`, got `\" + typeof encodedURI + \"`\");\n      }\n      try {\n        encodedURI = encodedURI.replace(/\\+/g, \" \");\n        return decodeURIComponent(encodedURI);\n      } catch (err) {\n        return customDecodeURIComponent(encodedURI);\n      }\n    };\n  }\n});\n\n// node_modules/split-on-first/index.js\nvar require_split_on_first = __commonJS({\n  \"node_modules/split-on-first/index.js\"(exports, module) {\n    \"use strict\";\n    module.exports = (string, separator) => {\n      if (!(typeof string === \"string\" && typeof separator === \"string\")) {\n        throw new TypeError(\"Expected the arguments to be of type `string`\");\n      }\n      if (separator === \"\") {\n        return [string];\n      }\n      const separatorIndex = string.indexOf(separator);\n      if (separatorIndex === -1) {\n        return [string];\n      }\n      return [\n        string.slice(0, separatorIndex),\n        string.slice(separatorIndex + separator.length)\n      ];\n    };\n  }\n});\n\n// node_modules/filter-obj/index.js\nvar require_filter_obj = __commonJS({\n  \"node_modules/filter-obj/index.js\"(exports, module) {\n    \"use strict\";\n    module.exports = function(obj, predicate) {\n      var ret = {};\n      var keys = Object.keys(obj);\n      var isArr = Array.isArray(predicate);\n      for (var i = 0; i < keys.length; i++) {\n        var key = keys[i];\n        var val = obj[key];\n        if (isArr ? predicate.indexOf(key) !== -1 : predicate(key, val, obj)) {\n          ret[key] = val;\n        }\n      }\n      return ret;\n    };\n  }\n});\n\n// node_modules/query-string/index.js\nvar require_query_string = __commonJS({\n  \"node_modules/query-string/index.js\"(exports) {\n    \"use strict\";\n    var strictUriEncode = require_strict_uri_encode();\n    var decodeComponent = require_decode_uri_component();\n    var splitOnFirst = require_split_on_first();\n    var filterObject = require_filter_obj();\n    var isNullOrUndefined = (value) => value === null || value === void 0;\n    var encodeFragmentIdentifier = Symbol(\"encodeFragmentIdentifier\");\n    function encoderForArrayFormat(options) {\n      switch (options.arrayFormat) {\n        case \"index\":\n          return (key) => (result, value) => {\n            const index = result.length;\n            if (value === void 0 || options.skipNull && value === null || options.skipEmptyString && value === \"\") {\n              return result;\n            }\n            if (value === null) {\n              return [...result, [encode(key, options), \"[\", index, \"]\"].join(\"\")];\n            }\n            return [\n              ...result,\n              [encode(key, options), \"[\", encode(index, options), \"]=\", encode(value, options)].join(\"\")\n            ];\n          };\n        case \"bracket\":\n          return (key) => (result, value) => {\n            if (value === void 0 || options.skipNull && value === null || options.skipEmptyString && value === \"\") {\n              return result;\n            }\n            if (value === null) {\n              return [...result, [encode(key, options), \"[]\"].join(\"\")];\n            }\n            return [...result, [encode(key, options), \"[]=\", encode(value, options)].join(\"\")];\n          };\n        case \"comma\":\n        case \"separator\":\n        case \"bracket-separator\": {\n          const keyValueSep = options.arrayFormat === \"bracket-separator\" ? \"[]=\" : \"=\";\n          return (key) => (result, value) => {\n            if (value === void 0 || options.skipNull && value === null || options.skipEmptyString && value === \"\") {\n              return result;\n            }\n            value = value === null ? \"\" : value;\n            if (result.length === 0) {\n              return [[encode(key, options), keyValueSep, encode(value, options)].join(\"\")];\n            }\n            return [[result, encode(value, options)].join(options.arrayFormatSeparator)];\n          };\n        }\n        default:\n          return (key) => (result, value) => {\n            if (value === void 0 || options.skipNull && value === null || options.skipEmptyString && value === \"\") {\n              return result;\n            }\n            if (value === null) {\n              return [...result, encode(key, options)];\n            }\n            return [...result, [encode(key, options), \"=\", encode(value, options)].join(\"\")];\n          };\n      }\n    }\n    function parserForArrayFormat(options) {\n      let result;\n      switch (options.arrayFormat) {\n        case \"index\":\n          return (key, value, accumulator) => {\n            result = /\\[(\\d*)\\]$/.exec(key);\n            key = key.replace(/\\[\\d*\\]$/, \"\");\n            if (!result) {\n              accumulator[key] = value;\n              return;\n            }\n            if (accumulator[key] === void 0) {\n              accumulator[key] = {};\n            }\n            accumulator[key][result[1]] = value;\n          };\n        case \"bracket\":\n          return (key, value, accumulator) => {\n            result = /(\\[\\])$/.exec(key);\n            key = key.replace(/\\[\\]$/, \"\");\n            if (!result) {\n              accumulator[key] = value;\n              return;\n            }\n            if (accumulator[key] === void 0) {\n              accumulator[key] = [value];\n              return;\n            }\n            accumulator[key] = [].concat(accumulator[key], value);\n          };\n        case \"comma\":\n        case \"separator\":\n          return (key, value, accumulator) => {\n            const isArray = typeof value === \"string\" && value.includes(options.arrayFormatSeparator);\n            const isEncodedArray = typeof value === \"string\" && !isArray && decode(value, options).includes(options.arrayFormatSeparator);\n            value = isEncodedArray ? decode(value, options) : value;\n            const newValue = isArray || isEncodedArray ? value.split(options.arrayFormatSeparator).map((item) => decode(item, options)) : value === null ? value : decode(value, options);\n            accumulator[key] = newValue;\n          };\n        case \"bracket-separator\":\n          return (key, value, accumulator) => {\n            const isArray = /(\\[\\])$/.test(key);\n            key = key.replace(/\\[\\]$/, \"\");\n            if (!isArray) {\n              accumulator[key] = value ? decode(value, options) : value;\n              return;\n            }\n            const arrayValue = value === null ? [] : value.split(options.arrayFormatSeparator).map((item) => decode(item, options));\n            if (accumulator[key] === void 0) {\n              accumulator[key] = arrayValue;\n              return;\n            }\n            accumulator[key] = [].concat(accumulator[key], arrayValue);\n          };\n        default:\n          return (key, value, accumulator) => {\n            if (accumulator[key] === void 0) {\n              accumulator[key] = value;\n              return;\n            }\n            accumulator[key] = [].concat(accumulator[key], value);\n          };\n      }\n    }\n    function validateArrayFormatSeparator(value) {\n      if (typeof value !== \"string\" || value.length !== 1) {\n        throw new TypeError(\"arrayFormatSeparator must be single character string\");\n      }\n    }\n    function encode(value, options) {\n      if (options.encode) {\n        return options.strict ? strictUriEncode(value) : encodeURIComponent(value);\n      }\n      return value;\n    }\n    function decode(value, options) {\n      if (options.decode) {\n        return decodeComponent(value);\n      }\n      return value;\n    }\n    function keysSorter(input) {\n      if (Array.isArray(input)) {\n        return input.sort();\n      }\n      if (typeof input === \"object\") {\n        return keysSorter(Object.keys(input)).sort((a, b) => Number(a) - Number(b)).map((key) => input[key]);\n      }\n      return input;\n    }\n    function removeHash(input) {\n      const hashStart = input.indexOf(\"#\");\n      if (hashStart !== -1) {\n        input = input.slice(0, hashStart);\n      }\n      return input;\n    }\n    function getHash(url) {\n      let hash = \"\";\n      const hashStart = url.indexOf(\"#\");\n      if (hashStart !== -1) {\n        hash = url.slice(hashStart);\n      }\n      return hash;\n    }\n    function extract(input) {\n      input = removeHash(input);\n      const queryStart = input.indexOf(\"?\");\n      if (queryStart === -1) {\n        return \"\";\n      }\n      return input.slice(queryStart + 1);\n    }\n    function parseValue(value, options) {\n      if (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === \"string\" && value.trim() !== \"\")) {\n        value = Number(value);\n      } else if (options.parseBooleans && value !== null && (value.toLowerCase() === \"true\" || value.toLowerCase() === \"false\")) {\n        value = value.toLowerCase() === \"true\";\n      }\n      return value;\n    }\n    function parse(query, options) {\n      options = Object.assign({\n        decode: true,\n        sort: true,\n        arrayFormat: \"none\",\n        arrayFormatSeparator: \",\",\n        parseNumbers: false,\n        parseBooleans: false\n      }, options);\n      validateArrayFormatSeparator(options.arrayFormatSeparator);\n      const formatter = parserForArrayFormat(options);\n      const ret = Object.create(null);\n      if (typeof query !== \"string\") {\n        return ret;\n      }\n      query = query.trim().replace(/^[?#&]/, \"\");\n      if (!query) {\n        return ret;\n      }\n      for (const param of query.split(\"&\")) {\n        if (param === \"\") {\n          continue;\n        }\n        let [key, value] = splitOnFirst(options.decode ? param.replace(/\\+/g, \" \") : param, \"=\");\n        value = value === void 0 ? null : [\"comma\", \"separator\", \"bracket-separator\"].includes(options.arrayFormat) ? value : decode(value, options);\n        formatter(decode(key, options), value, ret);\n      }\n      for (const key of Object.keys(ret)) {\n        const value = ret[key];\n        if (typeof value === \"object\" && value !== null) {\n          for (const k of Object.keys(value)) {\n            value[k] = parseValue(value[k], options);\n          }\n        } else {\n          ret[key] = parseValue(value, options);\n        }\n      }\n      if (options.sort === false) {\n        return ret;\n      }\n      return (options.sort === true ? Object.keys(ret).sort() : Object.keys(ret).sort(options.sort)).reduce((result, key) => {\n        const value = ret[key];\n        if (Boolean(value) && typeof value === \"object\" && !Array.isArray(value)) {\n          result[key] = keysSorter(value);\n        } else {\n          result[key] = value;\n        }\n        return result;\n      }, Object.create(null));\n    }\n    exports.extract = extract;\n    exports.parse = parse;\n    exports.stringify = (object, options) => {\n      if (!object) {\n        return \"\";\n      }\n      options = Object.assign({\n        encode: true,\n        strict: true,\n        arrayFormat: \"none\",\n        arrayFormatSeparator: \",\"\n      }, options);\n      validateArrayFormatSeparator(options.arrayFormatSeparator);\n      const shouldFilter = (key) => options.skipNull && isNullOrUndefined(object[key]) || options.skipEmptyString && object[key] === \"\";\n      const formatter = encoderForArrayFormat(options);\n      const objectCopy = {};\n      for (const key of Object.keys(object)) {\n        if (!shouldFilter(key)) {\n          objectCopy[key] = object[key];\n        }\n      }\n      const keys = Object.keys(objectCopy);\n      if (options.sort !== false) {\n        keys.sort(options.sort);\n      }\n      return keys.map((key) => {\n        const value = object[key];\n        if (value === void 0) {\n          return \"\";\n        }\n        if (value === null) {\n          return encode(key, options);\n        }\n        if (Array.isArray(value)) {\n          if (value.length === 0 && options.arrayFormat === \"bracket-separator\") {\n            return encode(key, options) + \"[]\";\n          }\n          return value.reduce(formatter(key), []).join(\"&\");\n        }\n        return encode(key, options) + \"=\" + encode(value, options);\n      }).filter((x) => x.length > 0).join(\"&\");\n    };\n    exports.parseUrl = (url, options) => {\n      options = Object.assign({\n        decode: true\n      }, options);\n      const [url_, hash] = splitOnFirst(url, \"#\");\n      return Object.assign({\n        url: url_.split(\"?\")[0] || \"\",\n        query: parse(extract(url), options)\n      }, options && options.parseFragmentIdentifier && hash ? { fragmentIdentifier: decode(hash, options) } : {});\n    };\n    exports.stringifyUrl = (object, options) => {\n      options = Object.assign({\n        encode: true,\n        strict: true,\n        [encodeFragmentIdentifier]: true\n      }, options);\n      const url = removeHash(object.url).split(\"?\")[0] || \"\";\n      const queryFromUrl = exports.extract(object.url);\n      const parsedQueryFromUrl = exports.parse(queryFromUrl, { sort: false });\n      const query = Object.assign(parsedQueryFromUrl, object.query);\n      let queryString = exports.stringify(query, options);\n      if (queryString) {\n        queryString = `?${queryString}`;\n      }\n      let hash = getHash(object.url);\n      if (object.fragmentIdentifier) {\n        hash = `#${options[encodeFragmentIdentifier] ? encode(object.fragmentIdentifier, options) : object.fragmentIdentifier}`;\n      }\n      return `${url}${queryString}${hash}`;\n    };\n    exports.pick = (input, filter, options) => {\n      options = Object.assign({\n        parseFragmentIdentifier: true,\n        [encodeFragmentIdentifier]: false\n      }, options);\n      const { url, query, fragmentIdentifier } = exports.parseUrl(input, options);\n      return exports.stringifyUrl({\n        url,\n        query: filterObject(query, filter),\n        fragmentIdentifier\n      }, options);\n    };\n    exports.exclude = (input, filter, options) => {\n      const exclusionFilter = Array.isArray(filter) ? (key) => !filter.includes(key) : (key, value) => !filter(key, value);\n      return exports.pick(input, exclusionFilter, options);\n    };\n  }\n});\n\n// data/rules.json\nvar require_rules = __commonJS({\n  \"data/rules.json\"(exports, module) {\n    module.exports = [\n      {\n        id: \"CASING\",\n        description: \"Detecting uppercase words where lowercase is required and vice versa.\"\n      },\n      {\n        id: \"COLLOQUIALISMS\",\n        description: \"Colloquial style.\"\n      },\n      {\n        id: \"COMPOUNDING\",\n        description: \"Rules about spelling terms as one word or as as separate words.\"\n      },\n      {\n        id: \"CONFUSED_WORDS\",\n        description: \"Words that are easily confused, like 'there' and 'their' in English.\"\n      },\n      {\n        id: \"FALSE_FRIENDS\",\n        description: \"Words easily confused by language learners because a similar word exists in their native language.\"\n      },\n      {\n        id: \"GENDER_NEUTRALITY\",\n        description: \"\"\n      },\n      {\n        id: \"GRAMMAR\",\n        description: \"\"\n      },\n      {\n        id: \"MISC\",\n        description: \"Miscellaneous rules that don't fit elsewhere.\"\n      },\n      {\n        id: \"PUNCTUATION\",\n        description: \"\"\n      },\n      {\n        id: \"REDUNDANCY\",\n        description: \"\"\n      },\n      {\n        id: \"REGIONALISMS\",\n        description: \"Words used only in another language variant or used with different meanings.\"\n      },\n      {\n        id: \"REPETITIONS\",\n        description: \"\"\n      },\n      {\n        id: \"SEMANTICS\",\n        description: \"Logic, content, and consistency problems.\"\n      },\n      {\n        id: \"STYLE\",\n        description: \"General style issues not covered by other categories, like overly verbose wording.\"\n      },\n      {\n        id: \"TYPOGRAPHY\",\n        description: \"Problems like incorrectly used dash or quote characters.\"\n      },\n      {\n        id: \"TYPOS\",\n        description: \"Spelling issues.\"\n      }\n    ];\n  }\n});\n\n// src/validators/rules.js\nvar require_rules2 = __commonJS({\n  \"src/validators/rules.js\"(exports, module) {\n    var rules = require_rules();\n    var ruleOptions = rules.map((rule) => rule.id.toLowerCase());\n    var isRule = (value) => {\n      return ruleOptions.includes(value);\n    };\n    module.exports = {\n      ruleOptions,\n      isRule\n    };\n  }\n});\n\n// src/initialConfig.js\nvar require_initialConfig = __commonJS({\n  \"src/initialConfig.js\"(exports, module) {\n    var { ruleOptions } = require_rules2();\n    var rules = {};\n    ruleOptions.forEach((rule) => {\n      rules[rule] = true;\n    });\n    var initialConfig = {\n      api_url: \"https://api.languagetool.org/v2/check\",\n      api_key: \"\",\n      dictionary: [],\n      language: \"en-US\",\n      rules\n    };\n    module.exports = initialConfig;\n  }\n});\n\n// src/utils/prepareMarkdown.js\nvar require_prepareMarkdown = __commonJS({\n  \"src/utils/prepareMarkdown.js\"(exports) {\n    var __create = Object.create;\n    var __defProp = Object.defineProperty;\n    var __getOwnPropDesc = Object.getOwnPropertyDescriptor;\n    var __getOwnPropNames = Object.getOwnPropertyNames;\n    var __getProtoOf = Object.getPrototypeOf;\n    var __hasOwnProp = Object.prototype.hasOwnProperty;\n    var __markAsModule = (target) => __defProp(target, \"__esModule\", { value: true });\n    var __commonJS2 = (cb, mod) => function __require() {\n      return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;\n    };\n    var __export = (target, all2) => {\n      __markAsModule(target);\n      for (var name in all2)\n        __defProp(target, name, { get: all2[name], enumerable: true });\n    };\n    var __reExport = (target, module2, desc) => {\n      if (module2 && typeof module2 === \"object\" || typeof module2 === \"function\") {\n        for (let key of __getOwnPropNames(module2))\n          if (!__hasOwnProp.call(target, key) && key !== \"default\")\n            __defProp(target, key, {\n              get: () => module2[key],\n              enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable\n            });\n      }\n      return target;\n    };\n    var __toModule = (module2) => {\n      return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, \"default\", module2 && module2.__esModule && \"default\" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);\n    };\n    var require_format = __commonJS2({\n      \"node_modules/format/format.js\"(exports2, module2) {\n        ;\n        (function() {\n          var namespace;\n          if (typeof module2 !== \"undefined\") {\n            namespace = module2.exports = format;\n          } else {\n            namespace = function() {\n              return this || (1, eval)(\"this\");\n            }();\n          }\n          namespace.format = format;\n          namespace.vsprintf = vsprintf;\n          if (typeof console !== \"undefined\" && typeof console.log === \"function\") {\n            namespace.printf = printf;\n          }\n          function printf() {\n            console.log(format.apply(null, arguments));\n          }\n          function vsprintf(fmt, replacements) {\n            return format.apply(null, [fmt].concat(replacements));\n          }\n          function format(fmt) {\n            var argIndex = 1, args = [].slice.call(arguments), i = 0, n = fmt.length, result = \"\", c, escaped = false, arg, tmp, leadingZero = false, precision, nextArg = function() {\n              return args[argIndex++];\n            }, slurpNumber = function() {\n              var digits = \"\";\n              while (/\\d/.test(fmt[i])) {\n                digits += fmt[i++];\n                c = fmt[i];\n              }\n              return digits.length > 0 ? parseInt(digits) : null;\n            };\n            for (; i < n; ++i) {\n              c = fmt[i];\n              if (escaped) {\n                escaped = false;\n                if (c == \".\") {\n                  leadingZero = false;\n                  c = fmt[++i];\n                } else if (c == \"0\" && fmt[i + 1] == \".\") {\n                  leadingZero = true;\n                  i += 2;\n                  c = fmt[i];\n                } else {\n                  leadingZero = true;\n                }\n                precision = slurpNumber();\n                switch (c) {\n                  case \"b\":\n                    result += parseInt(nextArg(), 10).toString(2);\n                    break;\n                  case \"c\":\n                    arg = nextArg();\n                    if (typeof arg === \"string\" || arg instanceof String)\n                      result += arg;\n                    else\n                      result += String.fromCharCode(parseInt(arg, 10));\n                    break;\n                  case \"d\":\n                    result += parseInt(nextArg(), 10);\n                    break;\n                  case \"f\":\n                    tmp = String(parseFloat(nextArg()).toFixed(precision || 6));\n                    result += leadingZero ? tmp : tmp.replace(/^0/, \"\");\n                    break;\n                  case \"j\":\n                    result += JSON.stringify(nextArg());\n                    break;\n                  case \"o\":\n                    result += \"0\" + parseInt(nextArg(), 10).toString(8);\n                    break;\n                  case \"s\":\n                    result += nextArg();\n                    break;\n                  case \"x\":\n                    result += \"0x\" + parseInt(nextArg(), 10).toString(16);\n                    break;\n                  case \"X\":\n                    result += \"0x\" + parseInt(nextArg(), 10).toString(16).toUpperCase();\n                    break;\n                  default:\n                    result += c;\n                    break;\n                }\n              } else if (c === \"%\") {\n                escaped = true;\n              } else {\n                result += c;\n              }\n            }\n            return result;\n          }\n        })();\n      }\n    });\n    var require_is_buffer = __commonJS2({\n      \"node_modules/is-buffer/index.js\"(exports2, module2) {\n        module2.exports = function isBuffer2(obj) {\n          return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === \"function\" && obj.constructor.isBuffer(obj);\n        };\n      }\n    });\n    var require_extend = __commonJS2({\n      \"node_modules/extend/index.js\"(exports2, module2) {\n        \"use strict\";\n        var hasOwn = Object.prototype.hasOwnProperty;\n        var toStr = Object.prototype.toString;\n        var defineProperty = Object.defineProperty;\n        var gOPD = Object.getOwnPropertyDescriptor;\n        var isArray = function isArray2(arr) {\n          if (typeof Array.isArray === \"function\") {\n            return Array.isArray(arr);\n          }\n          return toStr.call(arr) === \"[object Array]\";\n        };\n        var isPlainObject2 = function isPlainObject3(obj) {\n          if (!obj || toStr.call(obj) !== \"[object Object]\") {\n            return false;\n          }\n          var hasOwnConstructor = hasOwn.call(obj, \"constructor\");\n          var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\");\n          if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\n            return false;\n          }\n          var key;\n          for (key in obj) {\n          }\n          return typeof key === \"undefined\" || hasOwn.call(obj, key);\n        };\n        var setProperty = function setProperty2(target, options) {\n          if (defineProperty && options.name === \"__proto__\") {\n            defineProperty(target, options.name, {\n              enumerable: true,\n              configurable: true,\n              value: options.newValue,\n              writable: true\n            });\n          } else {\n            target[options.name] = options.newValue;\n          }\n        };\n        var getProperty = function getProperty2(obj, name) {\n          if (name === \"__proto__\") {\n            if (!hasOwn.call(obj, name)) {\n              return void 0;\n            } else if (gOPD) {\n              return gOPD(obj, name).value;\n            }\n          }\n          return obj[name];\n        };\n        module2.exports = function extend2() {\n          var options, name, src, copy, copyIsArray, clone;\n          var target = arguments[0];\n          var i = 1;\n          var length = arguments.length;\n          var deep = false;\n          if (typeof target === \"boolean\") {\n            deep = target;\n            target = arguments[1] || {};\n            i = 2;\n          }\n          if (target == null || typeof target !== \"object\" && typeof target !== \"function\") {\n            target = {};\n          }\n          for (; i < length; ++i) {\n            options = arguments[i];\n            if (options != null) {\n              for (name in options) {\n                src = getProperty(target, name);\n                copy = getProperty(options, name);\n                if (target !== copy) {\n                  if (deep && copy && (isPlainObject2(copy) || (copyIsArray = isArray(copy)))) {\n                    if (copyIsArray) {\n                      copyIsArray = false;\n                      clone = src && isArray(src) ? src : [];\n                    } else {\n                      clone = src && isPlainObject2(src) ? src : {};\n                    }\n                    setProperty(target, {\n                      name,\n                      newValue: extend2(deep, clone, copy)\n                    });\n                  } else if (typeof copy !== \"undefined\") {\n                    setProperty(target, { name, newValue: copy });\n                  }\n                }\n              }\n            }\n          }\n          return target;\n        };\n      }\n    });\n    __export(exports, {\n      default: () => prepareMarkdown_default\n    });\n    var defaults = {\n      children(node) {\n        return node.children;\n      },\n      annotatetextnode(node, text3) {\n        if (node.type === \"text\") {\n          return {\n            offset: {\n              end: node.position.end.offset,\n              start: node.position.start.offset\n            },\n            text: text3.substring(node.position.start.offset, node.position.end.offset)\n          };\n        } else {\n          return null;\n        }\n      },\n      interpretmarkup(text3 = \"\") {\n        return text3;\n      }\n    };\n    function collecttextnodes(ast, text3, options = defaults) {\n      const textannotations = [];\n      function recurse(node) {\n        const annotation = options.annotatetextnode(node, text3);\n        if (annotation !== null) {\n          textannotations.push(annotation);\n        }\n        const children = options.children(node);\n        if (children !== null && Array.isArray(children)) {\n          children.forEach(recurse);\n        }\n      }\n      recurse(ast);\n      return textannotations;\n    }\n    function composeannotation(text3, annotatedtextnodes, options = defaults) {\n      const annotations = [];\n      let prior = {\n        offset: {\n          end: 0,\n          start: 0\n        }\n      };\n      for (const current of annotatedtextnodes) {\n        const currenttext = text3.substring(prior.offset.end, current.offset.start);\n        annotations.push({\n          interpretAs: options.interpretmarkup(currenttext),\n          markup: currenttext,\n          offset: {\n            end: current.offset.start,\n            start: prior.offset.end\n          }\n        });\n        annotations.push(current);\n        prior = current;\n      }\n      const finaltext = text3.substring(prior.offset.end, text3.length);\n      annotations.push({\n        interpretAs: options.interpretmarkup(finaltext),\n        markup: finaltext,\n        offset: {\n          end: text3.length,\n          start: prior.offset.end\n        }\n      });\n      return { annotation: annotations };\n    }\n    function build(text3, parse3, options = defaults) {\n      const nodes = parse3(text3);\n      const textnodes = collecttextnodes(nodes, text3, options);\n      return composeannotation(text3, textnodes, options);\n    }\n    var import_format = __toModule(require_format());\n    var fault = Object.assign(create(Error), {\n      eval: create(EvalError),\n      range: create(RangeError),\n      reference: create(ReferenceError),\n      syntax: create(SyntaxError),\n      type: create(TypeError),\n      uri: create(URIError)\n    });\n    function create(Constructor) {\n      FormattedError.displayName = Constructor.displayName || Constructor.name;\n      return FormattedError;\n      function FormattedError(format, ...values) {\n        var reason = format ? (0, import_format.default)(format, ...values) : format;\n        return new Constructor(reason);\n      }\n    }\n    var own = {}.hasOwnProperty;\n    var markers = {\n      yaml: \"-\",\n      toml: \"+\"\n    };\n    function matters(options = \"yaml\") {\n      const results = [];\n      let index2 = -1;\n      if (!Array.isArray(options)) {\n        options = [options];\n      }\n      while (++index2 < options.length) {\n        results[index2] = matter(options[index2]);\n      }\n      return results;\n    }\n    function matter(option) {\n      let result = option;\n      if (typeof result === \"string\") {\n        if (!own.call(markers, result)) {\n          throw fault(\"Missing matter definition for `%s`\", result);\n        }\n        result = {\n          type: result,\n          marker: markers[result]\n        };\n      } else if (typeof result !== \"object\") {\n        throw fault(\"Expected matter to be an object, not `%j`\", result);\n      }\n      if (!own.call(result, \"type\")) {\n        throw fault(\"Missing `type` in matter `%j`\", result);\n      }\n      if (!own.call(result, \"fence\") && !own.call(result, \"marker\")) {\n        throw fault(\"Missing `marker` or `fence` in matter `%j`\", result);\n      }\n      return result;\n    }\n    var 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]/;\n    var asciiAlpha = regexCheck(/[A-Za-z]/);\n    var asciiDigit = regexCheck(/\\d/);\n    var asciiHexDigit = regexCheck(/[\\dA-Fa-f]/);\n    var asciiAlphanumeric = regexCheck(/[\\dA-Za-z]/);\n    var asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/);\n    var asciiAtext = regexCheck(/[#-'*+\\--9=?A-Z^-~]/);\n    function asciiControl(code) {\n      return code !== null && (code < 32 || code === 127);\n    }\n    function markdownLineEndingOrSpace(code) {\n      return code !== null && (code < 0 || code === 32);\n    }\n    function markdownLineEnding(code) {\n      return code !== null && code < -2;\n    }\n    function markdownSpace(code) {\n      return code === -2 || code === -1 || code === 32;\n    }\n    var unicodeWhitespace = regexCheck(/\\s/);\n    var unicodePunctuation = regexCheck(unicodePunctuationRegex);\n    function regexCheck(regex) {\n      return check;\n      function check(code) {\n        return code !== null && regex.test(String.fromCharCode(code));\n      }\n    }\n    function frontmatter(options) {\n      const settings = matters(options);\n      const flow3 = {};\n      let index2 = -1;\n      let matter2;\n      let code;\n      while (++index2 < settings.length) {\n        matter2 = settings[index2];\n        code = fence(matter2, \"open\").charCodeAt(0);\n        if (code in flow3) {\n          flow3[code].push(parse(matter2));\n        } else {\n          flow3[code] = [parse(matter2)];\n        }\n      }\n      return {\n        flow: flow3\n      };\n    }\n    function parse(matter2) {\n      const name = matter2.type;\n      const anywhere = matter2.anywhere;\n      const valueType = name + \"Value\";\n      const fenceType = name + \"Fence\";\n      const sequenceType = fenceType + \"Sequence\";\n      const fenceConstruct = {\n        tokenize: tokenizeFence,\n        partial: true\n      };\n      let buffer2;\n      return {\n        tokenize: tokenizeFrontmatter,\n        concrete: true\n      };\n      function tokenizeFrontmatter(effects, ok, nok) {\n        const self2 = this;\n        return start;\n        function start(code) {\n          const position2 = self2.now();\n          if (position2.column !== 1 || !anywhere && position2.line !== 1) {\n            return nok(code);\n          }\n          effects.enter(name);\n          buffer2 = fence(matter2, \"open\");\n          return effects.attempt(fenceConstruct, afterOpeningFence, nok)(code);\n        }\n        function afterOpeningFence(code) {\n          buffer2 = fence(matter2, \"close\");\n          return lineEnd(code);\n        }\n        function lineStart(code) {\n          if (code === null || markdownLineEnding(code)) {\n            return lineEnd(code);\n          }\n          effects.enter(valueType);\n          return lineData(code);\n        }\n        function lineData(code) {\n          if (code === null || markdownLineEnding(code)) {\n            effects.exit(valueType);\n            return lineEnd(code);\n          }\n          effects.consume(code);\n          return lineData;\n        }\n        function lineEnd(code) {\n          if (code === null) {\n            return nok(code);\n          }\n          effects.enter(\"lineEnding\");\n          effects.consume(code);\n          effects.exit(\"lineEnding\");\n          return effects.attempt(fenceConstruct, after, lineStart);\n        }\n        function after(code) {\n          effects.exit(name);\n          return ok(code);\n        }\n      }\n      function tokenizeFence(effects, ok, nok) {\n        let bufferIndex = 0;\n        return start;\n        function start(code) {\n          if (code === buffer2.charCodeAt(bufferIndex)) {\n            effects.enter(fenceType);\n            effects.enter(sequenceType);\n            return insideSequence(code);\n          }\n          return nok(code);\n        }\n        function insideSequence(code) {\n          if (bufferIndex === buffer2.length) {\n            effects.exit(sequenceType);\n            if (markdownSpace(code)) {\n              effects.enter(\"whitespace\");\n              return insideWhitespace(code);\n            }\n            return fenceEnd(code);\n          }\n          if (code === buffer2.charCodeAt(bufferIndex++)) {\n            effects.consume(code);\n            return insideSequence;\n          }\n          return nok(code);\n        }\n        function insideWhitespace(code) {\n          if (markdownSpace(code)) {\n            effects.consume(code);\n            return insideWhitespace;\n          }\n          effects.exit(\"whitespace\");\n          return fenceEnd(code);\n        }\n        function fenceEnd(code) {\n          if (code === null || markdownLineEnding(code)) {\n            effects.exit(fenceType);\n            return ok(code);\n          }\n          return nok(code);\n        }\n      }\n    }\n    function fence(matter2, prop) {\n      return matter2.marker ? pick(matter2.marker, prop).repeat(3) : pick(matter2.fence, prop);\n    }\n    function pick(schema, prop) {\n      return typeof schema === \"string\" ? schema : schema[prop];\n    }\n    function frontmatterFromMarkdown(options) {\n      const settings = matters(options);\n      const enter = {};\n      const exit2 = {};\n      let index2 = -1;\n      while (++index2 < settings.length) {\n        const matter2 = settings[index2];\n        enter[matter2.type] = opener(matter2);\n        exit2[matter2.type] = close;\n        exit2[matter2.type + \"Value\"] = value;\n      }\n      return { enter, exit: exit2 };\n    }\n    function opener(matter2) {\n      return open;\n      function open(token) {\n        this.enter({ type: matter2.type, value: \"\" }, token);\n        this.buffer();\n      }\n    }\n    function close(token) {\n      const data = this.resume();\n      this.exit(token).value = data.replace(/^(\\r?\\n|\\r)|(\\r?\\n|\\r)$/g, \"\");\n    }\n    function value(token) {\n      this.config.enter.data.call(this, token);\n      this.config.exit.data.call(this, token);\n    }\n    function frontmatterToMarkdown(options) {\n      const unsafe = [];\n      const handlers = {};\n      const settings = matters(options);\n      let index2 = -1;\n      while (++index2 < settings.length) {\n        const matter2 = settings[index2];\n        handlers[matter2.type] = handler(matter2);\n        unsafe.push({ atBreak: true, character: fence2(matter2, \"open\").charAt(0) });\n      }\n      return { unsafe, handlers };\n    }\n    function handler(matter2) {\n      const open = fence2(matter2, \"open\");\n      const close2 = fence2(matter2, \"close\");\n      return handle;\n      function handle(node) {\n        return open + (node.value ? \"\\n\" + node.value : \"\") + \"\\n\" + close2;\n      }\n    }\n    function fence2(matter2, prop) {\n      return matter2.marker ? pick2(matter2.marker, prop).repeat(3) : pick2(matter2.fence, prop);\n    }\n    function pick2(schema, prop) {\n      return typeof schema === \"string\" ? schema : schema[prop];\n    }\n    function remarkFrontmatter(options = \"yaml\") {\n      const data = this.data();\n      add(\"micromarkExtensions\", frontmatter(options));\n      add(\"fromMarkdownExtensions\", frontmatterFromMarkdown(options));\n      add(\"toMarkdownExtensions\", frontmatterToMarkdown(options));\n      function add(field, value2) {\n        const list2 = data[field] ? data[field] : data[field] = [];\n        list2.push(value2);\n      }\n    }\n    function toString(node, options) {\n      var { includeImageAlt = true } = options || {};\n      return one(node, includeImageAlt);\n    }\n    function one(node, includeImageAlt) {\n      return node && typeof node === \"object\" && (node.value || (includeImageAlt ? node.alt : \"\") || \"children\" in node && all(node.children, includeImageAlt) || Array.isArray(node) && all(node, includeImageAlt)) || \"\";\n    }\n    function all(values, includeImageAlt) {\n      var result = [];\n      var index2 = -1;\n      while (++index2 < values.length) {\n        result[index2] = one(values[index2], includeImageAlt);\n      }\n      return result.join(\"\");\n    }\n    function splice(list2, start, remove, items) {\n      const end = list2.length;\n      let chunkStart = 0;\n      let parameters;\n      if (start < 0) {\n        start = -start > end ? 0 : end + start;\n      } else {\n        start = start > end ? end : start;\n      }\n      remove = remove > 0 ? remove : 0;\n      if (items.length < 1e4) {\n        parameters = Array.from(items);\n        parameters.unshift(start, remove);\n        [].splice.apply(list2, parameters);\n      } else {\n        if (remove)\n          [].splice.apply(list2, [start, remove]);\n        while (chunkStart < items.length) {\n          parameters = items.slice(chunkStart, chunkStart + 1e4);\n          parameters.unshift(start, 0);\n          [].splice.apply(list2, parameters);\n          chunkStart += 1e4;\n          start += 1e4;\n        }\n      }\n    }\n    function push(list2, items) {\n      if (list2.length > 0) {\n        splice(list2, list2.length, 0, items);\n        return list2;\n      }\n      return items;\n    }\n    var hasOwnProperty = {}.hasOwnProperty;\n    function combineExtensions(extensions) {\n      const all2 = {};\n      let index2 = -1;\n      while (++index2 < extensions.length) {\n        syntaxExtension(all2, extensions[index2]);\n      }\n      return all2;\n    }\n    function syntaxExtension(all2, extension2) {\n      let hook;\n      for (hook in extension2) {\n        const maybe = hasOwnProperty.call(all2, hook) ? all2[hook] : void 0;\n        const left = maybe || (all2[hook] = {});\n        const right = extension2[hook];\n        let code;\n        for (code in right) {\n          if (!hasOwnProperty.call(left, code))\n            left[code] = [];\n          const value2 = right[code];\n          constructs(left[code], Array.isArray(value2) ? value2 : value2 ? [value2] : []);\n        }\n      }\n    }\n    function constructs(existing, list2) {\n      let index2 = -1;\n      const before = [];\n      while (++index2 < list2.length) {\n        ;\n        (list2[index2].add === \"after\" ? existing : before).push(list2[index2]);\n      }\n      splice(existing, 0, 0, before);\n    }\n    function factorySpace(effects, ok, type, max) {\n      const limit = max ? max - 1 : Number.POSITIVE_INFINITY;\n      let size = 0;\n      return start;\n      function start(code) {\n        if (markdownSpace(code)) {\n          effects.enter(type);\n          return prefix(code);\n        }\n        return ok(code);\n      }\n      function prefix(code) {\n        if (markdownSpace(code) && size++ < limit) {\n          effects.consume(code);\n          return prefix;\n        }\n        effects.exit(type);\n        return ok(code);\n      }\n    }\n    var content = {\n      tokenize: initializeContent\n    };\n    function initializeContent(effects) {\n      const contentStart = effects.attempt(this.parser.constructs.contentInitial, afterContentStartConstruct, paragraphInitial);\n      let previous2;\n      return contentStart;\n      function afterContentStartConstruct(code) {\n        if (code === null) {\n          effects.consume(code);\n          return;\n        }\n        effects.enter(\"lineEnding\");\n        effects.consume(code);\n        effects.exit(\"lineEnding\");\n        return factorySpace(effects, contentStart, \"linePrefix\");\n      }\n      function paragraphInitial(code) {\n        effects.enter(\"paragraph\");\n        return lineStart(code);\n      }\n      function lineStart(code) {\n        const token = effects.enter(\"chunkText\", {\n          contentType: \"text\",\n          previous: previous2\n        });\n        if (previous2) {\n          previous2.next = token;\n        }\n        previous2 = token;\n        return data(code);\n      }\n      function data(code) {\n        if (code === null) {\n          effects.exit(\"chunkText\");\n          effects.exit(\"paragraph\");\n          effects.consume(code);\n          return;\n        }\n        if (markdownLineEnding(code)) {\n          effects.consume(code);\n          effects.exit(\"chunkText\");\n          return lineStart;\n        }\n        effects.consume(code);\n        return data;\n      }\n    }\n    var document2 = {\n      tokenize: initializeDocument\n    };\n    var containerConstruct = {\n      tokenize: tokenizeContainer\n    };\n    function initializeDocument(effects) {\n      const self2 = this;\n      const stack = [];\n      let continued = 0;\n      let childFlow;\n      let childToken;\n      let lineStartOffset;\n      return start;\n      function start(code) {\n        if (continued < stack.length) {\n          const item = stack[continued];\n          self2.containerState = item[1];\n          return effects.attempt(item[0].continuation, documentContinue, checkNewContainers)(code);\n        }\n        return checkNewContainers(code);\n      }\n      function documentContinue(code) {\n        continued++;\n        if (self2.containerState._closeFlow) {\n          self2.containerState._closeFlow = void 0;\n          if (childFlow) {\n            closeFlow();\n          }\n          const indexBeforeExits = self2.events.length;\n          let indexBeforeFlow = indexBeforeExits;\n          let point2;\n          while (indexBeforeFlow--) {\n            if (self2.events[indexBeforeFlow][0] === \"exit\" && self2.events[indexBeforeFlow][1].type === \"chunkFlow\") {\n              point2 = self2.events[indexBeforeFlow][1].end;\n              break;\n            }\n          }\n          exitContainers(continued);\n          let index2 = indexBeforeExits;\n          while (index2 < self2.events.length) {\n            self2.events[index2][1].end = Object.assign({}, point2);\n            index2++;\n          }\n          splice(self2.events, indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));\n          self2.events.length = index2;\n          return checkNewContainers(code);\n        }\n        return start(code);\n      }\n      function checkNewContainers(code) {\n        if (continued === stack.length) {\n          if (!childFlow) {\n            return documentContinued(code);\n          }\n          if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) {\n            return flowStart(code);\n          }\n          self2.interrupt = Boolean(childFlow.currentConstruct);\n        }\n        self2.containerState = {};\n        return effects.check(containerConstruct, thereIsANewContainer, thereIsNoNewContainer)(code);\n      }\n      function thereIsANewContainer(code) {\n        if (childFlow)\n          closeFlow();\n        exitContainers(continued);\n        return documentContinued(code);\n      }\n      function thereIsNoNewContainer(code) {\n        self2.parser.lazy[self2.now().line] = continued !== stack.length;\n        lineStartOffset = self2.now().offset;\n        return flowStart(code);\n      }\n      function documentContinued(code) {\n        self2.containerState = {};\n        return effects.attempt(containerConstruct, containerContinue, flowStart)(code);\n      }\n      function containerContinue(code) {\n        continued++;\n        stack.push([self2.currentConstruct, self2.containerState]);\n        return documentContinued(code);\n      }\n      function flowStart(code) {\n        if (code === null) {\n          if (childFlow)\n            closeFlow();\n          exitContainers(0);\n          effects.consume(code);\n          return;\n        }\n        childFlow = childFlow || self2.parser.flow(self2.now());\n        effects.enter(\"chunkFlow\", {\n          contentType: \"flow\",\n          previous: childToken,\n          _tokenizer: childFlow\n        });\n        return flowContinue(code);\n      }\n      function flowContinue(code) {\n        if (code === null) {\n          writeToChild(effects.exit(\"chunkFlow\"), true);\n          exitContainers(0);\n          effects.consume(code);\n          return;\n        }\n        if (markdownLineEnding(code)) {\n          effects.consume(code);\n          writeToChild(effects.exit(\"chunkFlow\"));\n          continued = 0;\n          self2.interrupt = void 0;\n          return start;\n        }\n        effects.consume(code);\n        return flowContinue;\n      }\n      function writeToChild(token, eof) {\n        const stream = self2.sliceStream(token);\n        if (eof)\n          stream.push(null);\n        token.previous = childToken;\n        if (childToken)\n          childToken.next = token;\n        childToken = token;\n        childFlow.defineSkip(token.start);\n        childFlow.write(stream);\n        if (self2.parser.lazy[token.start.line]) {\n          let index2 = childFlow.events.length;\n          while (index2--) {\n            if (childFlow.events[index2][1].start.offset < lineStartOffset && (!childFlow.events[index2][1].end || childFlow.events[index2][1].end.offset > lineStartOffset)) {\n              return;\n            }\n          }\n          const indexBeforeExits = self2.events.length;\n          let indexBeforeFlow = indexBeforeExits;\n          let seen;\n          let point2;\n          while (indexBeforeFlow--) {\n            if (self2.events[indexBeforeFlow][0] === \"exit\" && self2.events[indexBeforeFlow][1].type === \"chunkFlow\") {\n              if (seen) {\n                point2 = self2.events[indexBeforeFlow][1].end;\n                break;\n              }\n              seen = true;\n            }\n          }\n          exitContainers(continued);\n          index2 = indexBeforeExits;\n          while (index2 < self2.events.length) {\n            self2.events[index2][1].end = Object.assign({}, point2);\n            index2++;\n          }\n          splice(self2.events, indexBeforeFlow + 1, 0, self2.events.slice(indexBeforeExits));\n          self2.events.length = index2;\n        }\n      }\n      function exitContainers(size) {\n        let index2 = stack.length;\n        while (index2-- > size) {\n          const entry = stack[index2];\n          self2.containerState = entry[1];\n          entry[0].exit.call(self2, effects);\n        }\n        stack.length = size;\n      }\n      function closeFlow() {\n        childFlow.write([null]);\n        childToken = void 0;\n        childFlow = void 0;\n        self2.containerState._closeFlow = void 0;\n      }\n    }\n    function tokenizeContainer(effects, ok, nok) {\n      return factorySpace(effects, effects.attempt(this.parser.constructs.document, ok, nok), \"linePrefix\", this.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4);\n    }\n    function classifyCharacter(code) {\n      if (code === null || markdownLineEndingOrSpace(code) || unicodeWhitespace(code)) {\n        return 1;\n      }\n      if (unicodePunctuation(code)) {\n        return 2;\n      }\n    }\n    function resolveAll(constructs2, events, context) {\n      const called = [];\n      let index2 = -1;\n      while (++index2 < constructs2.length) {\n        const resolve = constructs2[index2].resolveAll;\n        if (resolve && !called.includes(resolve)) {\n          events = resolve(events, context);\n          called.push(resolve);\n        }\n      }\n      return events;\n    }\n    var attention = {\n      name: \"attention\",\n      tokenize: tokenizeAttention,\n      resolveAll: resolveAllAttention\n    };\n    function resolveAllAttention(events, context) {\n      let index2 = -1;\n      let open;\n      let group;\n      let text3;\n      let openingSequence;\n      let closingSequence;\n      let use;\n      let nextEvents;\n      let offset;\n      while (++index2 < events.length) {\n        if (events[index2][0] === \"enter\" && events[index2][1].type === \"attentionSequence\" && events[index2][1]._close) {\n          open = index2;\n          while (open--) {\n            if (events[open][0] === \"exit\" && events[open][1].type === \"attentionSequence\" && events[open][1]._open && context.sliceSerialize(events[open][1]).charCodeAt(0) === context.sliceSerialize(events[index2][1]).charCodeAt(0)) {\n              if ((events[open][1]._close || events[index2][1]._open) && (events[index2][1].end.offset - events[index2][1].start.offset) % 3 && !((events[open][1].end.offset - events[open][1].start.offset + events[index2][1].end.offset - events[index2][1].start.offset) % 3)) {\n                continue;\n              }\n              use = events[open][1].end.offset - events[open][1].start.offset > 1 && events[index2][1].end.offset - events[index2][1].start.offset > 1 ? 2 : 1;\n              const start = Object.assign({}, events[open][1].end);\n              const end = Object.assign({}, events[index2][1].start);\n              movePoint(start, -use);\n              movePoint(end, use);\n              openingSequence = {\n                type: use > 1 ? \"strongSequence\" : \"emphasisSequence\",\n                start,\n                end: Object.assign({}, events[open][1].end)\n              };\n              closingSequence = {\n                type: use > 1 ? \"strongSequence\" : \"emphasisSequence\",\n                start: Object.assign({}, events[index2][1].start),\n                end\n              };\n              text3 = {\n                type: use > 1 ? \"strongText\" : \"emphasisText\",\n                start: Object.assign({}, events[open][1].end),\n                end: Object.assign({}, events[index2][1].start)\n              };\n              group = {\n                type: use > 1 ? \"strong\" : \"emphasis\",\n                start: Object.assign({}, openingSequence.start),\n                end: Object.assign({}, closingSequence.end)\n              };\n              events[open][1].end = Object.assign({}, openingSequence.start);\n              events[index2][1].start = Object.assign({}, closingSequence.end);\n              nextEvents = [];\n              if (events[open][1].end.offset - events[open][1].start.offset) {\n                nextEvents = push(nextEvents, [\n                  [\"enter\", events[open][1], context],\n                  [\"exit\", events[open][1], context]\n                ]);\n              }\n              nextEvents = push(nextEvents, [\n                [\"enter\", group, context],\n                [\"enter\", openingSequence, context],\n                [\"exit\", openingSequence, context],\n                [\"enter\", text3, context]\n              ]);\n              nextEvents = push(nextEvents, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + 1, index2), context));\n              nextEvents = push(nextEvents, [\n                [\"exit\", text3, context],\n                [\"enter\", closingSequence, context],\n                [\"exit\", closingSequence, context],\n                [\"exit\", group, context]\n              ]);\n              if (events[index2][1].end.offset - events[index2][1].start.offset) {\n                offset = 2;\n                nextEvents = push(nextEvents, [\n                  [\"enter\", events[index2][1], context],\n                  [\"exit\", events[index2][1], context]\n                ]);\n              } else {\n                offset = 0;\n              }\n              splice(events, open - 1, index2 - open + 3, nextEvents);\n              index2 = open + nextEvents.length - offset - 2;\n              break;\n            }\n          }\n        }\n      }\n      index2 = -1;\n      while (++index2 < events.length) {\n        if (events[index2][1].type === \"attentionSequence\") {\n          events[index2][1].type = \"data\";\n        }\n      }\n      return events;\n    }\n    function tokenizeAttention(effects, ok) {\n      const attentionMarkers2 = this.parser.constructs.attentionMarkers.null;\n      const previous2 = this.previous;\n      const before = classifyCharacter(previous2);\n      let marker;\n      return start;\n      function start(code) {\n        effects.enter(\"attentionSequence\");\n        marker = code;\n        return sequence(code);\n      }\n      function sequence(code) {\n        if (code === marker) {\n          effects.consume(code);\n          return sequence;\n        }\n        const token = effects.exit(\"attentionSequence\");\n        const after = classifyCharacter(code);\n        const open = !after || after === 2 && before || attentionMarkers2.includes(code);\n        const close2 = !before || before === 2 && after || attentionMarkers2.includes(previous2);\n        token._open = Boolean(marker === 42 ? open : open && (before || !close2));\n        token._close = Boolean(marker === 42 ? close2 : close2 && (after || !open));\n        return ok(code);\n      }\n    }\n    function movePoint(point2, offset) {\n      point2.column += offset;\n      point2.offset += offset;\n      point2._bufferIndex += offset;\n    }\n    var autolink = {\n      name: \"autolink\",\n      tokenize: tokenizeAutolink\n    };\n    function tokenizeAutolink(effects, ok, nok) {\n      let size = 1;\n      return start;\n      function start(code) {\n        effects.enter(\"autolink\");\n        effects.enter(\"autolinkMarker\");\n        effects.consume(code);\n        effects.exit(\"autolinkMarker\");\n        effects.enter(\"autolinkProtocol\");\n        return open;\n      }\n      function open(code) {\n        if (asciiAlpha(code)) {\n          effects.consume(code);\n          return schemeOrEmailAtext;\n        }\n        return asciiAtext(code) ? emailAtext(code) : nok(code);\n      }\n      function schemeOrEmailAtext(code) {\n        return code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code) ? schemeInsideOrEmailAtext(code) : emailAtext(code);\n      }\n      function schemeInsideOrEmailAtext(code) {\n        if (code === 58) {\n          effects.consume(code);\n          return urlInside;\n        }\n        if ((code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) && size++ < 32) {\n          effects.consume(code);\n          return schemeInsideOrEmailAtext;\n        }\n        return emailAtext(code);\n      }\n      function urlInside(code) {\n        if (code === 62) {\n          effects.exit(\"autolinkProtocol\");\n          return end(code);\n        }\n        if (code === null || code === 32 || code === 60 || asciiControl(code)) {\n          return nok(code);\n        }\n        effects.consume(code);\n        return urlInside;\n      }\n      function emailAtext(code) {\n        if (code === 64) {\n          effects.consume(code);\n          size = 0;\n          return emailAtSignOrDot;\n        }\n        if (asciiAtext(code)) {\n          effects.consume(code);\n          return emailAtext;\n        }\n        return nok(code);\n      }\n      function emailAtSignOrDot(code) {\n        return asciiAlphanumeric(code) ? emailLabel(code) : nok(code);\n      }\n      function emailLabel(code) {\n        if (code === 46) {\n          effects.consume(code);\n          size = 0;\n          return emailAtSignOrDot;\n        }\n        if (code === 62) {\n          effects.exit(\"autolinkProtocol\").type = \"autolinkEmail\";\n          return end(code);\n        }\n        return emailValue(code);\n      }\n      function emailValue(code) {\n        if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) {\n          effects.consume(code);\n          return code === 45 ? emailValue : emailLabel;\n        }\n        return nok(code);\n      }\n      function end(code) {\n        effects.enter(\"autolinkMarker\");\n        effects.consume(code);\n        effects.exit(\"autolinkMarker\");\n        effects.exit(\"autolink\");\n        return ok;\n      }\n    }\n    var blankLine = {\n      tokenize: tokenizeBlankLine,\n      partial: true\n    };\n    function tokenizeBlankLine(effects, ok, nok) {\n      return factorySpace(effects, afterWhitespace, \"linePrefix\");\n      function afterWhitespace(code) {\n        return code === null || markdownLineEnding(code) ? ok(code) : nok(code);\n      }\n    }\n    var blockQuote = {\n      name: \"blockQuote\",\n      tokenize: tokenizeBlockQuoteStart,\n      continuation: {\n        tokenize: tokenizeBlockQuoteContinuation\n      },\n      exit\n    };\n    function tokenizeBlockQuoteStart(effects, ok, nok) {\n      const self2 = this;\n      return start;\n      function start(code) {\n        if (code === 62) {\n          const state = self2.containerState;\n          if (!state.open) {\n            effects.enter(\"blockQuote\", {\n              _container: true\n            });\n            state.open = true;\n          }\n          effects.enter(\"blockQuotePrefix\");\n          effects.enter(\"blockQuoteMarker\");\n          effects.consume(code);\n          effects.exit(\"blockQuoteMarker\");\n          return after;\n        }\n        return nok(code);\n      }\n      function after(code) {\n        if (markdownSpace(code)) {\n          effects.enter(\"blockQuotePrefixWhitespace\");\n          effects.consume(code);\n          effects.exit(\"blockQuotePrefixWhitespace\");\n          effects.exit(\"blockQuotePrefix\");\n          return ok;\n        }\n        effects.exit(\"blockQuotePrefix\");\n        return ok(code);\n      }\n    }\n    function tokenizeBlockQuoteContinuation(effects, ok, nok) {\n      return factorySpace(effects, effects.attempt(blockQuote, ok, nok), \"linePrefix\", this.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4);\n    }\n    function exit(effects) {\n      effects.exit(\"blockQuote\");\n    }\n    var characterEscape = {\n      name: \"characterEscape\",\n      tokenize: tokenizeCharacterEscape\n    };\n    function tokenizeCharacterEscape(effects, ok, nok) {\n      return start;\n      function start(code) {\n        effects.enter(\"characterEscape\");\n        effects.enter(\"escapeMarker\");\n        effects.consume(code);\n        effects.exit(\"escapeMarker\");\n        return open;\n      }\n      function open(code) {\n        if (asciiPunctuation(code)) {\n          effects.enter(\"characterEscapeValue\");\n          effects.consume(code);\n          effects.exit(\"characterEscapeValue\");\n          effects.exit(\"characterEscape\");\n          return ok;\n        }\n        return nok(code);\n      }\n    }\n    var semicolon = 59;\n    var element;\n    function decodeEntity(characters) {\n      var entity = \"&\" + characters + \";\";\n      var char;\n      element = element || document.createElement(\"i\");\n      element.innerHTML = entity;\n      char = element.textContent;\n      if (char.charCodeAt(char.length - 1) === semicolon && characters !== \"semi\") {\n        return false;\n      }\n      return char === entity ? false : char;\n    }\n    var characterReference = {\n      name: \"characterReference\",\n      tokenize: tokenizeCharacterReference\n    };\n    function tokenizeCharacterReference(effects, ok, nok) {\n      const self2 = this;\n      let size = 0;\n      let max;\n      let test;\n      return start;\n      function start(code) {\n        effects.enter(\"characterReference\");\n        effects.enter(\"characterReferenceMarker\");\n        effects.consume(code);\n        effects.exit(\"characterReferenceMarker\");\n        return open;\n      }\n      function open(code) {\n        if (code === 35) {\n          effects.enter(\"characterReferenceMarkerNumeric\");\n          effects.consume(code);\n          effects.exit(\"characterReferenceMarkerNumeric\");\n          return numeric;\n        }\n        effects.enter(\"characterReferenceValue\");\n        max = 31;\n        test = asciiAlphanumeric;\n        return value2(code);\n      }\n      function numeric(code) {\n        if (code === 88 || code === 120) {\n          effects.enter(\"characterReferenceMarkerHexadecimal\");\n          effects.consume(code);\n          effects.exit(\"characterReferenceMarkerHexadecimal\");\n          effects.enter(\"characterReferenceValue\");\n          max = 6;\n          test = asciiHexDigit;\n          return value2;\n        }\n        effects.enter(\"characterReferenceValue\");\n        max = 7;\n        test = asciiDigit;\n        return value2(code);\n      }\n      function value2(code) {\n        let token;\n        if (code === 59 && size) {\n          token = effects.exit(\"characterReferenceValue\");\n          if (test === asciiAlphanumeric && !decodeEntity(self2.sliceSerialize(token))) {\n            return nok(code);\n          }\n          effects.enter(\"characterReferenceMarker\");\n          effects.consume(code);\n          effects.exit(\"characterReferenceMarker\");\n          effects.exit(\"characterReference\");\n          return ok;\n        }\n        if (test(code) && size++ < max) {\n          effects.consume(code);\n          return value2;\n        }\n        return nok(code);\n      }\n    }\n    var codeFenced = {\n      name: \"codeFenced\",\n      tokenize: tokenizeCodeFenced,\n      concrete: true\n    };\n    function tokenizeCodeFenced(effects, ok, nok) {\n      const self2 = this;\n      const closingFenceConstruct = {\n        tokenize: tokenizeClosingFence,\n        partial: true\n      };\n      const nonLazyLine = {\n        tokenize: tokenizeNonLazyLine,\n        partial: true\n      };\n      const tail = this.events[this.events.length - 1];\n      const initialPrefix = tail && tail[1].type === \"linePrefix\" ? tail[2].sliceSerialize(tail[1], true).length : 0;\n      let sizeOpen = 0;\n      let marker;\n      return start;\n      function start(code) {\n        effects.enter(\"codeFenced\");\n        effects.enter(\"codeFencedFence\");\n        effects.enter(\"codeFencedFenceSequence\");\n        marker = code;\n        return sequenceOpen(code);\n      }\n      function sequenceOpen(code) {\n        if (code === marker) {\n          effects.consume(code);\n          sizeOpen++;\n          return sequenceOpen;\n        }\n        effects.exit(\"codeFencedFenceSequence\");\n        return sizeOpen < 3 ? nok(code) : factorySpace(effects, infoOpen, \"whitespace\")(code);\n      }\n      function infoOpen(code) {\n        if (code === null || markdownLineEnding(code)) {\n          return openAfter(code);\n        }\n        effects.enter(\"codeFencedFenceInfo\");\n        effects.enter(\"chunkString\", {\n          contentType: \"string\"\n        });\n        return info(code);\n      }\n      function info(code) {\n        if (code === null || markdownLineEndingOrSpace(code)) {\n          effects.exit(\"chunkString\");\n          effects.exit(\"codeFencedFenceInfo\");\n          return factorySpace(effects, infoAfter, \"whitespace\")(code);\n        }\n        if (code === 96 && code === marker)\n          return nok(code);\n        effects.consume(code);\n        return info;\n      }\n      function infoAfter(code) {\n        if (code === null || markdownLineEnding(code)) {\n          return openAfter(code);\n        }\n        effects.enter(\"codeFencedFenceMeta\");\n        effects.enter(\"chunkString\", {\n          contentType: \"string\"\n        });\n        return meta(code);\n      }\n      function meta(code) {\n        if (code === null || markdownLineEnding(code)) {\n          effects.exit(\"chunkString\");\n          effects.exit(\"codeFencedFenceMeta\");\n          return openAfter(code);\n        }\n        if (code === 96 && code === marker)\n          return nok(code);\n        effects.consume(code);\n        return meta;\n      }\n      function openAfter(code) {\n        effects.exit(\"codeFencedFence\");\n        return self2.interrupt ? ok(code) : contentStart(code);\n      }\n      function contentStart(code) {\n        if (code === null) {\n          return after(code);\n        }\n        if (markdownLineEnding(code)) {\n          return effects.attempt(nonLazyLine, effects.attempt(closingFenceConstruct, after, initialPrefix ? factorySpace(effects, contentStart, \"linePrefix\", initialPrefix + 1) : contentStart), after)(code);\n        }\n        effects.enter(\"codeFlowValue\");\n        return contentContinue(code);\n      }\n      function contentContinue(code) {\n        if (code === null || markdownLineEnding(code)) {\n          effects.exit(\"codeFlowValue\");\n          return contentStart(code);\n        }\n        effects.consume(code);\n        return contentContinue;\n      }\n      function after(code) {\n        effects.exit(\"codeFenced\");\n        return ok(code);\n      }\n      function tokenizeNonLazyLine(effects2, ok2, nok2) {\n        const self22 = this;\n        return start2;\n        function start2(code) {\n          effects2.enter(\"lineEnding\");\n          effects2.consume(code);\n          effects2.exit(\"lineEnding\");\n          return lineStart;\n        }\n        function lineStart(code) {\n          return self22.parser.lazy[self22.now().line] ? nok2(code) : ok2(code);\n        }\n      }\n      function tokenizeClosingFence(effects2, ok2, nok2) {\n        let size = 0;\n        return factorySpace(effects2, closingSequenceStart, \"linePrefix\", this.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4);\n        function closingSequenceStart(code) {\n          effects2.enter(\"codeFencedFence\");\n          effects2.enter(\"codeFencedFenceSequence\");\n          return closingSequence(code);\n        }\n        function closingSequence(code) {\n          if (code === marker) {\n            effects2.consume(code);\n            size++;\n            return closingSequence;\n          }\n          if (size < sizeOpen)\n            return nok2(code);\n          effects2.exit(\"codeFencedFenceSequence\");\n          return factorySpace(effects2, closingSequenceEnd, \"whitespace\")(code);\n        }\n        function closingSequenceEnd(code) {\n          if (code === null || markdownLineEnding(code)) {\n            effects2.exit(\"codeFencedFence\");\n            return ok2(code);\n          }\n          return nok2(code);\n        }\n      }\n    }\n    var codeIndented = {\n      name: \"codeIndented\",\n      tokenize: tokenizeCodeIndented\n    };\n    var indentedContent = {\n      tokenize: tokenizeIndentedContent,\n      partial: true\n    };\n    function tokenizeCodeIndented(effects, ok, nok) {\n      const self2 = this;\n      return start;\n      function start(code) {\n        effects.enter(\"codeIndented\");\n        return factorySpace(effects, afterStartPrefix, \"linePrefix\", 4 + 1)(code);\n      }\n      function afterStartPrefix(code) {\n        const tail = self2.events[self2.events.length - 1];\n        return tail && tail[1].type === \"linePrefix\" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? afterPrefix(code) : nok(code);\n      }\n      function afterPrefix(code) {\n        if (code === null) {\n          return after(code);\n        }\n        if (markdownLineEnding(code)) {\n          return effects.attempt(indentedContent, afterPrefix, after)(code);\n        }\n        effects.enter(\"codeFlowValue\");\n        return content3(code);\n      }\n      function content3(code) {\n        if (code === null || markdownLineEnding(code)) {\n          effects.exit(\"codeFlowValue\");\n          return afterPrefix(code);\n        }\n        effects.consume(code);\n        return content3;\n      }\n      function after(code) {\n        effects.exit(\"codeIndented\");\n        return ok(code);\n      }\n    }\n    function tokenizeIndentedContent(effects, ok, nok) {\n      const self2 = this;\n      return start;\n      function start(code) {\n        if (self2.parser.lazy[self2.now().line]) {\n          return nok(code);\n        }\n        if (markdownLineEnding(code)) {\n          effects.enter(\"lineEnding\");\n          effects.consume(code);\n          effects.exit(\"lineEnding\");\n          return start;\n        }\n        return factorySpace(effects, afterPrefix, \"linePrefix\", 4 + 1)(code);\n      }\n      function afterPrefix(code) {\n        const tail = self2.events[self2.events.length - 1];\n        return tail && tail[1].type === \"linePrefix\" && tail[2].sliceSerialize(tail[1], true).length >= 4 ? ok(code) : markdownLineEnding(code) ? start(code) : nok(code);\n      }\n    }\n    var codeText = {\n      name: \"codeText\",\n      tokenize: tokenizeCodeText,\n      resolve: resolveCodeText,\n      previous\n    };\n    function resolveCodeText(events) {\n      let tailExitIndex = events.length - 4;\n      let headEnterIndex = 3;\n      let index2;\n      let enter;\n      if ((events[headEnterIndex][1].type === \"lineEnding\" || events[headEnterIndex][1].type === \"space\") && (events[tailExitIndex][1].type === \"lineEnding\" || events[tailExitIndex][1].type === \"space\")) {\n        index2 = headEnterIndex;\n        while (++index2 < tailExitIndex) {\n          if (events[index2][1].type === \"codeTextData\") {\n            events[headEnterIndex][1].type = \"codeTextPadding\";\n            events[tailExitIndex][1].type = \"codeTextPadding\";\n            headEnterIndex += 2;\n            tailExitIndex -= 2;\n            break;\n          }\n        }\n      }\n      index2 = headEnterIndex - 1;\n      tailExitIndex++;\n      while (++index2 <= tailExitIndex) {\n        if (enter === void 0) {\n          if (index2 !== tailExitIndex && events[index2][1].type !== \"lineEnding\") {\n            enter = index2;\n          }\n        } else if (index2 === tailExitIndex || events[index2][1].type === \"lineEnding\") {\n          events[enter][1].type = \"codeTextData\";\n          if (index2 !== enter + 2) {\n            events[enter][1].end = events[index2 - 1][1].end;\n            events.splice(enter + 2, index2 - enter - 2);\n            tailExitIndex -= index2 - enter - 2;\n            index2 = enter + 2;\n          }\n          enter = void 0;\n        }\n      }\n      return events;\n    }\n    function previous(code) {\n      return code !== 96 || this.events[this.events.length - 1][1].type === \"characterEscape\";\n    }\n    function tokenizeCodeText(effects, ok, nok) {\n      const self2 = this;\n      let sizeOpen = 0;\n      let size;\n      let token;\n      return start;\n      function start(code) {\n        effects.enter(\"codeText\");\n        effects.enter(\"codeTextSequence\");\n        return openingSequence(code);\n      }\n      function openingSequence(code) {\n        if (code === 96) {\n          effects.consume(code);\n          sizeOpen++;\n          return openingSequence;\n        }\n        effects.exit(\"codeTextSequence\");\n        return gap(code);\n      }\n      function gap(code) {\n        if (code === null) {\n          return nok(code);\n        }\n        if (code === 96) {\n          token = effects.enter(\"codeTextSequence\");\n          size = 0;\n          return closingSequence(code);\n        }\n        if (code === 32) {\n          effects.enter(\"space\");\n          effects.consume(code);\n          effects.exit(\"space\");\n          return gap;\n        }\n        if (markdownLineEnding(code)) {\n          effects.enter(\"lineEnding\");\n          effects.consume(code);\n          effects.exit(\"lineEnding\");\n          return gap;\n        }\n        effects.enter(\"codeTextData\");\n        return data(code);\n      }\n      function data(code) {\n        if (code === null || code === 32 || code === 96 || markdownLineEnding(code)) {\n          effects.exit(\"codeTextData\");\n          return gap(code);\n        }\n        effects.consume(code);\n        return data;\n      }\n      function closingSequence(code) {\n        if (code === 96) {\n          effects.consume(code);\n          size++;\n          return closingSequence;\n        }\n        if (size === sizeOpen) {\n          effects.exit(\"codeTextSequence\");\n          effects.exit(\"codeText\");\n          return ok(code);\n        }\n        token.type = \"codeTextData\";\n        return data(code);\n      }\n    }\n    function subtokenize(events) {\n      const jumps = {};\n      let index2 = -1;\n      let event;\n      let lineIndex;\n      let otherIndex;\n      let otherEvent;\n      let parameters;\n      let subevents;\n      let more;\n      while (++index2 < events.length) {\n        while (index2 in jumps) {\n          index2 = jumps[index2];\n        }\n        event = events[index2];\n        if (index2 && event[1].type === \"chunkFlow\" && events[index2 - 1][1].type === \"listItemPrefix\") {\n          subevents = event[1]._tokenizer.events;\n          otherIndex = 0;\n          if (otherIndex < subevents.length && subevents[otherIndex][1].type === \"lineEndingBlank\") {\n            otherIndex += 2;\n          }\n          if (otherIndex < subevents.length && subevents[otherIndex][1].type === \"content\") {\n            while (++otherIndex < subevents.length) {\n              if (subevents[otherIndex][1].type === \"content\") {\n                break;\n              }\n              if (subevents[otherIndex][1].type === \"chunkText\") {\n                subevents[otherIndex][1]._isInFirstContentOfListItem = true;\n                otherIndex++;\n              }\n            }\n          }\n        }\n        if (event[0] === \"enter\") {\n          if (event[1].contentType) {\n            Object.assign(jumps, subcontent(events, index2));\n            index2 = jumps[index2];\n            more = true;\n          }\n        } else if (event[1]._container) {\n          otherIndex = index2;\n          lineIndex = void 0;\n          while (otherIndex--) {\n            otherEvent = events[otherIndex];\n            if (otherEvent[1].type === \"lineEnding\" || otherEvent[1].type === \"lineEndingBlank\") {\n              if (otherEvent[0] === \"enter\") {\n                if (lineIndex) {\n                  events[lineIndex][1].type = \"lineEndingBlank\";\n                }\n                otherEvent[1].type = \"lineEnding\";\n                lineIndex = otherIndex;\n              }\n            } else {\n              break;\n            }\n          }\n          if (lineIndex) {\n            event[1].end = Object.assign({}, events[lineIndex][1].start);\n            parameters = events.slice(lineIndex, index2);\n            parameters.unshift(event);\n            splice(events, lineIndex, index2 - lineIndex + 1, parameters);\n          }\n        }\n      }\n      return !more;\n    }\n    function subcontent(events, eventIndex) {\n      const token = events[eventIndex][1];\n      const context = events[eventIndex][2];\n      let startPosition = eventIndex - 1;\n      const startPositions = [];\n      const tokenizer = token._tokenizer || context.parser[token.contentType](token.start);\n      const childEvents = tokenizer.events;\n      const jumps = [];\n      const gaps = {};\n      let stream;\n      let previous2;\n      let index2 = -1;\n      let current = token;\n      let adjust = 0;\n      let start = 0;\n      const breaks = [start];\n      while (current) {\n        while (events[++startPosition][1] !== current) {\n        }\n        startPositions.push(startPosition);\n        if (!current._tokenizer) {\n          stream = context.sliceStream(current);\n          if (!current.next) {\n            stream.push(null);\n          }\n          if (previous2) {\n            tokenizer.defineSkip(current.start);\n          }\n          if (current._isInFirstContentOfListItem) {\n            tokenizer._gfmTasklistFirstContentOfListItem = true;\n          }\n          tokenizer.write(stream);\n          if (current._isInFirstContentOfListItem) {\n            tokenizer._gfmTasklistFirstContentOfListItem = void 0;\n          }\n        }\n        previous2 = current;\n        current = current.next;\n      }\n      current = token;\n      while (++index2 < childEvents.length) {\n        if (childEvents[index2][0] === \"exit\" && childEvents[index2 - 1][0] === \"enter\" && childEvents[index2][1].type === childEvents[index2 - 1][1].type && childEvents[index2][1].start.line !== childEvents[index2][1].end.line) {\n          start = index2 + 1;\n          breaks.push(start);\n          current._tokenizer = void 0;\n          current.previous = void 0;\n          current = current.next;\n        }\n      }\n      tokenizer.events = [];\n      if (current) {\n        current._tokenizer = void 0;\n        current.previous = void 0;\n      } else {\n        breaks.pop();\n      }\n      index2 = breaks.length;\n      while (index2--) {\n        const slice = childEvents.slice(breaks[index2], breaks[index2 + 1]);\n        const start2 = startPositions.pop();\n        jumps.unshift([start2, start2 + slice.length - 1]);\n        splice(events, start2, 2, slice);\n      }\n      index2 = -1;\n      while (++index2 < jumps.length) {\n        gaps[adjust + jumps[index2][0]] = adjust + jumps[index2][1];\n        adjust += jumps[index2][1] - jumps[index2][0] - 1;\n      }\n      return gaps;\n    }\n    var content2 = {\n      tokenize: tokenizeContent,\n      resolve: resolveContent\n    };\n    var continuationConstruct = {\n      tokenize: tokenizeContinuation,\n      partial: true\n    };\n    function resolveContent(events) {\n      subtokenize(events);\n      return events;\n    }\n    function tokenizeContent(effects, ok) {\n      let previous2;\n      return start;\n      function start(code) {\n        effects.enter(\"content\");\n        previous2 = effects.enter(\"chunkContent\", {\n          contentType: \"content\"\n        });\n        return data(code);\n      }\n      function data(code) {\n        if (code === null) {\n          return contentEnd(code);\n        }\n        if (markdownLineEnding(code)) {\n          return effects.check(continuationConstruct, contentContinue, contentEnd)(code);\n        }\n        effects.consume(code);\n        return data;\n      }\n      function contentEnd(code) {\n        effects.exit(\"chunkContent\");\n        effects.exit(\"content\");\n        return ok(code);\n      }\n      function contentContinue(code) {\n        effects.consume(code);\n        effects.exit(\"chunkContent\");\n        previous2.next = effects.enter(\"chunkContent\", {\n          contentType: \"content\",\n          previous: previous2\n        });\n        previous2 = previous2.next;\n        return data;\n      }\n    }\n    function tokenizeContinuation(effects, ok, nok) {\n      const self2 = this;\n      return startLookahead;\n      function startLookahead(code) {\n        effects.exit(\"chunkContent\");\n        effects.enter(\"lineEnding\");\n        effects.consume(code);\n        effects.exit(\"lineEnding\");\n        return factorySpace(effects, prefixed, \"linePrefix\");\n      }\n      function prefixed(code) {\n        if (code === null || markdownLineEnding(code)) {\n          return nok(code);\n        }\n        const tail = self2.events[self2.events.length - 1];\n        if (!self2.parser.constructs.disable.null.includes(\"codeIndented\") && tail && tail[1].type === \"linePrefix\" && tail[2].sliceSerialize(tail[1], true).length >= 4) {\n          return ok(code);\n        }\n        return effects.interrupt(self2.parser.constructs.flow, nok, ok)(code);\n      }\n    }\n    function factoryDestination(effects, ok, nok, type, literalType, literalMarkerType, rawType, stringType, max) {\n      const limit = max || Number.POSITIVE_INFINITY;\n      let balance = 0;\n      return start;\n      function start(code) {\n        if (code === 60) {\n          effects.enter(type);\n          effects.enter(literalType);\n          effects.enter(literalMarkerType);\n          effects.consume(code);\n          effects.exit(literalMarkerType);\n          return destinationEnclosedBefore;\n        }\n        if (code === null || code === 41 || asciiControl(code)) {\n          return nok(code);\n        }\n        effects.enter(type);\n        effects.enter(rawType);\n        effects.enter(stringType);\n        effects.enter(\"chunkString\", {\n          contentType: \"string\"\n        });\n        return destinationRaw(code);\n      }\n      function destinationEnclosedBefore(code) {\n        if (code === 62) {\n          effects.enter(literalMarkerType);\n          effects.consume(code);\n          effects.exit(literalMarkerType);\n          effects.exit(literalType);\n          effects.exit(type);\n          return ok;\n        }\n        effects.enter(stringType);\n        effects.enter(\"chunkString\", {\n          contentType: \"string\"\n        });\n        return destinationEnclosed(code);\n      }\n      function destinationEnclosed(code) {\n        if (code === 62) {\n          effects.exit(\"chunkString\");\n          effects.exit(stringType);\n          return destinationEnclosedBefore(code);\n        }\n        if (code === null || code === 60 || markdownLineEnding(code)) {\n          return nok(code);\n        }\n        effects.consume(code);\n        return code === 92 ? destinationEnclosedEscape : destinationEnclosed;\n      }\n      function destinationEnclosedEscape(code) {\n        if (code === 60 || code === 62 || code === 92) {\n          effects.consume(code);\n          return destinationEnclosed;\n        }\n        return destinationEnclosed(code);\n      }\n      function destinationRaw(code) {\n        if (code === 40) {\n          if (++balance > limit)\n            return nok(code);\n          effects.consume(code);\n          return destinationRaw;\n        }\n        if (code === 41) {\n          if (!balance--) {\n            effects.exit(\"chunkString\");\n            effects.exit(stringType);\n            effects.exit(rawType);\n            effects.exit(type);\n            return ok(code);\n          }\n          effects.consume(code);\n          return destinationRaw;\n        }\n        if (code === null || markdownLineEndingOrSpace(code)) {\n          if (balance)\n            return nok(code);\n          effects.exit(\"chunkString\");\n          effects.exit(stringType);\n          effects.exit(rawType);\n          effects.exit(type);\n          return ok(code);\n        }\n        if (asciiControl(code))\n          return nok(code);\n        effects.consume(code);\n        return code === 92 ? destinationRawEscape : destinationRaw;\n      }\n      function destinationRawEscape(code) {\n        if (code === 40 || code === 41 || code === 92) {\n          effects.consume(code);\n          return destinationRaw;\n        }\n        return destinationRaw(code);\n      }\n    }\n    function factoryLabel(effects, ok, nok, type, markerType, stringType) {\n      const self2 = this;\n      let size = 0;\n      let data;\n      return start;\n      function start(code) {\n        effects.enter(type);\n        effects.enter(markerType);\n        effects.consume(code);\n        effects.exit(markerType);\n        effects.enter(stringType);\n        return atBreak;\n      }\n      function atBreak(code) {\n        if (code === null || code === 91 || code === 93 && !data || code === 94 && !size && \"_hiddenFootnoteSupport\" in self2.parser.constructs || size > 999) {\n          return nok(code);\n        }\n        if (code === 93) {\n          effects.exit(stringType);\n          effects.enter(markerType);\n          effects.consume(code);\n          effects.exit(markerType);\n          effects.exit(type);\n          return ok;\n        }\n        if (markdownLineEnding(code)) {\n          effects.enter(\"lineEnding\");\n          effects.consume(code);\n          effects.exit(\"lineEnding\");\n          return atBreak;\n        }\n        effects.enter(\"chunkString\", {\n          contentType: \"string\"\n        });\n        return label(code);\n      }\n      function label(code) {\n        if (code === null || code === 91 || code === 93 || markdownLineEnding(code) || size++ > 999) {\n          effects.exit(\"chunkString\");\n          return atBreak(code);\n        }\n        effects.consume(code);\n        data = data || !markdownSpace(code);\n        return code === 92 ? labelEscape : label;\n      }\n      function labelEscape(code) {\n        if (code === 91 || code === 92 || code === 93) {\n          effects.consume(code);\n          size++;\n          return label;\n        }\n        return label(code);\n      }\n    }\n    function factoryTitle(effects, ok, nok, type, markerType, stringType) {\n      let marker;\n      return start;\n      function start(code) {\n        effects.enter(type);\n        effects.enter(markerType);\n        effects.consume(code);\n        effects.exit(markerType);\n        marker = code === 40 ? 41 : code;\n        return atFirstTitleBreak;\n      }\n      function atFirstTitleBreak(code) {\n        if (code === marker) {\n          effects.enter(markerType);\n          effects.consume(code);\n          effects.exit(markerType);\n          effects.exit(type);\n          return ok;\n        }\n        effects.enter(stringType);\n        return atTitleBreak(code);\n      }\n      function atTitleBreak(code) {\n        if (code === marker) {\n          effects.exit(stringType);\n          return atFirstTitleBreak(marker);\n        }\n        if (code === null) {\n          return nok(code);\n        }\n        if (markdownLineEnding(code)) {\n          effects.enter(\"lineEnding\");\n          effects.consume(code);\n          effects.exit(\"lineEnding\");\n          return factorySpace(effects, atTitleBreak, \"linePrefix\");\n        }\n        effects.enter(\"chunkString\", {\n          contentType: \"string\"\n        });\n        return title(code);\n      }\n      function title(code) {\n        if (code === marker || code === null || markdownLineEnding(code)) {\n          effects.exit(\"chunkString\");\n          return atTitleBreak(code);\n        }\n        effects.consume(code);\n        return code === 92 ? titleEscape : title;\n      }\n      function titleEscape(code) {\n        if (code === marker || code === 92) {\n          effects.consume(code);\n          return title;\n        }\n        return title(code);\n      }\n    }\n    function factoryWhitespace(effects, ok) {\n      let seen;\n      return start;\n      function start(code) {\n        if (markdownLineEnding(code)) {\n          effects.enter(\"lineEnding\");\n          effects.consume(code);\n          effects.exit(\"lineEnding\");\n          seen = true;\n          return start;\n        }\n        if (markdownSpace(code)) {\n          return factorySpace(effects, start, seen ? \"linePrefix\" : \"lineSuffix\")(code);\n        }\n        return ok(code);\n      }\n    }\n    function normalizeIdentifier(value2) {\n      return value2.replace(/[\\t\\n\\r ]+/g, \" \").replace(/^ | $/g, \"\").toLowerCase().toUpperCase();\n    }\n    var definition = {\n      name: \"definition\",\n      tokenize: tokenizeDefinition\n    };\n    var titleConstruct = {\n      tokenize: tokenizeTitle,\n      partial: true\n    };\n    function tokenizeDefinition(effects, ok, nok) {\n      const self2 = this;\n      let identifier;\n      return start;\n      function start(code) {\n        effects.enter(\"definition\");\n        return factoryLabel.call(self2, effects, labelAfter, nok, \"definitionLabel\", \"definitionLabelMarker\", \"definitionLabelString\")(code);\n      }\n      function labelAfter(code) {\n        identifier = normalizeIdentifier(self2.sliceSerialize(self2.events[self2.events.length - 1][1]).slice(1, -1));\n        if (code === 58) {\n          effects.enter(\"definitionMarker\");\n          effects.consume(code);\n          effects.exit(\"definitionMarker\");\n          return factoryWhitespace(effects, factoryDestination(effects, effects.attempt(titleConstruct, factorySpace(effects, after, \"whitespace\"), factorySpace(effects, after, \"whitespace\")), nok, \"definitionDestination\", \"definitionDestinationLiteral\", \"definitionDestinationLiteralMarker\", \"definitionDestinationRaw\", \"definitionDestinationString\"));\n        }\n        return nok(code);\n      }\n      function after(code) {\n        if (code === null || markdownLineEnding(code)) {\n          effects.exit(\"definition\");\n          if (!self2.parser.defined.includes(identifier)) {\n            self2.parser.defined.push(identifier);\n          }\n          return ok(code);\n        }\n        return nok(code);\n      }\n    }\n    function tokenizeTitle(effects, ok, nok) {\n      return start;\n      function start(code) {\n        return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, before)(code) : nok(code);\n      }\n      function before(code) {\n        if (code === 34 || code === 39 || code === 40) {\n          return factoryTitle(effects, factorySpace(effects, after, \"whitespace\"), nok, \"definitionTitle\", \"definitionTitleMarker\", \"definitionTitleString\")(code);\n        }\n        return nok(code);\n      }\n      function after(code) {\n        return code === null || markdownLineEnding(code) ? ok(code) : nok(code);\n      }\n    }\n    var hardBreakEscape = {\n      name: \"hardBreakEscape\",\n      tokenize: tokenizeHardBreakEscape\n    };\n    function tokenizeHardBreakEscape(effects, ok, nok) {\n      return start;\n      function start(code) {\n        effects.enter(\"hardBreakEscape\");\n        effects.enter(\"escapeMarker\");\n        effects.consume(code);\n        return open;\n      }\n      function open(code) {\n        if (markdownLineEnding(code)) {\n          effects.exit(\"escapeMarker\");\n          effects.exit(\"hardBreakEscape\");\n          return ok(code);\n        }\n        return nok(code);\n      }\n    }\n    var headingAtx = {\n      name: \"headingAtx\",\n      tokenize: tokenizeHeadingAtx,\n      resolve: resolveHeadingAtx\n    };\n    function resolveHeadingAtx(events, context) {\n      let contentEnd = events.length - 2;\n      let contentStart = 3;\n      let content3;\n      let text3;\n      if (events[contentStart][1].type === \"whitespace\") {\n        contentStart += 2;\n      }\n      if (contentEnd - 2 > contentStart && events[contentEnd][1].type === \"whitespace\") {\n        contentEnd -= 2;\n      }\n      if (events[contentEnd][1].type === \"atxHeadingSequence\" && (contentStart === contentEnd - 1 || contentEnd - 4 > contentStart && events[contentEnd - 2][1].type === \"whitespace\")) {\n        contentEnd -= contentStart + 1 === contentEnd ? 2 : 4;\n      }\n      if (contentEnd > contentStart) {\n        content3 = {\n          type: \"atxHeadingText\",\n          start: events[contentStart][1].start,\n          end: events[contentEnd][1].end\n        };\n        text3 = {\n          type: \"chunkText\",\n          start: events[contentStart][1].start,\n          end: events[contentEnd][1].end,\n          contentType: \"text\"\n        };\n        splice(events, contentStart, contentEnd - contentStart + 1, [\n          [\"enter\", content3, context],\n          [\"enter\", text3, context],\n          [\"exit\", text3, context],\n          [\"exit\", content3, context]\n        ]);\n      }\n      return events;\n    }\n    function tokenizeHeadingAtx(effects, ok, nok) {\n      const self2 = this;\n      let size = 0;\n      return start;\n      function start(code) {\n        effects.enter(\"atxHeading\");\n        effects.enter(\"atxHeadingSequence\");\n        return fenceOpenInside(code);\n      }\n      function fenceOpenInside(code) {\n        if (code === 35 && size++ < 6) {\n          effects.consume(code);\n          return fenceOpenInside;\n        }\n        if (code === null || markdownLineEndingOrSpace(code)) {\n          effects.exit(\"atxHeadingSequence\");\n          return self2.interrupt ? ok(code) : headingBreak(code);\n        }\n        return nok(code);\n      }\n      function headingBreak(code) {\n        if (code === 35) {\n          effects.enter(\"atxHeadingSequence\");\n          return sequence(code);\n        }\n        if (code === null || markdownLineEnding(code)) {\n          effects.exit(\"atxHeading\");\n          return ok(code);\n        }\n        if (markdownSpace(code)) {\n          return factorySpace(effects, headingBreak, \"whitespace\")(code);\n        }\n        effects.enter(\"atxHeadingText\");\n        return data(code);\n      }\n      function sequence(code) {\n        if (code === 35) {\n          effects.consume(code);\n          return sequence;\n        }\n        effects.exit(\"atxHeadingSequence\");\n        return headingBreak(code);\n      }\n      function data(code) {\n        if (code === null || code === 35 || markdownLineEndingOrSpace(code)) {\n          effects.exit(\"atxHeadingText\");\n          return headingBreak(code);\n        }\n        effects.consume(code);\n        return data;\n      }\n    }\n    var htmlBlockNames = [\n      \"address\",\n      \"article\",\n      \"aside\",\n      \"base\",\n      \"basefont\",\n      \"blockquote\",\n      \"body\",\n      \"caption\",\n      \"center\",\n      \"col\",\n      \"colgroup\",\n      \"dd\",\n      \"details\",\n      \"dialog\",\n      \"dir\",\n      \"div\",\n      \"dl\",\n      \"dt\",\n      \"fieldset\",\n      \"figcaption\",\n      \"figure\",\n      \"footer\",\n      \"form\",\n      \"frame\",\n      \"frameset\",\n      \"h1\",\n      \"h2\",\n      \"h3\",\n      \"h4\",\n      \"h5\",\n      \"h6\",\n      \"head\",\n      \"header\",\n      \"hr\",\n      \"html\",\n      \"iframe\",\n      \"legend\",\n      \"li\",\n      \"link\",\n      \"main\",\n      \"menu\",\n      \"menuitem\",\n      \"nav\",\n      \"noframes\",\n      \"ol\",\n      \"optgroup\",\n      \"option\",\n      \"p\",\n      \"param\",\n      \"section\",\n      \"source\",\n      \"summary\",\n      \"table\",\n      \"tbody\",\n      \"td\",\n      \"tfoot\",\n      \"th\",\n      \"thead\",\n      \"title\",\n      \"tr\",\n      \"track\",\n      \"ul\"\n    ];\n    var htmlRawNames = [\"pre\", \"script\", \"style\", \"textarea\"];\n    var htmlFlow = {\n      name: \"htmlFlow\",\n      tokenize: tokenizeHtmlFlow,\n      resolveTo: resolveToHtmlFlow,\n      concrete: true\n    };\n    var nextBlankConstruct = {\n      tokenize: tokenizeNextBlank,\n      partial: true\n    };\n    function resolveToHtmlFlow(events) {\n      let index2 = events.length;\n      while (index2--) {\n        if (events[index2][0] === \"enter\" && events[index2][1].type === \"htmlFlow\") {\n          break;\n        }\n      }\n      if (index2 > 1 && events[index2 - 2][1].type === \"linePrefix\") {\n        events[index2][1].start = events[index2 - 2][1].start;\n        events[index2 + 1][1].start = events[index2 - 2][1].start;\n        events.splice(index2 - 2, 2);\n      }\n      return events;\n    }\n    function tokenizeHtmlFlow(effects, ok, nok) {\n      const self2 = this;\n      let kind;\n      let startTag;\n      let buffer2;\n      let index2;\n      let marker;\n      return start;\n      function start(code) {\n        effects.enter(\"htmlFlow\");\n        effects.enter(\"htmlFlowData\");\n        effects.consume(code);\n        return open;\n      }\n      function open(code) {\n        if (code === 33) {\n          effects.consume(code);\n          return declarationStart;\n        }\n        if (code === 47) {\n          effects.consume(code);\n          return tagCloseStart;\n        }\n        if (code === 63) {\n          effects.consume(code);\n          kind = 3;\n          return self2.interrupt ? ok : continuationDeclarationInside;\n        }\n        if (asciiAlpha(code)) {\n          effects.consume(code);\n          buffer2 = String.fromCharCode(code);\n          startTag = true;\n          return tagName;\n        }\n        return nok(code);\n      }\n      function declarationStart(code) {\n        if (code === 45) {\n          effects.consume(code);\n          kind = 2;\n          return commentOpenInside;\n        }\n        if (code === 91) {\n          effects.consume(code);\n          kind = 5;\n          buffer2 = \"CDATA[\";\n          index2 = 0;\n          return cdataOpenInside;\n        }\n        if (asciiAlpha(code)) {\n          effects.consume(code);\n          kind = 4;\n          return self2.interrupt ? ok : continuationDeclarationInside;\n        }\n        return nok(code);\n      }\n      function commentOpenInside(code) {\n        if (code === 45) {\n          effects.consume(code);\n          return self2.interrupt ? ok : continuationDeclarationInside;\n        }\n        return nok(code);\n      }\n      function cdataOpenInside(code) {\n        if (code === buffer2.charCodeAt(index2++)) {\n          effects.consume(code);\n          return index2 === buffer2.length ? self2.interrupt ? ok : continuation : cdataOpenInside;\n        }\n        return nok(code);\n      }\n      function tagCloseStart(code) {\n        if (asciiAlpha(code)) {\n          effects.consume(code);\n          buffer2 = String.fromCharCode(code);\n          return tagName;\n        }\n        return nok(code);\n      }\n      function tagName(code) {\n        if (code === null || code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {\n          if (code !== 47 && startTag && htmlRawNames.includes(buffer2.toLowerCase())) {\n            kind = 1;\n            return self2.interrupt ? ok(code) : continuation(code);\n          }\n          if (htmlBlockNames.includes(buffer2.toLowerCase())) {\n            kind = 6;\n            if (code === 47) {\n              effects.consume(code);\n              return basicSelfClosing;\n            }\n            return self2.interrupt ? ok(code) : continuation(code);\n          }\n          kind = 7;\n          return self2.interrupt && !self2.parser.lazy[self2.now().line] ? nok(code) : startTag ? completeAttributeNameBefore(code) : completeClosingTagAfter(code);\n        }\n        if (code === 45 || asciiAlphanumeric(code)) {\n          effects.consume(code);\n          buffer2 += String.fromCharCode(code);\n          return tagName;\n        }\n        return nok(code);\n      }\n      function basicSelfClosing(code) {\n        if (code === 62) {\n          effects.consume(code);\n          return self2.interrupt ? ok : continuation;\n        }\n        return nok(code);\n      }\n      function completeClosingTagAfter(code) {\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return completeClosingTagAfter;\n        }\n        return completeEnd(code);\n      }\n      function completeAttributeNameBefore(code) {\n        if (code === 47) {\n          effects.consume(code);\n          return completeEnd;\n        }\n        if (code === 58 || code === 95 || asciiAlpha(code)) {\n          effects.consume(code);\n          return completeAttributeName;\n        }\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return completeAttributeNameBefore;\n        }\n        return completeEnd(code);\n      }\n      function completeAttributeName(code) {\n        if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) {\n          effects.consume(code);\n          return completeAttributeName;\n        }\n        return completeAttributeNameAfter(code);\n      }\n      function completeAttributeNameAfter(code) {\n        if (code === 61) {\n          effects.consume(code);\n          return completeAttributeValueBefore;\n        }\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return completeAttributeNameAfter;\n        }\n        return completeAttributeNameBefore(code);\n      }\n      function completeAttributeValueBefore(code) {\n        if (code === null || code === 60 || code === 61 || code === 62 || code === 96) {\n          return nok(code);\n        }\n        if (code === 34 || code === 39) {\n          effects.consume(code);\n          marker = code;\n          return completeAttributeValueQuoted;\n        }\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return completeAttributeValueBefore;\n        }\n        marker = null;\n        return completeAttributeValueUnquoted(code);\n      }\n      function completeAttributeValueQuoted(code) {\n        if (code === null || markdownLineEnding(code)) {\n          return nok(code);\n        }\n        if (code === marker) {\n          effects.consume(code);\n          return completeAttributeValueQuotedAfter;\n        }\n        effects.consume(code);\n        return completeAttributeValueQuoted;\n      }\n      function completeAttributeValueUnquoted(code) {\n        if (code === null || code === 34 || code === 39 || code === 60 || code === 61 || code === 62 || code === 96 || markdownLineEndingOrSpace(code)) {\n          return completeAttributeNameAfter(code);\n        }\n        effects.consume(code);\n        return completeAttributeValueUnquoted;\n      }\n      function completeAttributeValueQuotedAfter(code) {\n        if (code === 47 || code === 62 || markdownSpace(code)) {\n          return completeAttributeNameBefore(code);\n        }\n        return nok(code);\n      }\n      function completeEnd(code) {\n        if (code === 62) {\n          effects.consume(code);\n          return completeAfter;\n        }\n        return nok(code);\n      }\n      function completeAfter(code) {\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return completeAfter;\n        }\n        return code === null || markdownLineEnding(code) ? continuation(code) : nok(code);\n      }\n      function continuation(code) {\n        if (code === 45 && kind === 2) {\n          effects.consume(code);\n          return continuationCommentInside;\n        }\n        if (code === 60 && kind === 1) {\n          effects.consume(code);\n          return continuationRawTagOpen;\n        }\n        if (code === 62 && kind === 4) {\n          effects.consume(code);\n          return continuationClose;\n        }\n        if (code === 63 && kind === 3) {\n          effects.consume(code);\n          return continuationDeclarationInside;\n        }\n        if (code === 93 && kind === 5) {\n          effects.consume(code);\n          return continuationCharacterDataInside;\n        }\n        if (markdownLineEnding(code) && (kind === 6 || kind === 7)) {\n          return effects.check(nextBlankConstruct, continuationClose, continuationAtLineEnding)(code);\n        }\n        if (code === null || markdownLineEnding(code)) {\n          return continuationAtLineEnding(code);\n        }\n        effects.consume(code);\n        return continuation;\n      }\n      function continuationAtLineEnding(code) {\n        effects.exit(\"htmlFlowData\");\n        return htmlContinueStart(code);\n      }\n      function htmlContinueStart(code) {\n        if (code === null) {\n          return done(code);\n        }\n        if (markdownLineEnding(code)) {\n          return effects.attempt({\n            tokenize: htmlLineEnd,\n            partial: true\n          }, htmlContinueStart, done)(code);\n        }\n        effects.enter(\"htmlFlowData\");\n        return continuation(code);\n      }\n      function htmlLineEnd(effects2, ok2, nok2) {\n        return start2;\n        function start2(code) {\n          effects2.enter(\"lineEnding\");\n          effects2.consume(code);\n          effects2.exit(\"lineEnding\");\n          return lineStart;\n        }\n        function lineStart(code) {\n          return self2.parser.lazy[self2.now().line] ? nok2(code) : ok2(code);\n        }\n      }\n      function continuationCommentInside(code) {\n        if (code === 45) {\n          effects.consume(code);\n          return continuationDeclarationInside;\n        }\n        return continuation(code);\n      }\n      function continuationRawTagOpen(code) {\n        if (code === 47) {\n          effects.consume(code);\n          buffer2 = \"\";\n          return continuationRawEndTag;\n        }\n        return continuation(code);\n      }\n      function continuationRawEndTag(code) {\n        if (code === 62 && htmlRawNames.includes(buffer2.toLowerCase())) {\n          effects.consume(code);\n          return continuationClose;\n        }\n        if (asciiAlpha(code) && buffer2.length < 8) {\n          effects.consume(code);\n          buffer2 += String.fromCharCode(code);\n          return continuationRawEndTag;\n        }\n        return continuation(code);\n      }\n      function continuationCharacterDataInside(code) {\n        if (code === 93) {\n          effects.consume(code);\n          return continuationDeclarationInside;\n        }\n        return continuation(code);\n      }\n      function continuationDeclarationInside(code) {\n        if (code === 62) {\n          effects.consume(code);\n          return continuationClose;\n        }\n        return continuation(code);\n      }\n      function continuationClose(code) {\n        if (code === null || markdownLineEnding(code)) {\n          effects.exit(\"htmlFlowData\");\n          return done(code);\n        }\n        effects.consume(code);\n        return continuationClose;\n      }\n      function done(code) {\n        effects.exit(\"htmlFlow\");\n        return ok(code);\n      }\n    }\n    function tokenizeNextBlank(effects, ok, nok) {\n      return start;\n      function start(code) {\n        effects.exit(\"htmlFlowData\");\n        effects.enter(\"lineEndingBlank\");\n        effects.consume(code);\n        effects.exit(\"lineEndingBlank\");\n        return effects.attempt(blankLine, ok, nok);\n      }\n    }\n    var htmlText = {\n      name: \"htmlText\",\n      tokenize: tokenizeHtmlText\n    };\n    function tokenizeHtmlText(effects, ok, nok) {\n      const self2 = this;\n      let marker;\n      let buffer2;\n      let index2;\n      let returnState;\n      return start;\n      function start(code) {\n        effects.enter(\"htmlText\");\n        effects.enter(\"htmlTextData\");\n        effects.consume(code);\n        return open;\n      }\n      function open(code) {\n        if (code === 33) {\n          effects.consume(code);\n          return declarationOpen;\n        }\n        if (code === 47) {\n          effects.consume(code);\n          return tagCloseStart;\n        }\n        if (code === 63) {\n          effects.consume(code);\n          return instruction;\n        }\n        if (asciiAlpha(code)) {\n          effects.consume(code);\n          return tagOpen;\n        }\n        return nok(code);\n      }\n      function declarationOpen(code) {\n        if (code === 45) {\n          effects.consume(code);\n          return commentOpen;\n        }\n        if (code === 91) {\n          effects.consume(code);\n          buffer2 = \"CDATA[\";\n          index2 = 0;\n          return cdataOpen;\n        }\n        if (asciiAlpha(code)) {\n          effects.consume(code);\n          return declaration;\n        }\n        return nok(code);\n      }\n      function commentOpen(code) {\n        if (code === 45) {\n          effects.consume(code);\n          return commentStart;\n        }\n        return nok(code);\n      }\n      function commentStart(code) {\n        if (code === null || code === 62) {\n          return nok(code);\n        }\n        if (code === 45) {\n          effects.consume(code);\n          return commentStartDash;\n        }\n        return comment(code);\n      }\n      function commentStartDash(code) {\n        if (code === null || code === 62) {\n          return nok(code);\n        }\n        return comment(code);\n      }\n      function comment(code) {\n        if (code === null) {\n          return nok(code);\n        }\n        if (code === 45) {\n          effects.consume(code);\n          return commentClose;\n        }\n        if (markdownLineEnding(code)) {\n          returnState = comment;\n          return atLineEnding(code);\n        }\n        effects.consume(code);\n        return comment;\n      }\n      function commentClose(code) {\n        if (code === 45) {\n          effects.consume(code);\n          return end;\n        }\n        return comment(code);\n      }\n      function cdataOpen(code) {\n        if (code === buffer2.charCodeAt(index2++)) {\n          effects.consume(code);\n          return index2 === buffer2.length ? cdata : cdataOpen;\n        }\n        return nok(code);\n      }\n      function cdata(code) {\n        if (code === null) {\n          return nok(code);\n        }\n        if (code === 93) {\n          effects.consume(code);\n          return cdataClose;\n        }\n        if (markdownLineEnding(code)) {\n          returnState = cdata;\n          return atLineEnding(code);\n        }\n        effects.consume(code);\n        return cdata;\n      }\n      function cdataClose(code) {\n        if (code === 93) {\n          effects.consume(code);\n          return cdataEnd;\n        }\n        return cdata(code);\n      }\n      function cdataEnd(code) {\n        if (code === 62) {\n          return end(code);\n        }\n        if (code === 93) {\n          effects.consume(code);\n          return cdataEnd;\n        }\n        return cdata(code);\n      }\n      function declaration(code) {\n        if (code === null || code === 62) {\n          return end(code);\n        }\n        if (markdownLineEnding(code)) {\n          returnState = declaration;\n          return atLineEnding(code);\n        }\n        effects.consume(code);\n        return declaration;\n      }\n      function instruction(code) {\n        if (code === null) {\n          return nok(code);\n        }\n        if (code === 63) {\n          effects.consume(code);\n          return instructionClose;\n        }\n        if (markdownLineEnding(code)) {\n          returnState = instruction;\n          return atLineEnding(code);\n        }\n        effects.consume(code);\n        return instruction;\n      }\n      function instructionClose(code) {\n        return code === 62 ? end(code) : instruction(code);\n      }\n      function tagCloseStart(code) {\n        if (asciiAlpha(code)) {\n          effects.consume(code);\n          return tagClose;\n        }\n        return nok(code);\n      }\n      function tagClose(code) {\n        if (code === 45 || asciiAlphanumeric(code)) {\n          effects.consume(code);\n          return tagClose;\n        }\n        return tagCloseBetween(code);\n      }\n      function tagCloseBetween(code) {\n        if (markdownLineEnding(code)) {\n          returnState = tagCloseBetween;\n          return atLineEnding(code);\n        }\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return tagCloseBetween;\n        }\n        return end(code);\n      }\n      function tagOpen(code) {\n        if (code === 45 || asciiAlphanumeric(code)) {\n          effects.consume(code);\n          return tagOpen;\n        }\n        if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {\n          return tagOpenBetween(code);\n        }\n        return nok(code);\n      }\n      function tagOpenBetween(code) {\n        if (code === 47) {\n          effects.consume(code);\n          return end;\n        }\n        if (code === 58 || code === 95 || asciiAlpha(code)) {\n          effects.consume(code);\n          return tagOpenAttributeName;\n        }\n        if (markdownLineEnding(code)) {\n          returnState = tagOpenBetween;\n          return atLineEnding(code);\n        }\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return tagOpenBetween;\n        }\n        return end(code);\n      }\n      function tagOpenAttributeName(code) {\n        if (code === 45 || code === 46 || code === 58 || code === 95 || asciiAlphanumeric(code)) {\n          effects.consume(code);\n          return tagOpenAttributeName;\n        }\n        return tagOpenAttributeNameAfter(code);\n      }\n      function tagOpenAttributeNameAfter(code) {\n        if (code === 61) {\n          effects.consume(code);\n          return tagOpenAttributeValueBefore;\n        }\n        if (markdownLineEnding(code)) {\n          returnState = tagOpenAttributeNameAfter;\n          return atLineEnding(code);\n        }\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return tagOpenAttributeNameAfter;\n        }\n        return tagOpenBetween(code);\n      }\n      function tagOpenAttributeValueBefore(code) {\n        if (code === null || code === 60 || code === 61 || code === 62 || code === 96) {\n          return nok(code);\n        }\n        if (code === 34 || code === 39) {\n          effects.consume(code);\n          marker = code;\n          return tagOpenAttributeValueQuoted;\n        }\n        if (markdownLineEnding(code)) {\n          returnState = tagOpenAttributeValueBefore;\n          return atLineEnding(code);\n        }\n        if (markdownSpace(code)) {\n          effects.consume(code);\n          return tagOpenAttributeValueBefore;\n        }\n        effects.consume(code);\n        marker = void 0;\n        return tagOpenAttributeValueUnquoted;\n      }\n      function tagOpenAttributeValueQuoted(code) {\n        if (code === marker) {\n          effects.consume(code);\n          return tagOpenAttributeValueQuotedAfter;\n        }\n        if (code === null) {\n          return nok(code);\n        }\n        if (markdownLineEnding(code)) {\n          returnState = tagOpenAttributeValueQuoted;\n          return atLineEnding(code);\n        }\n        effects.consume(code);\n        return tagOpenAttributeValueQuoted;\n      }\n      function tagOpenAttributeValueQuotedAfter(code) {\n        if (code === 62 || code === 47 || markdownLineEndingOrSpace(code)) {\n          return tagOpenBetween(code);\n        }\n        return nok(code);\n      }\n      function tagOpenAttributeValueUnquoted(code) {\n        if (code === null || code === 34 || code === 39 || code === 60 || code === 61 || code === 96) {\n          return nok(code);\n        }\n        if (code === 62 || markdownLineEndingOrSpace(code)) {\n          return tagOpenBetween(code);\n        }\n        effects.consume(code);\n        return tagOpenAttributeValueUnquoted;\n      }\n      function atLineEnding(code) {\n        effects.exit(\"htmlTextData\");\n        effects.enter(\"lineEnding\");\n        effects.consume(code);\n        effects.exit(\"lineEnding\");\n        return factorySpace(effects, afterPrefix, \"linePrefix\", self2.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4);\n      }\n      function afterPrefix(code) {\n        effects.enter(\"htmlTextData\");\n        return returnState(code);\n      }\n      function end(code) {\n        if (code === 62) {\n          effects.consume(code);\n          effects.exit(\"htmlTextData\");\n          effects.exit(\"htmlText\");\n          return ok;\n        }\n        return nok(code);\n      }\n    }\n    var labelEnd = {\n      name: \"labelEnd\",\n      tokenize: tokenizeLabelEnd,\n      resolveTo: resolveToLabelEnd,\n      resolveAll: resolveAllLabelEnd\n    };\n    var resourceConstruct = {\n      tokenize: tokenizeResource\n    };\n    var fullReferenceConstruct = {\n      tokenize: tokenizeFullReference\n    };\n    var collapsedReferenceConstruct = {\n      tokenize: tokenizeCollapsedReference\n    };\n    function resolveAllLabelEnd(events) {\n      let index2 = -1;\n      let token;\n      while (++index2 < events.length) {\n        token = events[index2][1];\n        if (token.type === \"labelImage\" || token.type === \"labelLink\" || token.type === \"labelEnd\") {\n          events.splice(index2 + 1, token.type === \"labelImage\" ? 4 : 2);\n          token.type = \"data\";\n          index2++;\n        }\n      }\n      return events;\n    }\n    function resolveToLabelEnd(events, context) {\n      let index2 = events.length;\n      let offset = 0;\n      let token;\n      let open;\n      let close2;\n      let media;\n      while (index2--) {\n        token = events[index2][1];\n        if (open) {\n          if (token.type === \"link\" || token.type === \"labelLink\" && token._inactive) {\n            break;\n          }\n          if (events[index2][0] === \"enter\" && token.type === \"labelLink\") {\n            token._inactive = true;\n          }\n        } else if (close2) {\n          if (events[index2][0] === \"enter\" && (token.type === \"labelImage\" || token.type === \"labelLink\") && !token._balanced) {\n            open = index2;\n            if (token.type !== \"labelLink\") {\n              offset = 2;\n              break;\n            }\n          }\n        } else if (token.type === \"labelEnd\") {\n          close2 = index2;\n        }\n      }\n      const group = {\n        type: events[open][1].type === \"labelLink\" ? \"link\" : \"image\",\n        start: Object.assign({}, events[open][1].start),\n        end: Object.assign({}, events[events.length - 1][1].end)\n      };\n      const label = {\n        type: \"label\",\n        start: Object.assign({}, events[open][1].start),\n        end: Object.assign({}, events[close2][1].end)\n      };\n      const text3 = {\n        type: \"labelText\",\n        start: Object.assign({}, events[open + offset + 2][1].end),\n        end: Object.assign({}, events[close2 - 2][1].start)\n      };\n      media = [\n        [\"enter\", group, context],\n        [\"enter\", label, context]\n      ];\n      media = push(media, events.slice(open + 1, open + offset + 3));\n      media = push(media, [[\"enter\", text3, context]]);\n      media = push(media, resolveAll(context.parser.constructs.insideSpan.null, events.slice(open + offset + 4, close2 - 3), context));\n      media = push(media, [\n        [\"exit\", text3, context],\n        events[close2 - 2],\n        events[close2 - 1],\n        [\"exit\", label, context]\n      ]);\n      media = push(media, events.slice(close2 + 1));\n      media = push(media, [[\"exit\", group, context]]);\n      splice(events, open, events.length, media);\n      return events;\n    }\n    function tokenizeLabelEnd(effects, ok, nok) {\n      const self2 = this;\n      let index2 = self2.events.length;\n      let labelStart;\n      let defined;\n      while (index2--) {\n        if ((self2.events[index2][1].type === \"labelImage\" || self2.events[index2][1].type === \"labelLink\") && !self2.events[index2][1]._balanced) {\n          labelStart = self2.events[index2][1];\n          break;\n        }\n      }\n      return start;\n      function start(code) {\n        if (!labelStart) {\n          return nok(code);\n        }\n        if (labelStart._inactive)\n          return balanced(code);\n        defined = self2.parser.defined.includes(normalizeIdentifier(self2.sliceSerialize({\n          start: labelStart.end,\n          end: self2.now()\n        })));\n        effects.enter(\"labelEnd\");\n        effects.enter(\"labelMarker\");\n        effects.consume(code);\n        effects.exit(\"labelMarker\");\n        effects.exit(\"labelEnd\");\n        return afterLabelEnd;\n      }\n      function afterLabelEnd(code) {\n        if (code === 40) {\n          return effects.attempt(resourceConstruct, ok, defined ? ok : balanced)(code);\n        }\n        if (code === 91) {\n          return effects.attempt(fullReferenceConstruct, ok, defined ? effects.attempt(collapsedReferenceConstruct, ok, balanced) : balanced)(code);\n        }\n        return defined ? ok(code) : balanced(code);\n      }\n      function balanced(code) {\n        labelStart._balanced = true;\n        return nok(code);\n      }\n    }\n    function tokenizeResource(effects, ok, nok) {\n      return start;\n      function start(code) {\n        effects.enter(\"resource\");\n        effects.enter(\"resourceMarker\");\n        effects.consume(code);\n        effects.exit(\"resourceMarker\");\n        return factoryWhitespace(effects, open);\n      }\n      function open(code) {\n        if (code === 41) {\n          return end(code);\n        }\n        return factoryDestination(effects, destinationAfter, nok, \"resourceDestination\", \"resourceDestinationLiteral\", \"resourceDestinationLiteralMarker\", \"resourceDestinationRaw\", \"resourceDestinationString\", 3)(code);\n      }\n      function destinationAfter(code) {\n        return markdownLineEndingOrSpace(code) ? factoryWhitespace(effects, between)(code) : end(code);\n      }\n      function between(code) {\n        if (code === 34 || code === 39 || code === 40) {\n          return factoryTitle(effects, factoryWhitespace(effects, end), nok, \"resourceTitle\", \"resourceTitleMarker\", \"resourceTitleString\")(code);\n        }\n        return end(code);\n      }\n      function end(code) {\n        if (code === 41) {\n          effects.enter(\"resourceMarker\");\n          effects.consume(code);\n          effects.exit(\"resourceMarker\");\n          effects.exit(\"resource\");\n          return ok;\n        }\n        return nok(code);\n      }\n    }\n    function tokenizeFullReference(effects, ok, nok) {\n      const self2 = this;\n      return start;\n      function start(code) {\n        return factoryLabel.call(self2, effects, afterLabel, nok, \"reference\", \"referenceMarker\", \"referenceString\")(code);\n      }\n      function afterLabel(code) {\n        return self2.parser.defined.includes(normalizeIdentifier(self2.sliceSerialize(self2.events[self2.events.length - 1][1]).slice(1, -1))) ? ok(code) : nok(code);\n      }\n    }\n    function tokenizeCollapsedReference(effects, ok, nok) {\n      return start;\n      function start(code) {\n        effects.enter(\"reference\");\n        effects.enter(\"referenceMarker\");\n        effects.consume(code);\n        effects.exit(\"referenceMarker\");\n        return open;\n      }\n      function open(code) {\n        if (code === 93) {\n          effects.enter(\"referenceMarker\");\n          effects.consume(code);\n          effects.exit(\"referenceMarker\");\n          effects.exit(\"reference\");\n          return ok;\n        }\n        return nok(code);\n      }\n    }\n    var labelStartImage = {\n      name: \"labelStartImage\",\n      tokenize: tokenizeLabelStartImage,\n      resolveAll: labelEnd.resolveAll\n    };\n    function tokenizeLabelStartImage(effects, ok, nok) {\n      const self2 = this;\n      return start;\n      function start(code) {\n        effects.enter(\"labelImage\");\n        effects.enter(\"labelImageMarker\");\n        effects.consume(code);\n        effects.exit(\"labelImageMarker\");\n        return open;\n      }\n      function open(code) {\n        if (code === 91) {\n          effects.enter(\"labelMarker\");\n          effects.consume(code);\n          effects.exit(\"labelMarker\");\n          effects.exit(\"labelImage\");\n          return after;\n        }\n        return nok(code);\n      }\n      function after(code) {\n        return code === 94 && \"_hiddenFootnoteSupport\" in self2.parser.constructs ? nok(code) : ok(code);\n      }\n    }\n    var labelStartLink = {\n      name: \"labelStartLink\",\n      tokenize: tokenizeLabelStartLink,\n      resolveAll: labelEnd.resolveAll\n    };\n    function tokenizeLabelStartLink(effects, ok, nok) {\n      const self2 = this;\n      return start;\n      function start(code) {\n        effects.enter(\"labelLink\");\n        effects.enter(\"labelMarker\");\n        effects.consume(code);\n        effects.exit(\"labelMarker\");\n        effects.exit(\"labelLink\");\n        return after;\n      }\n      function after(code) {\n        return code === 94 && \"_hiddenFootnoteSupport\" in self2.parser.constructs ? nok(code) : ok(code);\n      }\n    }\n    var lineEnding = {\n      name: \"lineEnding\",\n      tokenize: tokenizeLineEnding\n    };\n    function tokenizeLineEnding(effects, ok) {\n      return start;\n      function start(code) {\n        effects.enter(\"lineEnding\");\n        effects.consume(code);\n        effects.exit(\"lineEnding\");\n        return factorySpace(effects, ok, \"linePrefix\");\n      }\n    }\n    var thematicBreak = {\n      name: \"thematicBreak\",\n      tokenize: tokenizeThematicBreak\n    };\n    function tokenizeThematicBreak(effects, ok, nok) {\n      let size = 0;\n      let marker;\n      return start;\n      function start(code) {\n        effects.enter(\"thematicBreak\");\n        marker = code;\n        return atBreak(code);\n      }\n      function atBreak(code) {\n        if (code === marker) {\n          effects.enter(\"thematicBreakSequence\");\n          return sequence(code);\n        }\n        if (markdownSpace(code)) {\n          return factorySpace(effects, atBreak, \"whitespace\")(code);\n        }\n        if (size < 3 || code !== null && !markdownLineEnding(code)) {\n          return nok(code);\n        }\n        effects.exit(\"thematicBreak\");\n        return ok(code);\n      }\n      function sequence(code) {\n        if (code === marker) {\n          effects.consume(code);\n          size++;\n          return sequence;\n        }\n        effects.exit(\"thematicBreakSequence\");\n        return atBreak(code);\n      }\n    }\n    var list = {\n      name: \"list\",\n      tokenize: tokenizeListStart,\n      continuation: {\n        tokenize: tokenizeListContinuation\n      },\n      exit: tokenizeListEnd\n    };\n    var listItemPrefixWhitespaceConstruct = {\n      tokenize: tokenizeListItemPrefixWhitespace,\n      partial: true\n    };\n    var indentConstruct = {\n      tokenize: tokenizeIndent,\n      partial: true\n    };\n    function tokenizeListStart(effects, ok, nok) {\n      const self2 = this;\n      const tail = self2.events[self2.events.length - 1];\n      let initialSize = tail && tail[1].type === \"linePrefix\" ? tail[2].sliceSerialize(tail[1], true).length : 0;\n      let size = 0;\n      return start;\n      function start(code) {\n        const kind = self2.containerState.type || (code === 42 || code === 43 || code === 45 ? \"listUnordered\" : \"listOrdered\");\n        if (kind === \"listUnordered\" ? !self2.containerState.marker || code === self2.containerState.marker : asciiDigit(code)) {\n          if (!self2.containerState.type) {\n            self2.containerState.type = kind;\n            effects.enter(kind, {\n              _container: true\n            });\n          }\n          if (kind === \"listUnordered\") {\n            effects.enter(\"listItemPrefix\");\n            return code === 42 || code === 45 ? effects.check(thematicBreak, nok, atMarker)(code) : atMarker(code);\n          }\n          if (!self2.interrupt || code === 49) {\n            effects.enter(\"listItemPrefix\");\n            effects.enter(\"listItemValue\");\n            return inside(code);\n          }\n        }\n        return nok(code);\n      }\n      function inside(code) {\n        if (asciiDigit(code) && ++size < 10) {\n          effects.consume(code);\n          return inside;\n        }\n        if ((!self2.interrupt || size < 2) && (self2.containerState.marker ? code === self2.containerState.marker : code === 41 || code === 46)) {\n          effects.exit(\"listItemValue\");\n          return atMarker(code);\n        }\n        return nok(code);\n      }\n      function atMarker(code) {\n        effects.enter(\"listItemMarker\");\n        effects.consume(code);\n        effects.exit(\"listItemMarker\");\n        self2.containerState.marker = self2.containerState.marker || code;\n        return effects.check(blankLine, self2.interrupt ? nok : onBlank, effects.attempt(listItemPrefixWhitespaceConstruct, endOfPrefix, otherPrefix));\n      }\n      function onBlank(code) {\n        self2.containerState.initialBlankLine = true;\n        initialSize++;\n        return endOfPrefix(code);\n      }\n      function otherPrefix(code) {\n        if (markdownSpace(code)) {\n          effects.enter(\"listItemPrefixWhitespace\");\n          effects.consume(code);\n          effects.exit(\"listItemPrefixWhitespace\");\n          return endOfPrefix;\n        }\n        return nok(code);\n      }\n      function endOfPrefix(code) {\n        self2.containerState.size = initialSize + self2.sliceSerialize(effects.exit(\"listItemPrefix\"), true).length;\n        return ok(code);\n      }\n    }\n    function tokenizeListContinuation(effects, ok, nok) {\n      const self2 = this;\n      self2.containerState._closeFlow = void 0;\n      return effects.check(blankLine, onBlank, notBlank);\n      function onBlank(code) {\n        self2.containerState.furtherBlankLines = self2.containerState.furtherBlankLines || self2.containerState.initialBlankLine;\n        return factorySpace(effects, ok, \"listItemIndent\", self2.containerState.size + 1)(code);\n      }\n      function notBlank(code) {\n        if (self2.containerState.furtherBlankLines || !markdownSpace(code)) {\n          self2.containerState.furtherBlankLines = void 0;\n          self2.containerState.initialBlankLine = void 0;\n          return notInCurrentItem(code);\n        }\n        self2.containerState.furtherBlankLines = void 0;\n        self2.containerState.initialBlankLine = void 0;\n        return effects.attempt(indentConstruct, ok, notInCurrentItem)(code);\n      }\n      function notInCurrentItem(code) {\n        self2.containerState._closeFlow = true;\n        self2.interrupt = void 0;\n        return factorySpace(effects, effects.attempt(list, ok, nok), \"linePrefix\", self2.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4)(code);\n      }\n    }\n    function tokenizeIndent(effects, ok, nok) {\n      const self2 = this;\n      return factorySpace(effects, afterPrefix, \"listItemIndent\", self2.containerState.size + 1);\n      function afterPrefix(code) {\n        const tail = self2.events[self2.events.length - 1];\n        return tail && tail[1].type === \"listItemIndent\" && tail[2].sliceSerialize(tail[1], true).length === self2.containerState.size ? ok(code) : nok(code);\n      }\n    }\n    function tokenizeListEnd(effects) {\n      effects.exit(this.containerState.type);\n    }\n    function tokenizeListItemPrefixWhitespace(effects, ok, nok) {\n      const self2 = this;\n      return factorySpace(effects, afterPrefix, \"listItemPrefixWhitespace\", self2.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4 + 1);\n      function afterPrefix(code) {\n        const tail = self2.events[self2.events.length - 1];\n        return !markdownSpace(code) && tail && tail[1].type === \"listItemPrefixWhitespace\" ? ok(code) : nok(code);\n      }\n    }\n    var setextUnderline = {\n      name: \"setextUnderline\",\n      tokenize: tokenizeSetextUnderline,\n      resolveTo: resolveToSetextUnderline\n    };\n    function resolveToSetextUnderline(events, context) {\n      let index2 = events.length;\n      let content3;\n      let text3;\n      let definition2;\n      while (index2--) {\n        if (events[index2][0] === \"enter\") {\n          if (events[index2][1].type === \"content\") {\n            content3 = index2;\n            break;\n          }\n          if (events[index2][1].type === \"paragraph\") {\n            text3 = index2;\n          }\n        } else {\n          if (events[index2][1].type === \"content\") {\n            events.splice(index2, 1);\n          }\n          if (!definition2 && events[index2][1].type === \"definition\") {\n            definition2 = index2;\n          }\n        }\n      }\n      const heading = {\n        type: \"setextHeading\",\n        start: Object.assign({}, events[text3][1].start),\n        end: Object.assign({}, events[events.length - 1][1].end)\n      };\n      events[text3][1].type = \"setextHeadingText\";\n      if (definition2) {\n        events.splice(text3, 0, [\"enter\", heading, context]);\n        events.splice(definition2 + 1, 0, [\"exit\", events[content3][1], context]);\n        events[content3][1].end = Object.assign({}, events[definition2][1].end);\n      } else {\n        events[content3][1] = heading;\n      }\n      events.push([\"exit\", heading, context]);\n      return events;\n    }\n    function tokenizeSetextUnderline(effects, ok, nok) {\n      const self2 = this;\n      let index2 = self2.events.length;\n      let marker;\n      let paragraph;\n      while (index2--) {\n        if (self2.events[index2][1].type !== \"lineEnding\" && self2.events[index2][1].type !== \"linePrefix\" && self2.events[index2][1].type !== \"content\") {\n          paragraph = self2.events[index2][1].type === \"paragraph\";\n          break;\n        }\n      }\n      return start;\n      function start(code) {\n        if (!self2.parser.lazy[self2.now().line] && (self2.interrupt || paragraph)) {\n          effects.enter(\"setextHeadingLine\");\n          effects.enter(\"setextHeadingLineSequence\");\n          marker = code;\n          return closingSequence(code);\n        }\n        return nok(code);\n      }\n      function closingSequence(code) {\n        if (code === marker) {\n          effects.consume(code);\n          return closingSequence;\n        }\n        effects.exit(\"setextHeadingLineSequence\");\n        return factorySpace(effects, closingSequenceEnd, \"lineSuffix\")(code);\n      }\n      function closingSequenceEnd(code) {\n        if (code === null || markdownLineEnding(code)) {\n          effects.exit(\"setextHeadingLine\");\n          return ok(code);\n        }\n        return nok(code);\n      }\n    }\n    var flow = {\n      tokenize: initializeFlow\n    };\n    function initializeFlow(effects) {\n      const self2 = this;\n      const initial = effects.attempt(blankLine, atBlankEnding, effects.attempt(this.parser.constructs.flowInitial, afterConstruct, factorySpace(effects, effects.attempt(this.parser.constructs.flow, afterConstruct, effects.attempt(content2, afterConstruct)), \"linePrefix\")));\n      return initial;\n      function atBlankEnding(code) {\n        if (code === null) {\n          effects.consume(code);\n          return;\n        }\n        effects.enter(\"lineEndingBlank\");\n        effects.consume(code);\n        effects.exit(\"lineEndingBlank\");\n        self2.currentConstruct = void 0;\n        return initial;\n      }\n      function afterConstruct(code) {\n        if (code === null) {\n          effects.consume(code);\n          return;\n        }\n        effects.enter(\"lineEnding\");\n        effects.consume(code);\n        effects.exit(\"lineEnding\");\n        self2.currentConstruct = void 0;\n        return initial;\n      }\n    }\n    var resolver = {\n      resolveAll: createResolver()\n    };\n    var string = initializeFactory(\"string\");\n    var text = initializeFactory(\"text\");\n    function initializeFactory(field) {\n      return {\n        tokenize: initializeText,\n        resolveAll: createResolver(field === \"text\" ? resolveAllLineSuffixes : void 0)\n      };\n      function initializeText(effects) {\n        const self2 = this;\n        const constructs2 = this.parser.constructs[field];\n        const text3 = effects.attempt(constructs2, start, notText);\n        return start;\n        function start(code) {\n          return atBreak(code) ? text3(code) : notText(code);\n        }\n        function notText(code) {\n          if (code === null) {\n            effects.consume(code);\n            return;\n          }\n          effects.enter(\"data\");\n          effects.consume(code);\n          return data;\n        }\n        function data(code) {\n          if (atBreak(code)) {\n            effects.exit(\"data\");\n            return text3(code);\n          }\n          effects.consume(code);\n          return data;\n        }\n        function atBreak(code) {\n          if (code === null) {\n            return true;\n          }\n          const list2 = constructs2[code];\n          let index2 = -1;\n          if (list2) {\n            while (++index2 < list2.length) {\n              const item = list2[index2];\n              if (!item.previous || item.previous.call(self2, self2.previous)) {\n                return true;\n              }\n            }\n          }\n          return false;\n        }\n      }\n    }\n    function createResolver(extraResolver) {\n      return resolveAllText;\n      function resolveAllText(events, context) {\n        let index2 = -1;\n        let enter;\n        while (++index2 <= events.length) {\n          if (enter === void 0) {\n            if (events[index2] && events[index2][1].type === \"data\") {\n              enter = index2;\n              index2++;\n            }\n          } else if (!events[index2] || events[index2][1].type !== \"data\") {\n            if (index2 !== enter + 2) {\n              events[enter][1].end = events[index2 - 1][1].end;\n              events.splice(enter + 2, index2 - enter - 2);\n              index2 = enter + 2;\n            }\n            enter = void 0;\n          }\n        }\n        return extraResolver ? extraResolver(events, context) : events;\n      }\n    }\n    function resolveAllLineSuffixes(events, context) {\n      let eventIndex = -1;\n      while (++eventIndex <= events.length) {\n        if ((eventIndex === events.length || events[eventIndex][1].type === \"lineEnding\") && events[eventIndex - 1][1].type === \"data\") {\n          const data = events[eventIndex - 1][1];\n          const chunks = context.sliceStream(data);\n          let index2 = chunks.length;\n          let bufferIndex = -1;\n          let size = 0;\n          let tabs;\n          while (index2--) {\n            const chunk = chunks[index2];\n            if (typeof chunk === \"string\") {\n              bufferIndex = chunk.length;\n              while (chunk.charCodeAt(bufferIndex - 1) === 32) {\n                size++;\n                bufferIndex--;\n              }\n              if (bufferIndex)\n                break;\n              bufferIndex = -1;\n            } else if (chunk === -2) {\n              tabs = true;\n              size++;\n            } else if (chunk === -1) {\n            } else {\n              index2++;\n              break;\n            }\n          }\n          if (size) {\n            const token = {\n              type: eventIndex === events.length || tabs || size < 2 ? \"lineSuffix\" : \"hardBreakTrailing\",\n              start: {\n                line: data.end.line,\n                column: data.end.column - size,\n                offset: data.end.offset - size,\n                _index: data.start._index + index2,\n                _bufferIndex: index2 ? bufferIndex : data.start._bufferIndex + bufferIndex\n              },\n              end: Object.assign({}, data.end)\n            };\n            data.end = Object.assign({}, token.start);\n            if (data.start.offset === data.end.offset) {\n              Object.assign(data, token);\n            } else {\n              events.splice(eventIndex, 0, [\"enter\", token, context], [\"exit\", token, context]);\n              eventIndex += 2;\n            }\n          }\n          eventIndex++;\n        }\n      }\n      return events;\n    }\n    function createTokenizer(parser, initialize, from) {\n      let point2 = Object.assign(from ? Object.assign({}, from) : {\n        line: 1,\n        column: 1,\n        offset: 0\n      }, {\n        _index: 0,\n        _bufferIndex: -1\n      });\n      const columnStart = {};\n      const resolveAllConstructs = [];\n      let chunks = [];\n      let stack = [];\n      let consumed = true;\n      const effects = {\n        consume,\n        enter,\n        exit: exit2,\n        attempt: constructFactory(onsuccessfulconstruct),\n        check: constructFactory(onsuccessfulcheck),\n        interrupt: constructFactory(onsuccessfulcheck, {\n          interrupt: true\n        })\n      };\n      const context = {\n        previous: null,\n        code: null,\n        containerState: {},\n        events: [],\n        parser,\n        sliceStream,\n        sliceSerialize,\n        now,\n        defineSkip,\n        write\n      };\n      let state = initialize.tokenize.call(context, effects);\n      let expectedCode;\n      if (initialize.resolveAll) {\n        resolveAllConstructs.push(initialize);\n      }\n      return context;\n      function write(slice) {\n        chunks = push(chunks, slice);\n        main();\n        if (chunks[chunks.length - 1] !== null) {\n          return [];\n        }\n        addResult(initialize, 0);\n        context.events = resolveAll(resolveAllConstructs, context.events, context);\n        return context.events;\n      }\n      function sliceSerialize(token, expandTabs) {\n        return serializeChunks(sliceStream(token), expandTabs);\n      }\n      function sliceStream(token) {\n        return sliceChunks(chunks, token);\n      }\n      function now() {\n        return Object.assign({}, point2);\n      }\n      function defineSkip(value2) {\n        columnStart[value2.line] = value2.column;\n        accountForPotentialSkip();\n      }\n      function main() {\n        let chunkIndex;\n        while (point2._index < chunks.length) {\n          const chunk = chunks[point2._index];\n          if (typeof chunk === \"string\") {\n            chunkIndex = point2._index;\n            if (point2._bufferIndex < 0) {\n              point2._bufferIndex = 0;\n            }\n            while (point2._index === chunkIndex && point2._bufferIndex < chunk.length) {\n              go(chunk.charCodeAt(point2._bufferIndex));\n            }\n          } else {\n            go(chunk);\n          }\n        }\n      }\n      function go(code) {\n        consumed = void 0;\n        expectedCode = code;\n        state = state(code);\n      }\n      function consume(code) {\n        if (markdownLineEnding(code)) {\n          point2.line++;\n          point2.column = 1;\n          point2.offset += code === -3 ? 2 : 1;\n          accountForPotentialSkip();\n        } else if (code !== -1) {\n          point2.column++;\n          point2.offset++;\n        }\n        if (point2._bufferIndex < 0) {\n          point2._index++;\n        } else {\n          point2._bufferIndex++;\n          if (point2._bufferIndex === chunks[point2._index].length) {\n            point2._bufferIndex = -1;\n            point2._index++;\n          }\n        }\n        context.previous = code;\n        consumed = true;\n      }\n      function enter(type, fields) {\n        const token = fields || {};\n        token.type = type;\n        token.start = now();\n        context.events.push([\"enter\", token, context]);\n        stack.push(token);\n        return token;\n      }\n      function exit2(type) {\n        const token = stack.pop();\n        token.end = now();\n        context.events.push([\"exit\", token, context]);\n        return token;\n      }\n      function onsuccessfulconstruct(construct, info) {\n        addResult(construct, info.from);\n      }\n      function onsuccessfulcheck(_, info) {\n        info.restore();\n      }\n      function constructFactory(onreturn, fields) {\n        return hook;\n        function hook(constructs2, returnState, bogusState) {\n          let listOfConstructs;\n          let constructIndex;\n          let currentConstruct;\n          let info;\n          return Array.isArray(constructs2) ? handleListOfConstructs(constructs2) : \"tokenize\" in constructs2 ? handleListOfConstructs([constructs2]) : handleMapOfConstructs(constructs2);\n          function handleMapOfConstructs(map) {\n            return start;\n            function start(code) {\n              const def = code !== null && map[code];\n              const all2 = code !== null && map.null;\n              const list2 = [\n                ...Array.isArray(def) ? def : def ? [def] : [],\n                ...Array.isArray(all2) ? all2 : all2 ? [all2] : []\n              ];\n              return handleListOfConstructs(list2)(code);\n            }\n          }\n          function handleListOfConstructs(list2) {\n            listOfConstructs = list2;\n            constructIndex = 0;\n            if (list2.length === 0) {\n              return bogusState;\n            }\n            return handleConstruct(list2[constructIndex]);\n          }\n          function handleConstruct(construct) {\n            return start;\n            function start(code) {\n              info = store();\n              currentConstruct = construct;\n              if (!construct.partial) {\n                context.currentConstruct = construct;\n              }\n              if (construct.name && context.parser.constructs.disable.null.includes(construct.name)) {\n                return nok(code);\n              }\n              return construct.tokenize.call(fields ? Object.assign(Object.create(context), fields) : context, effects, ok, nok)(code);\n            }\n          }\n          function ok(code) {\n            consumed = true;\n            onreturn(currentConstruct, info);\n            return returnState;\n          }\n          function nok(code) {\n            consumed = true;\n            info.restore();\n            if (++constructIndex < listOfConstructs.length) {\n              return handleConstruct(listOfConstructs[constructIndex]);\n            }\n            return bogusState;\n          }\n        }\n      }\n      function addResult(construct, from2) {\n        if (construct.resolveAll && !resolveAllConstructs.includes(construct)) {\n          resolveAllConstructs.push(construct);\n        }\n        if (construct.resolve) {\n          splice(context.events, from2, context.events.length - from2, construct.resolve(context.events.slice(from2), context));\n        }\n        if (construct.resolveTo) {\n          context.events = construct.resolveTo(context.events, context);\n        }\n      }\n      function store() {\n        const startPoint = now();\n        const startPrevious = context.previous;\n        const startCurrentConstruct = context.currentConstruct;\n        const startEventsIndex = context.events.length;\n        const startStack = Array.from(stack);\n        return {\n          restore,\n          from: startEventsIndex\n        };\n        function restore() {\n          point2 = startPoint;\n          context.previous = startPrevious;\n          context.currentConstruct = startCurrentConstruct;\n          context.events.length = startEventsIndex;\n          stack = startStack;\n          accountForPotentialSkip();\n        }\n      }\n      function accountForPotentialSkip() {\n        if (point2.line in columnStart && point2.column < 2) {\n          point2.column = columnStart[point2.line];\n          point2.offset += columnStart[point2.line] - 1;\n        }\n      }\n    }\n    function sliceChunks(chunks, token) {\n      const startIndex = token.start._index;\n      const startBufferIndex = token.start._bufferIndex;\n      const endIndex = token.end._index;\n      const endBufferIndex = token.end._bufferIndex;\n      let view;\n      if (startIndex === endIndex) {\n        view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)];\n      } else {\n        view = chunks.slice(startIndex, endIndex);\n        if (startBufferIndex > -1) {\n          view[0] = view[0].slice(startBufferIndex);\n        }\n        if (endBufferIndex > 0) {\n          view.push(chunks[endIndex].slice(0, endBufferIndex));\n        }\n      }\n      return view;\n    }\n    function serializeChunks(chunks, expandTabs) {\n      let index2 = -1;\n      const result = [];\n      let atTab;\n      while (++index2 < chunks.length) {\n        const chunk = chunks[index2];\n        let value2;\n        if (typeof chunk === \"string\") {\n          value2 = chunk;\n        } else\n          switch (chunk) {\n            case -5: {\n              value2 = \"\\r\";\n              break;\n            }\n            case -4: {\n              value2 = \"\\n\";\n              break;\n            }\n            case -3: {\n              value2 = \"\\r\\n\";\n              break;\n            }\n            case -2: {\n              value2 = expandTabs ? \" \" : \"\t\";\n              break;\n            }\n            case -1: {\n              if (!expandTabs && atTab)\n                continue;\n              value2 = \" \";\n              break;\n            }\n            default: {\n              value2 = String.fromCharCode(chunk);\n            }\n          }\n        atTab = chunk === -2;\n        result.push(value2);\n      }\n      return result.join(\"\");\n    }\n    var constructs_exports = {};\n    __export(constructs_exports, {\n      attentionMarkers: () => attentionMarkers,\n      contentInitial: () => contentInitial,\n      disable: () => disable,\n      document: () => document3,\n      flow: () => flow2,\n      flowInitial: () => flowInitial,\n      insideSpan: () => insideSpan,\n      string: () => string2,\n      text: () => text2\n    });\n    var document3 = {\n      [42]: list,\n      [43]: list,\n      [45]: list,\n      [48]: list,\n      [49]: list,\n      [50]: list,\n      [51]: list,\n      [52]: list,\n      [53]: list,\n      [54]: list,\n      [55]: list,\n      [56]: list,\n      [57]: list,\n      [62]: blockQuote\n    };\n    var contentInitial = {\n      [91]: definition\n    };\n    var flowInitial = {\n      [-2]: codeIndented,\n      [-1]: codeIndented,\n      [32]: codeIndented\n    };\n    var flow2 = {\n      [35]: headingAtx,\n      [42]: thematicBreak,\n      [45]: [setextUnderline, thematicBreak],\n      [60]: htmlFlow,\n      [61]: setextUnderline,\n      [95]: thematicBreak,\n      [96]: codeFenced,\n      [126]: codeFenced\n    };\n    var string2 = {\n      [38]: characterReference,\n      [92]: characterEscape\n    };\n    var text2 = {\n      [-5]: lineEnding,\n      [-4]: lineEnding,\n      [-3]: lineEnding,\n      [33]: labelStartImage,\n      [38]: characterReference,\n      [42]: attention,\n      [60]: [autolink, htmlText],\n      [91]: labelStartLink,\n      [92]: [hardBreakEscape, characterEscape],\n      [93]: labelEnd,\n      [95]: attention,\n      [96]: codeText\n    };\n    var insideSpan = {\n      null: [attention, resolver]\n    };\n    var attentionMarkers = {\n      null: [42, 95]\n    };\n    var disable = {\n      null: []\n    };\n    function parse2(options = {}) {\n      const constructs2 = combineExtensions([constructs_exports].concat(options.extensions || []));\n      const parser = {\n        defined: [],\n        lazy: {},\n        constructs: constructs2,\n        content: create2(content),\n        document: create2(document2),\n        flow: create2(flow),\n        string: create2(string),\n        text: create2(text)\n      };\n      return parser;\n      function create2(initial) {\n        return creator;\n        function creator(from) {\n          return createTokenizer(parser, initial, from);\n        }\n      }\n    }\n    var search = /[\\0\\t\\n\\r]/g;\n    function preprocess() {\n      let column = 1;\n      let buffer2 = \"\";\n      let start = true;\n      let atCarriageReturn;\n      return preprocessor;\n      function preprocessor(value2, encoding, end) {\n        const chunks = [];\n        let match;\n        let next;\n        let startPosition;\n        let endPosition;\n        let code;\n        value2 = buffer2 + value2.toString(encoding);\n        startPosition = 0;\n        buffer2 = \"\";\n        if (start) {\n          if (value2.charCodeAt(0) === 65279) {\n            startPosition++;\n          }\n          start = void 0;\n        }\n        while (startPosition < value2.length) {\n          search.lastIndex = startPosition;\n          match = search.exec(value2);\n          endPosition = match && match.index !== void 0 ? match.index : value2.length;\n          code = value2.charCodeAt(endPosition);\n          if (!match) {\n            buffer2 = value2.slice(startPosition);\n            break;\n          }\n          if (code === 10 && startPosition === endPosition && atCarriageReturn) {\n            chunks.push(-3);\n            atCarriageReturn = void 0;\n          } else {\n            if (atCarriageReturn) {\n              chunks.push(-5);\n              atCarriageReturn = void 0;\n            }\n            if (startPosition < endPosition) {\n              chunks.push(value2.slice(startPosition, endPosition));\n              column += endPosition - startPosition;\n            }\n            switch (code) {\n              case 0: {\n                chunks.push(65533);\n                column++;\n                break;\n              }\n              case 9: {\n                next = Math.ceil(column / 4) * 4;\n                chunks.push(-2);\n                while (column++ < next)\n                  chunks.push(-1);\n                break;\n              }\n              case 10: {\n                chunks.push(-4);\n                column = 1;\n                break;\n              }\n              default: {\n                atCarriageReturn = true;\n                column = 1;\n              }\n            }\n          }\n          startPosition = endPosition + 1;\n        }\n        if (end) {\n          if (atCarriageReturn)\n            chunks.push(-5);\n          if (buffer2)\n            chunks.push(buffer2);\n          chunks.push(null);\n        }\n        return chunks;\n      }\n    }\n    function postprocess(events) {\n      while (!subtokenize(events)) {\n      }\n      return events;\n    }\n    function decodeNumericCharacterReference(value2, base2) {\n      const code = Number.parseInt(value2, base2);\n      if (code < 9 || code === 11 || code > 13 && code < 32 || code > 126 && code < 160 || code > 55295 && code < 57344 || code > 64975 && code < 65008 || (code & 65535) === 65535 || (code & 65535) === 65534 || code > 1114111) {\n        return \"\\uFFFD\";\n      }\n      return String.fromCharCode(code);\n    }\n    var characterEscapeOrReference = /\\\\([!-/:-@[-`{-~])|&(#(?:\\d{1,7}|x[\\da-f]{1,6})|[\\da-z]{1,31});/gi;\n    function decodeString(value2) {\n      return value2.replace(characterEscapeOrReference, decode);\n    }\n    function decode($0, $1, $2) {\n      if ($1) {\n        return $1;\n      }\n      const head = $2.charCodeAt(0);\n      if (head === 35) {\n        const head2 = $2.charCodeAt(1);\n        const hex = head2 === 120 || head2 === 88;\n        return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10);\n      }\n      return decodeEntity($2) || $0;\n    }\n    var own2 = {}.hasOwnProperty;\n    function stringifyPosition(value2) {\n      if (!value2 || typeof value2 !== \"object\") {\n        return \"\";\n      }\n      if (own2.call(value2, \"position\") || own2.call(value2, \"type\")) {\n        return position(value2.position);\n      }\n      if (own2.call(value2, \"start\") || own2.call(value2, \"end\")) {\n        return position(value2);\n      }\n      if (own2.call(value2, \"line\") || own2.call(value2, \"column\")) {\n        return point(value2);\n      }\n      return \"\";\n    }\n    function point(point2) {\n      return index(point2 && point2.line) + \":\" + index(point2 && point2.column);\n    }\n    function position(pos) {\n      return point(pos && pos.start) + \"-\" + point(pos && pos.end);\n    }\n    function index(value2) {\n      return value2 && typeof value2 === \"number\" ? value2 : 1;\n    }\n    var own3 = {}.hasOwnProperty;\n    var fromMarkdown = function(value2, encoding, options) {\n      if (typeof encoding !== \"string\") {\n        options = encoding;\n        encoding = void 0;\n      }\n      return compiler(options)(postprocess(parse2(options).document().write(preprocess()(value2, encoding, true))));\n    };\n    function compiler(options = {}) {\n      const config = configure({\n        transforms: [],\n        canContainEols: [\n          \"emphasis\",\n          \"fragment\",\n          \"heading\",\n          \"paragraph\",\n          \"strong\"\n        ],\n        enter: {\n          autolink: opener2(link),\n          autolinkProtocol: onenterdata,\n          autolinkEmail: onenterdata,\n          atxHeading: opener2(heading),\n          blockQuote: opener2(blockQuote2),\n          characterEscape: onenterdata,\n          characterReference: onenterdata,\n          codeFenced: opener2(codeFlow),\n          codeFencedFenceInfo: buffer2,\n          codeFencedFenceMeta: buffer2,\n          codeIndented: opener2(codeFlow, buffer2),\n          codeText: opener2(codeText2, buffer2),\n          codeTextData: onenterdata,\n          data: onenterdata,\n          codeFlowValue: onenterdata,\n          definition: opener2(definition2),\n          definitionDestinationString: buffer2,\n          definitionLabelString: buffer2,\n          definitionTitleString: buffer2,\n          emphasis: opener2(emphasis),\n          hardBreakEscape: opener2(hardBreak),\n          hardBreakTrailing: opener2(hardBreak),\n          htmlFlow: opener2(html, buffer2),\n          htmlFlowData: onenterdata,\n          htmlText: opener2(html, buffer2),\n          htmlTextData: onenterdata,\n          image: opener2(image),\n          label: buffer2,\n          link: opener2(link),\n          listItem: opener2(listItem),\n          listItemValue: onenterlistitemvalue,\n          listOrdered: opener2(list2, onenterlistordered),\n          listUnordered: opener2(list2),\n          paragraph: opener2(paragraph),\n          reference: onenterreference,\n          referenceString: buffer2,\n          resourceDestinationString: buffer2,\n          resourceTitleString: buffer2,\n          setextHeading: opener2(heading),\n          strong: opener2(strong),\n          thematicBreak: opener2(thematicBreak2)\n        },\n        exit: {\n          atxHeading: closer(),\n          atxHeadingSequence: onexitatxheadingsequence,\n          autolink: closer(),\n          autolinkEmail: onexitautolinkemail,\n          autolinkProtocol: onexitautolinkprotocol,\n          blockQuote: closer(),\n          characterEscapeValue: onexitdata,\n          characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker,\n          characterReferenceMarkerNumeric: onexitcharacterreferencemarker,\n          characterReferenceValue: onexitcharacterreferencevalue,\n          codeFenced: closer(onexitcodefenced),\n          codeFencedFence: onexitcodefencedfence,\n          codeFencedFenceInfo: onexitcodefencedfenceinfo,\n          codeFencedFenceMeta: onexitcodefencedfencemeta,\n          codeFlowValue: onexitdata,\n          codeIndented: closer(onexitcodeindented),\n          codeText: closer(onexitcodetext),\n          codeTextData: onexitdata,\n          data: onexitdata,\n          definition: closer(),\n          definitionDestinationString: onexitdefinitiondestinationstring,\n          definitionLabelString: onexitdefinitionlabelstring,\n          definitionTitleString: onexitdefinitiontitlestring,\n          emphasis: closer(),\n          hardBreakEscape: closer(onexithardbreak),\n          hardBreakTrailing: closer(onexithardbreak),\n          htmlFlow: closer(onexithtmlflow),\n          htmlFlowData: onexitdata,\n          htmlText: closer(onexithtmltext),\n          htmlTextData: onexitdata,\n          image: closer(onexitimage),\n          label: onexitlabel,\n          labelText: onexitlabeltext,\n          lineEnding: onexitlineending,\n          link: closer(onexitlink),\n          listItem: closer(),\n          listOrdered: closer(),\n          listUnordered: closer(),\n          paragraph: closer(),\n          referenceString: onexitreferencestring,\n          resourceDestinationString: onexitresourcedestinationstring,\n          resourceTitleString: onexitresourcetitlestring,\n          resource: onexitresource,\n          setextHeading: closer(onexitsetextheading),\n          setextHeadingLineSequence: onexitsetextheadinglinesequence,\n          setextHeadingText: onexitsetextheadingtext,\n          strong: closer(),\n          thematicBreak: closer()\n        }\n      }, options.mdastExtensions || []);\n      const data = {};\n      return compile;\n      function compile(events) {\n        let tree = {\n          type: \"root\",\n          children: []\n        };\n        const stack = [tree];\n        const tokenStack = [];\n        const listStack = [];\n        const context = {\n          stack,\n          tokenStack,\n          config,\n          enter,\n          exit: exit2,\n          buffer: buffer2,\n          resume,\n          setData,\n          getData\n        };\n        let index2 = -1;\n        while (++index2 < events.length) {\n          if (events[index2][1].type === \"listOrdered\" || events[index2][1].type === \"listUnordered\") {\n            if (events[index2][0] === \"enter\") {\n              listStack.push(index2);\n            } else {\n              const tail = listStack.pop();\n              index2 = prepareList(events, tail, index2);\n            }\n          }\n        }\n        index2 = -1;\n        while (++index2 < events.length) {\n          const handler2 = config[events[index2][0]];\n          if (own3.call(handler2, events[index2][1].type)) {\n            handler2[events[index2][1].type].call(Object.assign({\n              sliceSerialize: events[index2][2].sliceSerialize\n            }, context), events[index2][1]);\n          }\n        }\n        if (tokenStack.length > 0) {\n          throw new Error(\"Cannot close document, a token (`\" + tokenStack[tokenStack.length - 1].type + \"`, \" + stringifyPosition({\n            start: tokenStack[tokenStack.length - 1].start,\n            end: tokenStack[tokenStack.length - 1].end\n          }) + \") is still open\");\n        }\n        tree.position = {\n          start: point2(events.length > 0 ? events[0][1].start : {\n            line: 1,\n            column: 1,\n            offset: 0\n          }),\n          end: point2(events.length > 0 ? events[events.length - 2][1].end : {\n            line: 1,\n            column: 1,\n            offset: 0\n          })\n        };\n        index2 = -1;\n        while (++index2 < config.transforms.length) {\n          tree = config.transforms[index2](tree) || tree;\n        }\n        return tree;\n      }\n      function prepareList(events, start, length) {\n        let index2 = start - 1;\n        let containerBalance = -1;\n        let listSpread = false;\n        let listItem2;\n        let lineIndex;\n        let firstBlankLineIndex;\n        let atMarker;\n        while (++index2 <= length) {\n          const event = events[index2];\n          if (event[1].type === \"listUnordered\" || event[1].type === \"listOrdered\" || event[1].type === \"blockQuote\") {\n            if (event[0] === \"enter\") {\n              containerBalance++;\n            } else {\n              containerBalance--;\n            }\n            atMarker = void 0;\n          } else if (event[1].type === \"lineEndingBlank\") {\n            if (event[0] === \"enter\") {\n              if (listItem2 && !atMarker && !containerBalance && !firstBlankLineIndex) {\n                firstBlankLineIndex = index2;\n              }\n              atMarker = void 0;\n            }\n          } else if (event[1].type === \"linePrefix\" || event[1].type === \"listItemValue\" || event[1].type === \"listItemMarker\" || event[1].type === \"listItemPrefix\" || event[1].type === \"listItemPrefixWhitespace\") {\n          } else {\n            atMarker = void 0;\n          }\n          if (!containerBalance && event[0] === \"enter\" && event[1].type === \"listItemPrefix\" || containerBalance === -1 && event[0] === \"exit\" && (event[1].type === \"listUnordered\" || event[1].type === \"listOrdered\")) {\n            if (listItem2) {\n              let tailIndex = index2;\n              lineIndex = void 0;\n              while (tailIndex--) {\n                const tailEvent = events[tailIndex];\n                if (tailEvent[1].type === \"lineEnding\" || tailEvent[1].type === \"lineEndingBlank\") {\n                  if (tailEvent[0] === \"exit\")\n                    continue;\n                  if (lineIndex) {\n                    events[lineIndex][1].type = \"lineEndingBlank\";\n                    listSpread = true;\n                  }\n                  tailEvent[1].type = \"lineEnding\";\n                  lineIndex = tailIndex;\n                } else if (tailEvent[1].type === \"linePrefix\" || tailEvent[1].type === \"blockQuotePrefix\" || tailEvent[1].type === \"blockQuotePrefixWhitespace\" || tailEvent[1].type === \"blockQuoteMarker\" || tailEvent[1].type === \"listItemIndent\") {\n                } else {\n                  break;\n                }\n              }\n              if (firstBlankLineIndex && (!lineIndex || firstBlankLineIndex < lineIndex)) {\n                listItem2._spread = true;\n              }\n              listItem2.end = Object.assign({}, lineIndex ? events[lineIndex][1].start : event[1].end);\n              events.splice(lineIndex || index2, 0, [\"exit\", listItem2, event[2]]);\n              index2++;\n              length++;\n            }\n            if (event[1].type === \"listItemPrefix\") {\n              listItem2 = {\n                type: \"listItem\",\n                _spread: false,\n                start: Object.assign({}, event[1].start)\n              };\n              events.splice(index2, 0, [\"enter\", listItem2, event[2]]);\n              index2++;\n              length++;\n              firstBlankLineIndex = void 0;\n              atMarker = true;\n            }\n          }\n        }\n        events[start][1]._spread = listSpread;\n        return length;\n      }\n      function setData(key, value2) {\n        data[key] = value2;\n      }\n      function getData(key) {\n        return data[key];\n      }\n      function point2(d) {\n        return {\n          line: d.line,\n          column: d.column,\n          offset: d.offset\n        };\n      }\n      function opener2(create2, and) {\n        return open;\n        function open(token) {\n          enter.call(this, create2(token), token);\n          if (and)\n            and.call(this, token);\n        }\n      }\n      function buffer2() {\n        this.stack.push({\n          type: \"fragment\",\n          children: []\n        });\n      }\n      function enter(node, token) {\n        const parent = this.stack[this.stack.length - 1];\n        parent.children.push(node);\n        this.stack.push(node);\n        this.tokenStack.push(token);\n        node.position = {\n          start: point2(token.start)\n        };\n        return node;\n      }\n      function closer(and) {\n        return close2;\n        function close2(token) {\n          if (and)\n            and.call(this, token);\n          exit2.call(this, token);\n        }\n      }\n      function exit2(token) {\n        const node = this.stack.pop();\n        const open = this.tokenStack.pop();\n        if (!open) {\n          throw new Error(\"Cannot close `\" + token.type + \"` (\" + stringifyPosition({\n            start: token.start,\n            end: token.end\n          }) + \"): it\\u2019s not open\");\n        } else if (open.type !== token.type) {\n          throw new Error(\"Cannot close `\" + token.type + \"` (\" + stringifyPosition({\n            start: token.start,\n            end: token.end\n          }) + \"): a different token (`\" + open.type + \"`, \" + stringifyPosition({\n            start: open.start,\n            end: open.end\n          }) + \") is open\");\n        }\n        node.position.end = point2(token.end);\n        return node;\n      }\n      function resume() {\n        return toString(this.stack.pop());\n      }\n      function onenterlistordered() {\n        setData(\"expectingFirstListItemValue\", true);\n      }\n      function onenterlistitemvalue(token) {\n        if (getData(\"expectingFirstListItemValue\")) {\n          const ancestor = this.stack[this.stack.length - 2];\n          ancestor.start = Number.parseInt(this.sliceSerialize(token), 10);\n          setData(\"expectingFirstListItemValue\");\n        }\n      }\n      function onexitcodefencedfenceinfo() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.lang = data2;\n      }\n      function onexitcodefencedfencemeta() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.meta = data2;\n      }\n      function onexitcodefencedfence() {\n        if (getData(\"flowCodeInside\"))\n          return;\n        this.buffer();\n        setData(\"flowCodeInside\", true);\n      }\n      function onexitcodefenced() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.value = data2.replace(/^(\\r?\\n|\\r)|(\\r?\\n|\\r)$/g, \"\");\n        setData(\"flowCodeInside\");\n      }\n      function onexitcodeindented() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.value = data2.replace(/(\\r?\\n|\\r)$/g, \"\");\n      }\n      function onexitdefinitionlabelstring(token) {\n        const label = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.label = label;\n        node.identifier = normalizeIdentifier(this.sliceSerialize(token)).toLowerCase();\n      }\n      function onexitdefinitiontitlestring() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.title = data2;\n      }\n      function onexitdefinitiondestinationstring() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.url = data2;\n      }\n      function onexitatxheadingsequence(token) {\n        const node = this.stack[this.stack.length - 1];\n        if (!node.depth) {\n          const depth = this.sliceSerialize(token).length;\n          node.depth = depth;\n        }\n      }\n      function onexitsetextheadingtext() {\n        setData(\"setextHeadingSlurpLineEnding\", true);\n      }\n      function onexitsetextheadinglinesequence(token) {\n        const node = this.stack[this.stack.length - 1];\n        node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2;\n      }\n      function onexitsetextheading() {\n        setData(\"setextHeadingSlurpLineEnding\");\n      }\n      function onenterdata(token) {\n        const parent = this.stack[this.stack.length - 1];\n        let tail = parent.children[parent.children.length - 1];\n        if (!tail || tail.type !== \"text\") {\n          tail = text3();\n          tail.position = {\n            start: point2(token.start)\n          };\n          parent.children.push(tail);\n        }\n        this.stack.push(tail);\n      }\n      function onexitdata(token) {\n        const tail = this.stack.pop();\n        tail.value += this.sliceSerialize(token);\n        tail.position.end = point2(token.end);\n      }\n      function onexitlineending(token) {\n        const context = this.stack[this.stack.length - 1];\n        if (getData(\"atHardBreak\")) {\n          const tail = context.children[context.children.length - 1];\n          tail.position.end = point2(token.end);\n          setData(\"atHardBreak\");\n          return;\n        }\n        if (!getData(\"setextHeadingSlurpLineEnding\") && config.canContainEols.includes(context.type)) {\n          onenterdata.call(this, token);\n          onexitdata.call(this, token);\n        }\n      }\n      function onexithardbreak() {\n        setData(\"atHardBreak\", true);\n      }\n      function onexithtmlflow() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.value = data2;\n      }\n      function onexithtmltext() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.value = data2;\n      }\n      function onexitcodetext() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.value = data2;\n      }\n      function onexitlink() {\n        const context = this.stack[this.stack.length - 1];\n        if (getData(\"inReference\")) {\n          context.type += \"Reference\";\n          context.referenceType = getData(\"referenceType\") || \"shortcut\";\n          delete context.url;\n          delete context.title;\n        } else {\n          delete context.identifier;\n          delete context.label;\n        }\n        setData(\"referenceType\");\n      }\n      function onexitimage() {\n        const context = this.stack[this.stack.length - 1];\n        if (getData(\"inReference\")) {\n          context.type += \"Reference\";\n          context.referenceType = getData(\"referenceType\") || \"shortcut\";\n          delete context.url;\n          delete context.title;\n        } else {\n          delete context.identifier;\n          delete context.label;\n        }\n        setData(\"referenceType\");\n      }\n      function onexitlabeltext(token) {\n        const ancestor = this.stack[this.stack.length - 2];\n        const string3 = this.sliceSerialize(token);\n        ancestor.label = decodeString(string3);\n        ancestor.identifier = normalizeIdentifier(string3).toLowerCase();\n      }\n      function onexitlabel() {\n        const fragment = this.stack[this.stack.length - 1];\n        const value2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        setData(\"inReference\", true);\n        if (node.type === \"link\") {\n          node.children = fragment.children;\n        } else {\n          node.alt = value2;\n        }\n      }\n      function onexitresourcedestinationstring() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.url = data2;\n      }\n      function onexitresourcetitlestring() {\n        const data2 = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.title = data2;\n      }\n      function onexitresource() {\n        setData(\"inReference\");\n      }\n      function onenterreference() {\n        setData(\"referenceType\", \"collapsed\");\n      }\n      function onexitreferencestring(token) {\n        const label = this.resume();\n        const node = this.stack[this.stack.length - 1];\n        node.label = label;\n        node.identifier = normalizeIdentifier(this.sliceSerialize(token)).toLowerCase();\n        setData(\"referenceType\", \"full\");\n      }\n      function onexitcharacterreferencemarker(token) {\n        setData(\"characterReferenceType\", token.type);\n      }\n      function onexitcharacterreferencevalue(token) {\n        const data2 = this.sliceSerialize(token);\n        const type = getData(\"characterReferenceType\");\n        let value2;\n        if (type) {\n          value2 = decodeNumericCharacterReference(data2, type === \"characterReferenceMarkerNumeric\" ? 10 : 16);\n          setData(\"characterReferenceType\");\n        } else {\n          value2 = decodeEntity(data2);\n        }\n        const tail = this.stack.pop();\n        tail.value += value2;\n        tail.position.end = point2(token.end);\n      }\n      function onexitautolinkprotocol(token) {\n        onexitdata.call(this, token);\n        const node = this.stack[this.stack.length - 1];\n        node.url = this.sliceSerialize(token);\n      }\n      function onexitautolinkemail(token) {\n        onexitdata.call(this, token);\n        const node = this.stack[this.stack.length - 1];\n        node.url = \"mailto:\" + this.sliceSerialize(token);\n      }\n      function blockQuote2() {\n        return {\n          type: \"blockquote\",\n          children: []\n        };\n      }\n      function codeFlow() {\n        return {\n          type: \"code\",\n          lang: null,\n          meta: null,\n          value: \"\"\n        };\n      }\n      function codeText2() {\n        return {\n          type: \"inlineCode\",\n          value: \"\"\n        };\n      }\n      function definition2() {\n        return {\n          type: \"definition\",\n          identifier: \"\",\n          label: null,\n          title: null,\n          url: \"\"\n        };\n      }\n      function emphasis() {\n        return {\n          type: \"emphasis\",\n          children: []\n        };\n      }\n      function heading() {\n        return {\n          type: \"heading\",\n          depth: void 0,\n          children: []\n        };\n      }\n      function hardBreak() {\n        return {\n          type: \"break\"\n        };\n      }\n      function html() {\n        return {\n          type: \"html\",\n          value: \"\"\n        };\n      }\n      function image() {\n        return {\n          type: \"image\",\n          title: null,\n          url: \"\",\n          alt: null\n        };\n      }\n      function link() {\n        return {\n          type: \"link\",\n          title: null,\n          url: \"\",\n          children: []\n        };\n      }\n      function list2(token) {\n        return {\n          type: \"list\",\n          ordered: token.type === \"listOrdered\",\n          start: null,\n          spread: token._spread,\n          children: []\n        };\n      }\n      function listItem(token) {\n        return {\n          type: \"listItem\",\n          spread: token._spread,\n          checked: null,\n          children: []\n        };\n      }\n      function paragraph() {\n        return {\n          type: \"paragraph\",\n          children: []\n        };\n      }\n      function strong() {\n        return {\n          type: \"strong\",\n          children: []\n        };\n      }\n      function text3() {\n        return {\n          type: \"text\",\n          value: \"\"\n        };\n      }\n      function thematicBreak2() {\n        return {\n          type: \"thematicBreak\"\n        };\n      }\n    }\n    function configure(combined, extensions) {\n      let index2 = -1;\n      while (++index2 < extensions.length) {\n        const value2 = extensions[index2];\n        if (Array.isArray(value2)) {\n          configure(combined, value2);\n        } else {\n          extension(combined, value2);\n        }\n      }\n      return combined;\n    }\n    function extension(combined, extension2) {\n      let key;\n      for (key in extension2) {\n        if (own3.call(extension2, key)) {\n          const list2 = key === \"canContainEols\" || key === \"transforms\";\n          const maybe = own3.call(combined, key) ? combined[key] : void 0;\n          const left = maybe || (combined[key] = list2 ? [] : {});\n          const right = extension2[key];\n          if (right) {\n            if (list2) {\n              combined[key] = [...left, ...right];\n            } else {\n              Object.assign(left, right);\n            }\n          }\n        }\n      }\n    }\n    function remarkParse(options) {\n      const parser = (doc) => {\n        const settings = this.data(\"settings\");\n        return fromMarkdown(doc, Object.assign({}, settings, options, {\n          extensions: this.data(\"micromarkExtensions\") || [],\n          mdastExtensions: this.data(\"fromMarkdownExtensions\") || []\n        }));\n      };\n      Object.assign(this, { Parser: parser });\n    }\n    var remark_parse_default = remarkParse;\n    function bail(error) {\n      if (error) {\n        throw error;\n      }\n    }\n    var import_is_buffer2 = __toModule(require_is_buffer());\n    var import_extend = __toModule(require_extend());\n    function isPlainObject(value2) {\n      if (Object.prototype.toString.call(value2) !== \"[object Object]\") {\n        return false;\n      }\n      const prototype = Object.getPrototypeOf(value2);\n      return prototype === null || prototype === Object.prototype;\n    }\n    function trough() {\n      const fns = [];\n      const pipeline = { run, use };\n      return pipeline;\n      function run(...values) {\n        let middlewareIndex = -1;\n        const callback = values.pop();\n        if (typeof callback !== \"function\") {\n          throw new TypeError(\"Expected function as last argument, not \" + callback);\n        }\n        next(null, ...values);\n        function next(error, ...output) {\n          const fn = fns[++middlewareIndex];\n          let index2 = -1;\n          if (error) {\n            callback(error);\n            return;\n          }\n          while (++index2 < values.length) {\n            if (output[index2] === null || output[index2] === void 0) {\n              output[index2] = values[index2];\n            }\n          }\n          values = output;\n          if (fn) {\n            wrap(fn, next)(...output);\n          } else {\n            callback(null, ...output);\n          }\n        }\n      }\n      function use(middelware) {\n        if (typeof middelware !== \"function\") {\n          throw new TypeError(\"Expected `middelware` to be a function, not \" + middelware);\n        }\n        fns.push(middelware);\n        return pipeline;\n      }\n    }\n    function wrap(middleware, callback) {\n      let called;\n      return wrapped;\n      function wrapped(...parameters) {\n        const fnExpectsCallback = middleware.length > parameters.length;\n        let result;\n        if (fnExpectsCallback) {\n          parameters.push(done);\n        }\n        try {\n          result = middleware(...parameters);\n        } catch (error) {\n          const exception = error;\n          if (fnExpectsCallback && called) {\n            throw exception;\n          }\n          return done(exception);\n        }\n        if (!fnExpectsCallback) {\n          if (result instanceof Promise) {\n            result.then(then, done);\n          } else if (result instanceof Error) {\n            done(result);\n          } else {\n            then(result);\n          }\n        }\n      }\n      function done(error, ...output) {\n        if (!called) {\n          called = true;\n          callback(error, ...output);\n        }\n      }\n      function then(value2) {\n        done(null, value2);\n      }\n    }\n    var import_is_buffer = __toModule(require_is_buffer());\n    var VFileMessage = class extends Error {\n      constructor(reason, place, origin) {\n        var parts = [null, null];\n        var position2 = {\n          start: { line: null, column: null },\n          end: { line: null, column: null }\n        };\n        var index2;\n        super();\n        if (typeof place === \"string\") {\n          origin = place;\n          place = null;\n        }\n        if (typeof origin === \"string\") {\n          index2 = origin.indexOf(\":\");\n          if (index2 === -1) {\n            parts[1] = origin;\n          } else {\n            parts[0] = origin.slice(0, index2);\n            parts[1] = origin.slice(index2 + 1);\n          }\n        }\n        if (place) {\n          if (\"type\" in place || \"position\" in place) {\n            if (place.position) {\n              position2 = place.position;\n            }\n          } else if (\"start\" in place || \"end\" in place) {\n            position2 = place;\n          } else if (\"line\" in place || \"column\" in place) {\n            position2.start = place;\n          }\n        }\n        this.name = stringifyPosition(place) || \"1:1\";\n        this.message = typeof reason === \"object\" ? reason.message : reason;\n        this.stack = typeof reason === \"object\" ? reason.stack : \"\";\n        this.reason = this.message;\n        this.line = position2.start.line;\n        this.column = position2.start.column;\n        this.source = parts[0];\n        this.ruleId = parts[1];\n        this.position = position2;\n        this.file;\n        this.fatal;\n        this.url;\n        this.note;\n      }\n    };\n    VFileMessage.prototype.file = \"\";\n    VFileMessage.prototype.name = \"\";\n    VFileMessage.prototype.reason = \"\";\n    VFileMessage.prototype.message = \"\";\n    VFileMessage.prototype.stack = \"\";\n    VFileMessage.prototype.fatal = null;\n    VFileMessage.prototype.column = null;\n    VFileMessage.prototype.line = null;\n    VFileMessage.prototype.source = null;\n    VFileMessage.prototype.ruleId = null;\n    VFileMessage.prototype.position = null;\n    var path = { basename, dirname, extname, join, sep: \"/\" };\n    function basename(path2, ext) {\n      if (ext !== void 0 && typeof ext !== \"string\") {\n        throw new TypeError('\"ext\" argument must be a string');\n      }\n      assertPath(path2);\n      let start = 0;\n      let end = -1;\n      let index2 = path2.length;\n      let seenNonSlash;\n      if (ext === void 0 || ext.length === 0 || ext.length > path2.length) {\n        while (index2--) {\n          if (path2.charCodeAt(index2) === 47) {\n            if (seenNonSlash) {\n              start = index2 + 1;\n              break;\n            }\n          } else if (end < 0) {\n            seenNonSlash = true;\n            end = index2 + 1;\n          }\n        }\n        return end < 0 ? \"\" : path2.slice(start, end);\n      }\n      if (ext === path2) {\n        return \"\";\n      }\n      let firstNonSlashEnd = -1;\n      let extIndex = ext.length - 1;\n      while (index2--) {\n        if (path2.charCodeAt(index2) === 47) {\n          if (seenNonSlash) {\n            start = index2 + 1;\n            break;\n          }\n        } else {\n          if (firstNonSlashEnd < 0) {\n            seenNonSlash = true;\n            firstNonSlashEnd = index2 + 1;\n          }\n          if (extIndex > -1) {\n            if (path2.charCodeAt(index2) === ext.charCodeAt(extIndex--)) {\n              if (extIndex < 0) {\n                end = index2;\n              }\n            } else {\n              extIndex = -1;\n              end = firstNonSlashEnd;\n            }\n          }\n        }\n      }\n      if (start === end) {\n        end = firstNonSlashEnd;\n      } else if (end < 0) {\n        end = path2.length;\n      }\n      return path2.slice(start, end);\n    }\n    function dirname(path2) {\n      assertPath(path2);\n      if (path2.length === 0) {\n        return \".\";\n      }\n      let end = -1;\n      let index2 = path2.length;\n      let unmatchedSlash;\n      while (--index2) {\n        if (path2.charCodeAt(index2) === 47) {\n          if (unmatchedSlash) {\n            end = index2;\n            break;\n          }\n        } else if (!unmatchedSlash) {\n          unmatchedSlash = true;\n        }\n      }\n      return end < 0 ? path2.charCodeAt(0) === 47 ? \"/\" : \".\" : end === 1 && path2.charCodeAt(0) === 47 ? \"//\" : path2.slice(0, end);\n    }\n    function extname(path2) {\n      assertPath(path2);\n      let index2 = path2.length;\n      let end = -1;\n      let startPart = 0;\n      let startDot = -1;\n      let preDotState = 0;\n      let unmatchedSlash;\n      while (index2--) {\n        const code = path2.charCodeAt(index2);\n        if (code === 47) {\n          if (unmatchedSlash) {\n            startPart = index2 + 1;\n            break;\n          }\n          continue;\n        }\n        if (end < 0) {\n          unmatchedSlash = true;\n          end = index2 + 1;\n        }\n        if (code === 46) {\n          if (startDot < 0) {\n            startDot = index2;\n          } else if (preDotState !== 1) {\n            preDotState = 1;\n          }\n        } else if (startDot > -1) {\n          preDotState = -1;\n        }\n      }\n      if (startDot < 0 || end < 0 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {\n        return \"\";\n      }\n      return path2.slice(startDot, end);\n    }\n    function join(...segments) {\n      let index2 = -1;\n      let joined;\n      while (++index2 < segments.length) {\n        assertPath(segments[index2]);\n        if (segments[index2]) {\n          joined = joined === void 0 ? segments[index2] : joined + \"/\" + segments[index2];\n        }\n      }\n      return joined === void 0 ? \".\" : normalize(joined);\n    }\n    function normalize(path2) {\n      assertPath(path2);\n      const absolute = path2.charCodeAt(0) === 47;\n      let value2 = normalizeString(path2, !absolute);\n      if (value2.length === 0 && !absolute) {\n        value2 = \".\";\n      }\n      if (value2.length > 0 && path2.charCodeAt(path2.length - 1) === 47) {\n        value2 += \"/\";\n      }\n      return absolute ? \"/\" + value2 : value2;\n    }\n    function normalizeString(path2, allowAboveRoot) {\n      let result = \"\";\n      let lastSegmentLength = 0;\n      let lastSlash = -1;\n      let dots = 0;\n      let index2 = -1;\n      let code;\n      let lastSlashIndex;\n      while (++index2 <= path2.length) {\n        if (index2 < path2.length) {\n          code = path2.charCodeAt(index2);\n        } else if (code === 47) {\n          break;\n        } else {\n          code = 47;\n        }\n        if (code === 47) {\n          if (lastSlash === index2 - 1 || dots === 1) {\n          } else if (lastSlash !== index2 - 1 && dots === 2) {\n            if (result.length < 2 || lastSegmentLength !== 2 || result.charCodeAt(result.length - 1) !== 46 || result.charCodeAt(result.length - 2) !== 46) {\n              if (result.length > 2) {\n                lastSlashIndex = result.lastIndexOf(\"/\");\n                if (lastSlashIndex !== result.length - 1) {\n                  if (lastSlashIndex < 0) {\n                    result = \"\";\n                    lastSegmentLength = 0;\n                  } else {\n                    result = result.slice(0, lastSlashIndex);\n                    lastSegmentLength = result.length - 1 - result.lastIndexOf(\"/\");\n                  }\n                  lastSlash = index2;\n                  dots = 0;\n                  continue;\n                }\n              } else if (result.length > 0) {\n                result = \"\";\n                lastSegmentLength = 0;\n                lastSlash = index2;\n                dots = 0;\n                continue;\n              }\n            }\n            if (allowAboveRoot) {\n              result = result.length > 0 ? result + \"/..\" : \"..\";\n              lastSegmentLength = 2;\n            }\n          } else {\n            if (result.length > 0) {\n              result += \"/\" + path2.slice(lastSlash + 1, index2);\n            } else {\n              result = path2.slice(lastSlash + 1, index2);\n            }\n            lastSegmentLength = index2 - lastSlash - 1;\n          }\n          lastSlash = index2;\n          dots = 0;\n        } else if (code === 46 && dots > -1) {\n          dots++;\n        } else {\n          dots = -1;\n        }\n      }\n      return result;\n    }\n    function assertPath(path2) {\n      if (typeof path2 !== \"string\") {\n        throw new TypeError(\"Path must be a string. Received \" + JSON.stringify(path2));\n      }\n    }\n    var proc = { cwd };\n    function cwd() {\n      return \"/\";\n    }\n    function isUrl(fileURLOrPath) {\n      return fileURLOrPath !== null && typeof fileURLOrPath === \"object\" && fileURLOrPath.href && fileURLOrPath.origin;\n    }\n    function urlToPath(path2) {\n      if (typeof path2 === \"string\") {\n        path2 = new URL(path2);\n      } else if (!isUrl(path2)) {\n        const error = new TypeError('The \"path\" argument must be of type string or an instance of URL. Received `' + path2 + \"`\");\n        error.code = \"ERR_INVALID_ARG_TYPE\";\n        throw error;\n      }\n      if (path2.protocol !== \"file:\") {\n        const error = new TypeError(\"The URL must be of scheme file\");\n        error.code = \"ERR_INVALID_URL_SCHEME\";\n        throw error;\n      }\n      return getPathFromURLPosix(path2);\n    }\n    function getPathFromURLPosix(url) {\n      if (url.hostname !== \"\") {\n        const error = new TypeError('File URL host must be \"localhost\" or empty on darwin');\n        error.code = \"ERR_INVALID_FILE_URL_HOST\";\n        throw error;\n      }\n      const pathname = url.pathname;\n      let index2 = -1;\n      while (++index2 < pathname.length) {\n        if (pathname.charCodeAt(index2) === 37 && pathname.charCodeAt(index2 + 1) === 50) {\n          const third = pathname.charCodeAt(index2 + 2);\n          if (third === 70 || third === 102) {\n            const error = new TypeError(\"File URL path must not include encoded / characters\");\n            error.code = \"ERR_INVALID_FILE_URL_PATH\";\n            throw error;\n          }\n        }\n      }\n      return decodeURIComponent(pathname);\n    }\n    var order = [\"history\", \"path\", \"basename\", \"stem\", \"extname\", \"dirname\"];\n    var VFile = class {\n      constructor(value2) {\n        let options;\n        if (!value2) {\n          options = {};\n        } else if (typeof value2 === \"string\" || (0, import_is_buffer.default)(value2)) {\n          options = { value: value2 };\n        } else if (isUrl(value2)) {\n          options = { path: value2 };\n        } else {\n          options = value2;\n        }\n        this.data = {};\n        this.messages = [];\n        this.history = [];\n        this.cwd = proc.cwd();\n        this.value;\n        this.stored;\n        this.result;\n        this.map;\n        let index2 = -1;\n        while (++index2 < order.length) {\n          const prop2 = order[index2];\n          if (prop2 in options && options[prop2] !== void 0) {\n            this[prop2] = prop2 === \"history\" ? [...options[prop2]] : options[prop2];\n          }\n        }\n        let prop;\n        for (prop in options) {\n          if (!order.includes(prop))\n            this[prop] = options[prop];\n        }\n      }\n      get path() {\n        return this.history[this.history.length - 1];\n      }\n      set path(path2) {\n        if (isUrl(path2)) {\n          path2 = urlToPath(path2);\n        }\n        assertNonEmpty(path2, \"path\");\n        if (this.path !== path2) {\n          this.history.push(path2);\n        }\n      }\n      get dirname() {\n        return typeof this.path === \"string\" ? path.dirname(this.path) : void 0;\n      }\n      set dirname(dirname2) {\n        assertPath2(this.basename, \"dirname\");\n        this.path = path.join(dirname2 || \"\", this.basename);\n      }\n      get basename() {\n        return typeof this.path === \"string\" ? path.basename(this.path) : void 0;\n      }\n      set basename(basename2) {\n        assertNonEmpty(basename2, \"basename\");\n        assertPart(basename2, \"basename\");\n        this.path = path.join(this.dirname || \"\", basename2);\n      }\n      get extname() {\n        return typeof this.path === \"string\" ? path.extname(this.path) : void 0;\n      }\n      set extname(extname2) {\n        assertPart(extname2, \"extname\");\n        assertPath2(this.dirname, \"extname\");\n        if (extname2) {\n          if (extname2.charCodeAt(0) !== 46) {\n            throw new Error(\"`extname` must start with `.`\");\n          }\n          if (extname2.includes(\".\", 1)) {\n            throw new Error(\"`extname` cannot contain multiple dots\");\n          }\n        }\n        this.path = path.join(this.dirname, this.stem + (extname2 || \"\"));\n      }\n      get stem() {\n        return typeof this.path === \"string\" ? path.basename(this.path, this.extname) : void 0;\n      }\n      set stem(stem) {\n        assertNonEmpty(stem, \"stem\");\n        assertPart(stem, \"stem\");\n        this.path = path.join(this.dirname || \"\", stem + (this.extname || \"\"));\n      }\n      toString(encoding) {\n        return (this.value || \"\").toString(encoding);\n      }\n      message(reason, place, origin) {\n        const message = new VFileMessage(reason, place, origin);\n        if (this.path) {\n          message.name = this.path + \":\" + message.name;\n          message.file = this.path;\n        }\n        message.fatal = false;\n        this.messages.push(message);\n        return message;\n      }\n      info(reason, place, origin) {\n        const message = this.message(reason, place, origin);\n        message.fatal = null;\n        return message;\n      }\n      fail(reason, place, origin) {\n        const message = this.message(reason, place, origin);\n        message.fatal = true;\n        throw message;\n      }\n    };\n    function assertPart(part, name) {\n      if (part && part.includes(path.sep)) {\n        throw new Error(\"`\" + name + \"` cannot be a path: did not expect `\" + path.sep + \"`\");\n      }\n    }\n    function assertNonEmpty(part, name) {\n      if (!part) {\n        throw new Error(\"`\" + name + \"` cannot be empty\");\n      }\n    }\n    function assertPath2(path2, name) {\n      if (!path2) {\n        throw new Error(\"Setting `\" + name + \"` requires `path` to be set too\");\n      }\n    }\n    var unified = base().freeze();\n    var own4 = {}.hasOwnProperty;\n    function base() {\n      const transformers = trough();\n      const attachers = [];\n      let namespace = {};\n      let frozen;\n      let freezeIndex = -1;\n      processor.data = data;\n      processor.Parser = void 0;\n      processor.Compiler = void 0;\n      processor.freeze = freeze;\n      processor.attachers = attachers;\n      processor.use = use;\n      processor.parse = parse3;\n      processor.stringify = stringify;\n      processor.run = run;\n      processor.runSync = runSync;\n      processor.process = process;\n      processor.processSync = processSync;\n      return processor;\n      function processor() {\n        const destination = base();\n        let index2 = -1;\n        while (++index2 < attachers.length) {\n          destination.use(...attachers[index2]);\n        }\n        destination.data((0, import_extend.default)(true, {}, namespace));\n        return destination;\n      }\n      function data(key, value2) {\n        if (typeof key === \"string\") {\n          if (arguments.length === 2) {\n            assertUnfrozen(\"data\", frozen);\n            namespace[key] = value2;\n            return processor;\n          }\n          return own4.call(namespace, key) && namespace[key] || null;\n        }\n        if (key) {\n          assertUnfrozen(\"data\", frozen);\n          namespace = key;\n          return processor;\n        }\n        return namespace;\n      }\n      function freeze() {\n        if (frozen) {\n          return processor;\n        }\n        while (++freezeIndex < attachers.length) {\n          const [attacher, ...options] = attachers[freezeIndex];\n          if (options[0] === false) {\n            continue;\n          }\n          if (options[0] === true) {\n            options[1] = void 0;\n          }\n          const transformer = attacher.call(processor, ...options);\n          if (typeof transformer === \"function\") {\n            transformers.use(transformer);\n          }\n        }\n        frozen = true;\n        freezeIndex = Number.POSITIVE_INFINITY;\n        return processor;\n      }\n      function use(value2, ...options) {\n        let settings;\n        assertUnfrozen(\"use\", frozen);\n        if (value2 === null || value2 === void 0) {\n        } else if (typeof value2 === \"function\") {\n          addPlugin(value2, ...options);\n        } else if (typeof value2 === \"object\") {\n          if (Array.isArray(value2)) {\n            addList(value2);\n          } else {\n            addPreset(value2);\n          }\n        } else {\n          throw new TypeError(\"Expected usable value, not `\" + value2 + \"`\");\n        }\n        if (settings) {\n          namespace.settings = Object.assign(namespace.settings || {}, settings);\n        }\n        return processor;\n        function add(value3) {\n          if (typeof value3 === \"function\") {\n            addPlugin(value3);\n          } else if (typeof value3 === \"object\") {\n            if (Array.isArray(value3)) {\n              const [plugin, ...options2] = value3;\n              addPlugin(plugin, ...options2);\n            } else {\n              addPreset(value3);\n            }\n          } else {\n            throw new TypeError(\"Expected usable value, not `\" + value3 + \"`\");\n          }\n        }\n        function addPreset(result) {\n          addList(result.plugins);\n          if (result.settings) {\n            settings = Object.assign(settings || {}, result.settings);\n          }\n        }\n        function addList(plugins) {\n          let index2 = -1;\n          if (plugins === null || plugins === void 0) {\n          } else if (Array.isArray(plugins)) {\n            while (++index2 < plugins.length) {\n              const thing = plugins[index2];\n              add(thing);\n            }\n          } else {\n            throw new TypeError(\"Expected a list of plugins, not `\" + plugins + \"`\");\n          }\n        }\n        function addPlugin(plugin, value3) {\n          let index2 = -1;\n          let entry;\n          while (++index2 < attachers.length) {\n            if (attachers[index2][0] === plugin) {\n              entry = attachers[index2];\n              break;\n            }\n          }\n          if (entry) {\n            if (isPlainObject(entry[1]) && isPlainObject(value3)) {\n              value3 = (0, import_extend.default)(true, entry[1], value3);\n            }\n            entry[1] = value3;\n          } else {\n            attachers.push([...arguments]);\n          }\n        }\n      }\n      function parse3(doc) {\n        processor.freeze();\n        const file = vfile(doc);\n        const Parser = processor.Parser;\n        assertParser(\"parse\", Parser);\n        if (newable(Parser, \"parse\")) {\n          return new Parser(String(file), file).parse();\n        }\n        return Parser(String(file), file);\n      }\n      function stringify(node, doc) {\n        processor.freeze();\n        const file = vfile(doc);\n        const Compiler = processor.Compiler;\n        assertCompiler(\"stringify\", Compiler);\n        assertNode(node);\n        if (newable(Compiler, \"compile\")) {\n          return new Compiler(node, file).compile();\n        }\n        return Compiler(node, file);\n      }\n      function run(node, doc, callback) {\n        assertNode(node);\n        processor.freeze();\n        if (!callback && typeof doc === \"function\") {\n          callback = doc;\n          doc = void 0;\n        }\n        if (!callback) {\n          return new Promise(executor);\n        }\n        executor(null, callback);\n        function executor(resolve, reject) {\n          transformers.run(node, vfile(doc), done);\n          function done(error, tree, file) {\n            tree = tree || node;\n            if (error) {\n              reject(error);\n            } else if (resolve) {\n              resolve(tree);\n            } else {\n              callback(null, tree, file);\n            }\n          }\n        }\n      }\n      function runSync(node, file) {\n        let result;\n        let complete;\n        processor.run(node, file, done);\n        assertDone(\"runSync\", \"run\", complete);\n        return result;\n        function done(error, tree) {\n          bail(error);\n          result = tree;\n          complete = true;\n        }\n      }\n      function process(doc, callback) {\n        processor.freeze();\n        assertParser(\"process\", processor.Parser);\n        assertCompiler(\"process\", processor.Compiler);\n        if (!callback) {\n          return new Promise(executor);\n        }\n        executor(null, callback);\n        function executor(resolve, reject) {\n          const file = vfile(doc);\n          processor.run(processor.parse(file), file, (error, tree, file2) => {\n            if (error || !tree || !file2) {\n              done(error);\n            } else {\n              const result = processor.stringify(tree, file2);\n              if (result === void 0 || result === null) {\n              } else if (looksLikeAVFileValue(result)) {\n                file2.value = result;\n              } else {\n                file2.result = result;\n              }\n              done(error, file2);\n            }\n          });\n          function done(error, file2) {\n            if (error || !file2) {\n              reject(error);\n            } else if (resolve) {\n              resolve(file2);\n            } else {\n              callback(null, file2);\n            }\n          }\n        }\n      }\n      function processSync(doc) {\n        let complete;\n        processor.freeze();\n        assertParser(\"processSync\", processor.Parser);\n        assertCompiler(\"processSync\", processor.Compiler);\n        const file = vfile(doc);\n        processor.process(file, done);\n        assertDone(\"processSync\", \"process\", complete);\n        return file;\n        function done(error) {\n          complete = true;\n          bail(error);\n        }\n      }\n    }\n    function newable(value2, name) {\n      return typeof value2 === \"function\" && value2.prototype && (keys(value2.prototype) || name in value2.prototype);\n    }\n    function keys(value2) {\n      let key;\n      for (key in value2) {\n        if (own4.call(value2, key)) {\n          return true;\n        }\n      }\n      return false;\n    }\n    function assertParser(name, value2) {\n      if (typeof value2 !== \"function\") {\n        throw new TypeError(\"Cannot `\" + name + \"` without `Parser`\");\n      }\n    }\n    function assertCompiler(name, value2) {\n      if (typeof value2 !== \"function\") {\n        throw new TypeError(\"Cannot `\" + name + \"` without `Compiler`\");\n      }\n    }\n    function assertUnfrozen(name, frozen) {\n      if (frozen) {\n        throw new Error(\"Cannot call `\" + name + \"` on a frozen processor.\\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.\");\n      }\n    }\n    function assertNode(node) {\n      if (!isPlainObject(node) || typeof node.type !== \"string\") {\n        throw new TypeError(\"Expected node, got `\" + node + \"`\");\n      }\n    }\n    function assertDone(name, asyncName, complete) {\n      if (!complete) {\n        throw new Error(\"`\" + name + \"` finished async. Use `\" + asyncName + \"` instead\");\n      }\n    }\n    function vfile(value2) {\n      return looksLikeAVFile(value2) ? value2 : new VFile(value2);\n    }\n    function looksLikeAVFile(value2) {\n      return Boolean(value2 && typeof value2 === \"object\" && \"message\" in value2 && \"messages\" in value2);\n    }\n    function looksLikeAVFileValue(value2) {\n      return typeof value2 === \"string\" || (0, import_is_buffer2.default)(value2);\n    }\n    var defaults2 = {\n      children(node) {\n        return defaults.children(node);\n      },\n      annotatetextnode(node, text3) {\n        return defaults.annotatetextnode(node, text3);\n      },\n      interpretmarkup(text3 = \"\") {\n        return \"\\n\".repeat((text3.match(/\\n/g) || []).length);\n      },\n      remarkoptions: {}\n    };\n    function build2(text3, options = defaults2) {\n      const processor = unified().use(remark_parse_default, options.remarkoptions).use(remarkFrontmatter, [\"yaml\", \"toml\"]);\n      return build(text3, processor.parse, options);\n    }\n    var prepareMarkdown = (text3) => JSON.stringify(build2(text3));\n    var prepareMarkdown_default = prepareMarkdown;\n  }\n});\n\n// src/requests/checkViaAPI.js\nvar require_checkViaAPI = __commonJS({\n  \"src/requests/checkViaAPI.js\"(exports, module) {\n    var queryString = require_query_string();\n    var initialConfig = require_initialConfig();\n    var prepareMarkdown = require_prepareMarkdown().default;\n    var addWordFields = (matches) => {\n      return matches.map((match) => {\n        const word = match.context.text.substr(match.context.offset, match.context.length);\n        return { ...match, word };\n      });\n    };\n    var removeFalsePositives = (matches, dictionary, disabledRules) => {\n      return matches.filter((match) => !disabledRules.includes(match.rule.category.id) && !(match.rule.issueType === \"misspelling\" && dictionary.includes(match.word)));\n    };\n    var MAX_REPLACEMENTS = 30;\n    var checkViaAPI = async (text, options = {}) => {\n      const cfg = { ...initialConfig, ...options };\n      const disabledRules = Object.entries(cfg.rules).filter(([rule, value]) => value === false).map(([rule]) => rule.toUpperCase());\n      const disabledRulesEntry = disabledRules.length === 0 || cfg.api_url.includes(\"grammarbot\") ? {} : { disabledCategories: disabledRules.join(\",\") };\n      const input = options.markdown ? { data: prepareMarkdown(text) } : { text };\n      const postData = queryString.stringify({\n        api_key: cfg.api_key,\n        language: cfg.language,\n        ...input,\n        ...disabledRulesEntry\n      });\n      const response = await fetch(cfg.api_url, {\n        headers: {\n          \"Content-Type\": \"application/x-www-form-urlencoded\"\n        },\n        body: postData,\n        method: \"POST\"\n      });\n      const body = await response.text();\n      let result;\n      try {\n        result = JSON.parse(body);\n      } catch (e) {\n        if (cfg.api_url.includes(\"grammarbot\")) {\n          throw new Error(\"Language not available at grammarbot.io.\\nPlease consider installing a local LanguageTool server:\\nhttps://github.com/caderek/gramma#installing-local-server\");\n        } else {\n          throw new Error(body);\n        }\n      }\n      const resultWithWords = {\n        ...result,\n        matches: removeFalsePositives(addWordFields(result.matches), cfg.dictionary, cfg.api_url === initialConfig.api_url ? disabledRules : [])\n      };\n      resultWithWords.matches.forEach((match) => {\n        if (match.replacements.length > MAX_REPLACEMENTS) {\n          match.replacements.length = MAX_REPLACEMENTS;\n        }\n      });\n      return resultWithWords;\n    };\n    module.exports = checkViaAPI;\n  }\n});\n\n// src/text-manipulation/replace.js\nvar require_replace = __commonJS({\n  \"src/text-manipulation/replace.js\"(exports, module) {\n    var replace = (text, change, offset, length) => {\n      const before = text.slice(0, offset);\n      const mistake = text.slice(offset, offset + length);\n      const after = text.slice(offset + length);\n      const newPhrase = typeof change === \"function\" ? change(mistake) : change;\n      return `${before}${newPhrase}${after}`;\n    };\n    module.exports = replace;\n  }\n});\n\n// src/text-manipulation/replaceAll.js\nvar require_replaceAll = __commonJS({\n  \"src/text-manipulation/replaceAll.js\"(exports, module) {\n    var replace = require_replace();\n    var replaceAll = (text, transformations) => {\n      return transformations.sort((a, b) => b.offset - a.offset).reduce((previousText, { change, offset, length }) => {\n        return replace(previousText, change, offset, length);\n      }, text);\n    };\n    module.exports = replaceAll;\n  }\n});\n\n// src/index.js\nvar require_src = __commonJS({\n  \"src/index.js\"(exports, module) {\n    require_fetch_npm_browserify();\n    var check = require_checkViaAPI();\n    var replaceAll = require_replaceAll();\n    module.exports = {\n      check,\n      replaceAll\n    };\n  }\n});\nexport default require_src();\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <https://feross.org>\n * @license  MIT\n */\n"
  },
  {
    "path": "data/languages.json",
    "content": "[\n  {\n    \"name\": \"Arabic\",\n    \"code\": \"ar\",\n    \"longCode\": \"ar\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Asturian\",\n    \"code\": \"ast\",\n    \"longCode\": \"ast-ES\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Belarusian\",\n    \"code\": \"be\",\n    \"longCode\": \"be-BY\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Breton\",\n    \"code\": \"br\",\n    \"longCode\": \"br-FR\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Catalan\",\n    \"code\": \"ca\",\n    \"longCode\": \"ca-ES\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Catalan (Valencian)\",\n    \"code\": \"ca\",\n    \"longCode\": \"ca-ES-valencia\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Chinese\",\n    \"code\": \"zh\",\n    \"longCode\": \"zh-CN\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Danish\",\n    \"code\": \"da\",\n    \"longCode\": \"da-DK\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Dutch\",\n    \"code\": \"nl\",\n    \"longCode\": \"nl\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Dutch (Belgium)\",\n    \"code\": \"nl\",\n    \"longCode\": \"nl-BE\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"English\",\n    \"code\": \"en\",\n    \"longCode\": \"en\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"English (Australian)\",\n    \"code\": \"en\",\n    \"longCode\": \"en-AU\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"English (Canadian)\",\n    \"code\": \"en\",\n    \"longCode\": \"en-CA\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"English (GB)\",\n    \"code\": \"en\",\n    \"longCode\": \"en-GB\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"English (New Zealand)\",\n    \"code\": \"en\",\n    \"longCode\": \"en-NZ\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"English (South African)\",\n    \"code\": \"en\",\n    \"longCode\": \"en-ZA\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"English (US)\",\n    \"code\": \"en\",\n    \"longCode\": \"en-US\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Esperanto\",\n    \"code\": \"eo\",\n    \"longCode\": \"eo\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"French\",\n    \"code\": \"fr\",\n    \"longCode\": \"fr\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Galician\",\n    \"code\": \"gl\",\n    \"longCode\": \"gl-ES\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"German\",\n    \"code\": \"de\",\n    \"longCode\": \"de\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"German (Austria)\",\n    \"code\": \"de\",\n    \"longCode\": \"de-AT\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"German (Germany)\",\n    \"code\": \"de\",\n    \"longCode\": \"de-DE\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"German (Swiss)\",\n    \"code\": \"de\",\n    \"longCode\": \"de-CH\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Greek\",\n    \"code\": \"el\",\n    \"longCode\": \"el-GR\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Irish\",\n    \"code\": \"ga\",\n    \"longCode\": \"ga-IE\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Italian\",\n    \"code\": \"it\",\n    \"longCode\": \"it\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Japanese\",\n    \"code\": \"ja\",\n    \"longCode\": \"ja-JP\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Khmer\",\n    \"code\": \"km\",\n    \"longCode\": \"km-KH\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Persian\",\n    \"code\": \"fa\",\n    \"longCode\": \"fa\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Polish\",\n    \"code\": \"pl\",\n    \"longCode\": \"pl-PL\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Portuguese\",\n    \"code\": \"pt\",\n    \"longCode\": \"pt\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Portuguese (Angola preAO)\",\n    \"code\": \"pt\",\n    \"longCode\": \"pt-AO\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Portuguese (Brazil)\",\n    \"code\": \"pt\",\n    \"longCode\": \"pt-BR\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Portuguese (Moçambique preAO)\",\n    \"code\": \"pt\",\n    \"longCode\": \"pt-MZ\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Portuguese (Portugal)\",\n    \"code\": \"pt\",\n    \"longCode\": \"pt-PT\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Romanian\",\n    \"code\": \"ro\",\n    \"longCode\": \"ro-RO\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Russian\",\n    \"code\": \"ru\",\n    \"longCode\": \"ru-RU\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Simple German\",\n    \"code\": \"de-DE-x-simple-language\",\n    \"longCode\": \"de-DE-x-simple-language\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Slovak\",\n    \"code\": \"sk\",\n    \"longCode\": \"sk-SK\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Slovenian\",\n    \"code\": \"sl\",\n    \"longCode\": \"sl-SI\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Spanish\",\n    \"code\": \"es\",\n    \"longCode\": \"es\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Spanish (voseo)\",\n    \"code\": \"es\",\n    \"longCode\": \"es-AR\",\n    \"grammarbotIo\": false,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Swedish\",\n    \"code\": \"sv\",\n    \"longCode\": \"sv\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Tagalog\",\n    \"code\": \"tl\",\n    \"longCode\": \"tl-PH\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Tamil\",\n    \"code\": \"ta\",\n    \"longCode\": \"ta-IN\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  },\n  {\n    \"name\": \"Ukrainian\",\n    \"code\": \"uk\",\n    \"longCode\": \"uk-UA\",\n    \"grammarbotIo\": true,\n    \"languagetoolOrg\": true\n  }\n]"
  },
  {
    "path": "data/rules.json",
    "content": "[\n  {\n    \"id\": \"CASING\",\n    \"description\": \"Detecting uppercase words where lowercase is required and vice versa.\"\n  },\n  {\n    \"id\": \"COLLOQUIALISMS\",\n    \"description\": \"Colloquial style.\"\n  },\n  {\n    \"id\": \"COMPOUNDING\",\n    \"description\": \"Rules about spelling terms as one word or as as separate words.\"\n  },\n  {\n    \"id\": \"CONFUSED_WORDS\",\n    \"description\": \"Words that are easily confused, like 'there' and 'their' in English.\"\n  },\n  {\n    \"id\": \"FALSE_FRIENDS\",\n    \"description\": \"Words easily confused by language learners because a similar word exists in their native language.\"\n  },\n  {\n    \"id\": \"GENDER_NEUTRALITY\",\n    \"description\": \"\"\n  },\n  {\n    \"id\": \"GRAMMAR\",\n    \"description\": \"\"\n  },\n  {\n    \"id\": \"MISC\",\n    \"description\": \"Miscellaneous rules that don't fit elsewhere.\"\n  },\n  {\n    \"id\": \"PUNCTUATION\",\n    \"description\": \"\"\n  },\n  {\n    \"id\": \"REDUNDANCY\",\n    \"description\": \"\"\n  },\n  {\n    \"id\": \"REGIONALISMS\",\n    \"description\": \"Words used only in another language variant or used with different meanings.\"\n  },\n  {\n    \"id\": \"REPETITIONS\",\n    \"description\": \"\"\n  },\n  {\n    \"id\": \"SEMANTICS\",\n    \"description\": \"Logic, content, and consistency problems.\"\n  },\n  {\n    \"id\": \"STYLE\",\n    \"description\": \"General style issues not covered by other categories, like overly verbose wording.\"\n  },\n  {\n    \"id\": \"TYPOGRAPHY\",\n    \"description\": \"Problems like incorrectly used dash or quote characters.\"\n  },\n  {\n    \"id\": \"TYPOS\",\n    \"description\": \"Spelling issues.\"\n  }\n]\n"
  },
  {
    "path": "examples/api-markdown.js",
    "content": "const { check } = require(\"../src\")\n\nconst main = async () => {\n  const { language, matches } = await check(`<a href=\"#xyz\">Helo</a> worlt!`, {\n    markdown: true,\n  })\n\n  console.log({ lang: language.name, mistakes: matches.length })\n}\n\nmain()\n"
  },
  {
    "path": "examples/api-plain.js",
    "content": "const { check } = require(\"../src\")\n\nconst main = async () => {\n  const response = await check(`Helo worlt!`, {\n    markdown: true,\n  })\n\n  console.dir(response, { depth: null })\n}\n\nmain()\n"
  },
  {
    "path": "examples/api-simple.js",
    "content": "const { check } = require(\"../src\")\n\nconst main = async () => {\n  const { language, matches } = await check(\"Some wrongg text to check.\")\n\n  console.log({ lang: language.name, mistakes: matches.length })\n}\n\nmain()\n"
  },
  {
    "path": "hello.md",
    "content": "Hello world!\n\n"
  },
  {
    "path": "lib/findUpSync.mjs",
    "content": "// esbuild findUpSync.mjs --bundle --outfile=src/utils/findUpSync.js --format=cjs --platform=node\nimport { findUpSync } from \"find-up\"\n\nexport default findUpSync\n"
  },
  {
    "path": "lib/package.json",
    "content": "{\n  \"name\": \"lib\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"keywords\": [],\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"annotatedtext-remark\": \"^1.0.1\",\n    \"find-up\": \"^6.2.0\"\n  }\n}\n"
  },
  {
    "path": "lib/prepareMarkdown.mjs",
    "content": "import * as builder from \"annotatedtext-remark\"\n\nconst prepareMarkdown = (text) => JSON.stringify(builder.build(text))\n\nexport default prepareMarkdown\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"gramma\",\n  \"version\": \"1.6.0\",\n  \"license\": \"ISC\",\n  \"repository\": \"https://github.com/caderek/gramma\",\n  \"homepage\": \"https://caderek.github.io/gramma/\",\n  \"description\": \"Command line grammar checker\",\n  \"main\": \"src/index.js\",\n  \"bin\": \"src/cli.js\",\n  \"exports\": {\n    \".\": \"./src/index.js\",\n    \"./esm\": \"./bundle/gramma.esm.js\",\n    \"./esm-min\": \"./bundle/gramma.esm.min.js\",\n    \"./iife\": \"./bundle/gramma.min.js\"\n  },\n  \"types\": \"src/index.d.ts\",\n  \"scripts\": {\n    \"build\": \"rm -rf bin; yarn run build:win64; yarn run build:macos; yarn run build:linux64; yarn run build:zip; yarn run build:bundles\",\n    \"build:win64\": \"pkg -c package.json -t node16-win-x64 --out-path bin/windows64 src/cli.js\",\n    \"build:macos\": \"pkg -c package.json -t node16-macos-x64 --out-path bin/macos src/cli.js\",\n    \"build:linux64\": \"pkg -c package.json -t node16-linux-x64 --out-path bin/linux64 src/cli.js\",\n    \"build:bundles\": \"yarn run build:esm; yarn run build:esm-min; yarn run build:iife\",\n    \"build:esm\": \"esbuild src/index.js --bundle --outfile=bundle/gramma.esm.js --format=esm\",\n    \"build:esm-min\": \"esbuild src/index.js --bundle --outfile=bundle/gramma.esm.min.js --format=esm --minify\",\n    \"build:iife\": \"esbuild src/index.js --bundle --outfile=bundle/gramma.min.js --format=iife --minify --global-name=gramma\",\n    \"build:zip\": \"node scripts/zipBinaries.js\",\n    \"format\": \"prettier --write \\\"src/**/*.js\\\"\",\n    \"lint\": \"eslint src/**\",\n    \"test\": \"jest\",\n    \"test:ci\": \"jest --coverage && cat ./coverage/lcov.info | codacy-coverage\",\n    \"check:langs\": \"node scripts/checkLanguagesSupport.js\",\n    \"prepare\": \"husky install\",\n    \"definitions\": \"tsc\"\n  },\n  \"keywords\": [\n    \"grammar\",\n    \"command-line\",\n    \"checker\"\n  ],\n  \"author\": \"Maciej Cąderek | maciej.caderek@gmail.com\",\n  \"dependencies\": {\n    \"cli-progress\": \"^3.9.1\",\n    \"decompress\": \"^4.2.1\",\n    \"decompress-unzip\": \"^4.0.1\",\n    \"dotenv\": \"^10.0.0\",\n    \"intercept-stdout\": \"^0.1.2\",\n    \"isomorphic-fetch\": \"^3.0.0\",\n    \"kleur\": \"^4.1.4\",\n    \"portfinder\": \"^1.0.28\",\n    \"progress-stream\": \"^2.0.0\",\n    \"prompts\": \"^2.4.1\",\n    \"query-string\": \"^7.0.1\",\n    \"rimraf\": \"^3.0.2\",\n    \"tcp-port-used\": \"^1.0.2\",\n    \"yargs\": \"^17.2.1\"\n  },\n  \"devDependencies\": {\n    \"@types/jest\": \"^27.0.2\",\n    \"codacy-coverage\": \"^3.4.0\",\n    \"esbuild\": \"^0.13.4\",\n    \"eslint\": \"^7.32.0\",\n    \"eslint-config-airbnb\": \"^18.2.1\",\n    \"eslint-config-prettier\": \"^8.3.0\",\n    \"eslint-plugin-import\": \"^2.24.2\",\n    \"eslint-plugin-jsx-a11y\": \"^6.4.1\",\n    \"eslint-plugin-react\": \"^7.26.1\",\n    \"gramma\": \"^1.6.0\",\n    \"husky\": \"^7.0.0\",\n    \"jest\": \"^27.2.4\",\n    \"pkg\": \"^5.3.3\",\n    \"prettier\": \"^2.4.1\",\n    \"shelljs\": \"^0.8.4\",\n    \"typescript\": \"^4.4.3\"\n  },\n  \"jest\": {\n    \"verbose\": true,\n    \"testMatch\": [\n      \"**/?(*.)(spec|test).?(m)js\"\n    ]\n  },\n  \"engines\": {\n    \"node\": \">=12.0.0\"\n  }\n}\n"
  },
  {
    "path": "scripts/checkLanguagesSupport.js",
    "content": "const fs = require(\"fs\")\nconst querystring = require(\"querystring\")\nconst fetch = require(\"node-fetch\")\n\nconst LOCAL_API_URL = \"http://localhost:8082/v2/languages\"\n\nconst checkSupport = async (language, api) => {\n  const postData = querystring.stringify({\n    api_key: \"\",\n    language,\n    text: \"abc\",\n    // ...disabledRulesEntry,\n  })\n\n  const response = await fetch(api, {\n    credentials: \"include\",\n    headers: {\n      \"Content-Type\": \"application/x-www-form-urlencoded\",\n    },\n    body: postData,\n    method: \"POST\",\n  })\n\n  console.log(`Checking ${language} at ${api}`)\n\n  try {\n    await response.json()\n  } catch (e) {\n    return false\n  }\n  return true\n}\n\nconst LANGUAGETOOL_ORG_LIMIT = 20 // req/min\nconst interval = (60 * 1000) / LANGUAGETOOL_ORG_LIMIT\nconst delay = () => new Promise((resolve) => setTimeout(resolve, interval))\n\nconst main = async () => {\n  const res = await fetch(LOCAL_API_URL)\n  const languages = await res.json()\n\n  for (const language of languages) {\n    language.grammarbotIo = await checkSupport(\n      language.longCode,\n      \"http://api.grammarbot.io/v2/check\",\n    )\n    language.languagetoolOrg = await checkSupport(\n      language.longCode,\n      \"https://api.languagetool.org/v2/check\",\n    )\n\n    await delay()\n  }\n\n  fs.writeFileSync(\"data/languages.json\", JSON.stringify(languages, null, 2))\n\n  const entries = languages\n    .map(\n      ({ name, longCode, grammarbotIo, languagetoolOrg }) =>\n        `\n      <tr>\n        <td><tt style=\"white-space: pre;\">${longCode}</tt></td>\n        <td>${name}</td>\n        <td>${languagetoolOrg ? \"✔\" : \"-\"}</td>\n        <td>${grammarbotIo ? \"✔\" : \"-\"}</td>\n        <td>✔</td>\n      </tr>\n        `,\n    )\n    .join(\"\")\n\n  const docs = `<!--LANG-->\\n${entries}\\n      <!--/LANG-->`.replace(\n    /^\\s*[\\r\\n]/gm,\n    \"\",\n  )\n\n  const readme = fs\n    .readFileSync(\"README.md\")\n    .toString()\n    .replace(/<!--LANG-->(.|\\n)+<!--\\/LANG-->/, docs)\n\n  fs.writeFileSync(\"README.md\", readme)\n  console.log(\"README entries updated!\")\n}\n\nmain()\n"
  },
  {
    "path": "scripts/zipBinaries.js",
    "content": "const fs = require(\"fs\")\nconst { execSync } = require(\"child_process\")\nconst { version } = require(\"../package.json\")\n\nconst cmd = (name) =>\n  `zip -9 -j bin/gramma-${name}-v${version}.zip bin/${name}/gramma${\n    name.includes(\"windows\") ? \".exe\" : \"\"\n  }`\n\nconst main = () => {\n  const folders = fs.readdirSync(\"bin\").filter((name) => !name.includes(\".zip\"))\n\n  folders.forEach((folder) => {\n    console.log(`Creating zip file for ${folder}...`)\n    execSync(cmd(folder))\n    console.log(`Zip file for ${folder} created!`)\n  })\n\n  const versionRegex = /v\\d\\.\\d\\.\\d/g\n\n  const readme = fs\n    .readFileSync(\"README.md\")\n    .toString()\n    .replace(versionRegex, `v${version}`)\n\n  fs.writeFileSync(\"README.md\", readme)\n  console.log(\"README links updated!\")\n\n  const website = fs\n    .readFileSync(\"_layouts/default.html\")\n    .toString()\n    .replace(versionRegex, `v${version}`)\n\n  fs.writeFileSync(\"_layouts/default.html\", website)\n  console.log(\"Website links updated!\")\n}\n\nmain()\n"
  },
  {
    "path": "src/actions/checkInteractively.js",
    "content": "const kleur = require(\"kleur\")\nconst checkWithFallback = require(\"../requests/checkWithFallback\")\nconst Mistake = require(\"../components/Mistake\")\nconst handleMistake = require(\"../prompts/handleMistake\")\nconst replaceAll = require(\"../text-manipulation/replaceAll\")\nconst equal = require(\"../utils/equal\")\nconst configure = require(\"./configure\")\nconst { displayUpdates } = require(\"../requests/updates\")\n\nconst checkInteractively = async (text, cfg) => {\n  if (!text || text.trim().length === 0) {\n    console.log(kleur.yellow(\"Nothing to check!\"))\n    return { changed: false }\n  }\n\n  const result = await checkWithFallback(text, cfg)\n\n  if (result.matches.length === 0) {\n    console.log(kleur.green(\"No mistakes found!\"))\n    await displayUpdates(cfg.paths.globalConfigDir)\n    return { changed: false, text }\n  }\n  console.log(\n    `Found ${result.matches.length} potential mistake${\n      result.matches.length === 1 ? \"\" : \"s\"\n    }`,\n  )\n\n  let { matches } = result\n  const total = matches.length\n  const transformations = []\n\n  while (matches.length > 0) {\n    console.clear()\n    console.log(`Language: ${result.language.name}`)\n    console.log(\n      `Resolved: ${total - matches.length} | Pending: ${matches.length}`,\n    )\n\n    const currentMatch = matches.shift()\n    console.log(Mistake(currentMatch))\n\n    // eslint-disable-next-line no-await-in-loop\n    const { option, replacement } = await handleMistake(\n      currentMatch.replacements,\n      currentMatch.rule.issueType,\n    )\n\n    if (option === \"l\") {\n      configure(\"dictionary\", currentMatch.word, cfg, false)\n    } else if (option === \"g\") {\n      configure(\"dictionary\", currentMatch.word, cfg, true)\n    }\n\n    if ([\"i\", \"l\", \"g\"].includes(option)) {\n      matches = matches.filter((match) => {\n        return !equal(\n          [\n            match.message,\n            match.shortMessage,\n            match.replacements,\n            match.type,\n            match.rule,\n            match.word,\n          ],\n          [\n            currentMatch.message,\n            currentMatch.shortMessage,\n            currentMatch.replacements,\n            currentMatch.type,\n            currentMatch.rule,\n            currentMatch.word,\n          ],\n        )\n      })\n    } else if (option === \"n\") {\n      matches.push(currentMatch)\n    } else if (option === \"0\") {\n      transformations.push({\n        change: replacement,\n        offset: currentMatch.offset,\n        length: currentMatch.length,\n      })\n    } else {\n      try {\n        transformations.push({\n          change: currentMatch.replacements[Number(option) - 1].value,\n          offset: currentMatch.offset,\n          length: currentMatch.length,\n        })\n      } catch (e) {\n        // It prevents from displaying error when users aborts with Ctrl-c\n        if (e.message === \"Cannot read property 'value' of undefined\") {\n          console.clear()\n          process.exit(0)\n        }\n\n        console.error(e)\n      }\n    }\n  }\n\n  return { changed: true, text: replaceAll(text, transformations) }\n}\n\nmodule.exports = checkInteractively\n"
  },
  {
    "path": "src/actions/checkNonInteractively.js",
    "content": "const kleur = require(\"kleur\")\nconst checkWithFallback = require(\"../requests/checkWithFallback\")\nconst Mistake = require(\"../components/Mistake\")\nconst { displayUpdates } = require(\"../requests/updates\")\n\nconst print = (result, styles) => {\n  if (result.matches.length === 0) {\n    console.log(kleur.green(\"No mistakes found!\"))\n  } else {\n    console.log(\n      `Found ${result.matches.length} potential mistake${\n        result.matches.length === 1 ? \"\" : \"s\"\n      }`,\n    )\n    console.log()\n    console.log(\n      result.matches.map((match) => Mistake(match, styles)).join(\"\\n\"),\n    )\n  }\n}\n\nconst checkNonInteractively = async (text, cfg, styles = true) => {\n  if (!text || text.trim().length === 0) {\n    console.log(kleur.yellow(\"Nothing to check!\"))\n    return 0\n  }\n\n  const result = await checkWithFallback(text, cfg)\n  console.log(`Language: ${result.language.name}`)\n\n  print(result, styles)\n\n  await displayUpdates(cfg.paths.globalConfigDir)\n\n  return result.matches.length === 0 ? 0 : 1\n}\n\nmodule.exports = checkNonInteractively\n"
  },
  {
    "path": "src/actions/configure.js",
    "content": "const fs = require(\"fs\")\nconst kleur = require(\"kleur\")\nconst { isRule, ruleOptions } = require(\"../validators/rules\")\nconst { isLanguage, languageOptions } = require(\"../validators/languages\")\n\nconst availableOptions = [\n  \"api_key\",\n  \"api_url\",\n  \"dictionary\",\n  \"server_once\",\n  \"language\",\n  \"enable\",\n  \"disable\",\n]\n\nconst addToDictionary = (dictionary, word) => {\n  const dict = Array.isArray(dictionary) ? dictionary : []\n\n  if (dict.includes(word)) {\n    return dict\n  }\n\n  return [...dict, word].sort()\n}\n\nconst changeRule = (rules, ruleName, isEnabled) => {\n  return { ...rules, [ruleName]: isEnabled }\n}\n\nconst prepareEntry = (key, value, cfg) => {\n  if (key === \"dictionary\") {\n    return { dictionary: addToDictionary(cfg.dictionary, value) }\n  }\n\n  if (key === \"enable\" || key === \"disable\") {\n    if (!isRule(value)) {\n      console.log(kleur.red(\"There is no such rule\"))\n      console.log(`Available options: ${ruleOptions.join(\", \")}`)\n      process.exit(1)\n    }\n\n    return { rules: changeRule(cfg.rules, value, key === \"enable\") }\n  }\n\n  if (key === \"language\" && !isLanguage(value)) {\n    console.log(kleur.red(\"There is no such language option\"))\n    console.log(`Available options: ${languageOptions.join(\", \")}`)\n    process.exit(1)\n  }\n\n  return { [key]: value }\n}\n\nconst configure = (key, value, cfg, isGlobal = false, internal = false) => {\n  if (!availableOptions.includes(key) && !internal) {\n    console.log(kleur.red(`There is no '${key}' option!`))\n    console.log(\"Available options:\")\n    console.log(availableOptions.join(\"\\n\"))\n    process.exit(1)\n  }\n\n  if (key === \"server_once\" && !isGlobal) {\n    console.log(\n      kleur.red(\"This setting can be used only with -g (--global) flag\"),\n    )\n    process.exit(1)\n  }\n\n  const currentConfig = isGlobal ? cfg.global : cfg.local\n\n  const configFilePath = isGlobal\n    ? cfg.paths.globalConfigFile\n    : cfg.paths.localConfigFile\n\n  const entry = prepareEntry(key, value, currentConfig)\n\n  const updatedConfig = { ...currentConfig, ...entry }\n\n  if (isGlobal) {\n    // eslint-disable-next-line no-param-reassign\n    cfg.global = updatedConfig\n  } else {\n    // eslint-disable-next-line no-param-reassign\n    cfg.local = updatedConfig\n  }\n\n  fs.writeFileSync(configFilePath, JSON.stringify(updatedConfig, null, 2))\n}\n\nmodule.exports = configure\n"
  },
  {
    "path": "src/actions/save.js",
    "content": "const path = require(\"path\")\nconst fs = require(\"fs\")\nconst kleur = require(\"kleur\")\nconst { homedir } = require(\"os\")\nconst handleSave = require(\"../prompts/handleSave\")\n\nconst save = async (text, mode, filePath = null) => {\n  const originalFile = filePath ? path.basename(filePath) : null\n\n  console.clear()\n  console.log(\"All mistakes fixed!\")\n  const { saveOption, fileName } = await handleSave(mode, originalFile)\n\n  if (saveOption === \"replace\") {\n    fs.writeFileSync(filePath, text)\n    console.clear()\n    console.log(kleur.green(\"Saved!\"))\n  } else if (saveOption === \"save-as\") {\n    const resolvedFileName = fileName.replace(\"~\", homedir())\n    const newPath = path.resolve(process.cwd(), resolvedFileName)\n\n    fs.writeFileSync(newPath, text)\n\n    console.clear()\n    console.log(kleur.green(`Saved as ${newPath}`))\n  } else {\n    console.clear()\n    console.log(\n      `---------------------------------\\n\\n${text}\\n\\n---------------------------------\\n${kleur.green(\n        \"Done!\",\n      )}`,\n    )\n  }\n}\n\nmodule.exports = save\n"
  },
  {
    "path": "src/actions/saveNow.js",
    "content": "const fs = require(\"fs\")\n\nconst saveNow = async (text, filePath) => {\n  fs.writeFileSync(filePath, text)\n  console.clear()\n}\n\nmodule.exports = saveNow\n"
  },
  {
    "path": "src/boot/load.js",
    "content": "const prepareConfig = require(\"./prepareConfig\")\n\nconst load = (action) => (argv) => {\n  if (argv.file && argv.file.endsWith(\".md\")) {\n    argv.markdown = true // eslint-disable-line\n  }\n\n  const cfg = prepareConfig(argv)\n  action(argv, cfg)\n}\n\nmodule.exports = load\n"
  },
  {
    "path": "src/boot/prepareConfig.js",
    "content": "const fs = require(\"fs\")\nconst path = require(\"path\")\nconst { platform, homedir } = require(\"os\")\nconst findUpSync = require(\"../utils/findUpSync\").default\nconst initialConfig = require(\"../initialConfig\")\n\nconst configBasePath = {\n  linux: \".config\",\n  darwin: \"Library/Preferences\",\n  win32: \"AppData/Roaming\",\n}\n\nconst home = homedir()\nconst globalConfigDir = path.join(home, configBasePath[platform()], \"gramma\")\nconst globalConfigFile = path.join(globalConfigDir, \"gramma.json\")\nconst localConfigFile = findUpSync(\".gramma.json\")\n\nif (!fs.existsSync(globalConfigDir)) {\n  fs.mkdirSync(globalConfigDir, { recursive: true })\n}\n\nif (!fs.existsSync(globalConfigFile)) {\n  fs.writeFileSync(globalConfigFile, JSON.stringify(initialConfig, null, 2))\n}\n\nconst loadEnvironmentVariables = (configText) => {\n  const items = configText.match(/\\${[a-z0-9\\-_.]*}/gi)\n\n  if (!items) {\n    return configText\n  }\n\n  let text = configText\n\n  items.forEach((item) => {\n    const envVarName = item.slice(2, -1)\n    const envVar = process.env[envVarName]\n\n    if (envVar) {\n      text = text.replace(item, envVar)\n    }\n  })\n\n  return text\n}\n\nconst prepareFileConfig = (filePath) => {\n  if (!filePath) return null\n\n  return fs.existsSync(filePath)\n    ? JSON.parse(loadEnvironmentVariables(fs.readFileSync(filePath).toString()))\n    : null\n}\n\nconst prepareArgvConfig = ({ language, disable, enable, global, markdown }) => {\n  const disabledRules = Array.isArray(disable) ? disable : [disable]\n  const enabledRules = Array.isArray(enable) ? enable : [enable]\n  const rules = {}\n\n  disabledRules.forEach((rule) => {\n    rules[rule] = false\n  })\n\n  enabledRules.forEach((rule) => {\n    rules[rule] = true\n  })\n\n  return {\n    language,\n    rules,\n    markdown,\n    modifiers: {\n      global,\n    },\n  }\n}\n\nconst prepareConfig = (paths) => (argv) => {\n  const globalConfig = prepareFileConfig(paths.globalConfigFile)\n  const localConfig = prepareFileConfig(paths.localConfigFile)\n\n  if (localConfig && localConfig.api_url === \"localhost\") {\n    localConfig.api_url = \"inherit\"\n  }\n\n  const argvConfig = prepareArgvConfig(argv)\n\n  const fileConfig = localConfig || globalConfig || {}\n\n  // File configs replace one another,\n  // so user's and project's configs won't mix\n  const cfg = {\n    ...initialConfig,\n    ...fileConfig,\n  }\n\n  // If local config has api_url set to 'inherit'\n  // then Gramma will use global settings (if set) or initial settings.\n  // This allows to use dynamic url of the local server\n  // eslint-disable-next-line camelcase\n  const api_url =\n    cfg.api_url === \"inherit\"\n      ? (globalConfig || {}).api_url || initialConfig.api_url\n      : cfg.api_url\n\n  // Argv config alters nested values,\n  // so you can change some rules for specific checks,\n  // without erasing other rules defined in config files\n  const sessionConfig = {\n    ...cfg,\n    language:\n      argvConfig.language === \"config\" ? cfg.language : argvConfig.language,\n    rules: { ...cfg.rules, ...argvConfig.rules },\n    modifiers: argvConfig.modifiers,\n    api_url,\n    markdown: argvConfig.markdown,\n  }\n\n  return {\n    initial: initialConfig,\n    global: globalConfig || {},\n    local: localConfig || {},\n    session: sessionConfig,\n    paths,\n  }\n}\n\nmodule.exports = prepareConfig({\n  globalConfigDir,\n  globalConfigFile,\n  localConfigFile,\n  home,\n  serverDownload: \"https://languagetool.org/download/LanguageTool-stable.zip\",\n})\n"
  },
  {
    "path": "src/cli.js",
    "content": "#!/usr/bin/env node\nrequire(\"dotenv\").config()\nrequire(\"isomorphic-fetch\")\n\nconst yargs = require(\"yargs\")\nconst { version } = require(\"../package.json\")\nconst load = require(\"./boot/load\")\n\nconst check = require(\"./commands/check\")\nconst listen = require(\"./commands/listen\")\nconst commit = require(\"./commands/commit\")\nconst init = require(\"./commands/init\")\nconst config = require(\"./commands/config\")\nconst paths = require(\"./commands/paths\")\nconst server = require(\"./commands/server\")\nconst { hook } = require(\"./commands/hook\")\n\nconst { languageOptions } = require(\"./validators/languages\")\nconst { ruleOptions } = require(\"./validators/rules\")\n\n// eslint-disable-next-line no-unused-expressions\nyargs\n  .command(\n    \"check <file>\",\n    \"check file for writing mistakes\",\n    (yargsCtx) => {\n      yargsCtx.positional(\"text\", {\n        describe: \"file to check\",\n      })\n    },\n    load(check),\n  )\n  .command(\n    \"listen <text>\",\n    \"check text for writing mistakes\",\n    (yargsCtx) => {\n      yargsCtx.positional(\"text\", {\n        describe: \"text to check\",\n      })\n    },\n    load(listen),\n  )\n  .command(\n    \"commit <text>\",\n    \"git commit -m with grammar check\",\n    (yargsCtx) => {\n      yargsCtx.positional(\"text\", {\n        describe: \"commit message to check\",\n      })\n    },\n    load(commit),\n  )\n  .command(\n    \"hook\",\n    \"toggles Git hook\",\n    (yargsCtx) => {\n      yargsCtx.positional(\"text\", {\n        describe: \"commit message file\",\n      })\n    },\n    load(hook),\n  )\n  .command(\n    \"init\",\n    \"create local config with default settings\",\n    () => {},\n    load(init),\n  )\n  .command(\n    \"config <key> <value>\",\n    \"set config entry\",\n    (yargsCtx) => {\n      yargsCtx\n        .positional(\"key\", {\n          describe: \"name of the config entry\",\n        })\n        .positional(\"value\", {\n          describe: \"value of the config entry\",\n        })\n    },\n    load(config),\n  )\n  .command(\"paths\", \"show paths used by Gramma\", () => {}, load(paths))\n  .command(\n    \"server <action>\",\n    \"manage local API server\",\n    (yargsCtx) => {\n      yargsCtx.positional(\"action\", {\n        describe: \"action to take (install / start / stop / pid / gui)\",\n      })\n    },\n    load(server),\n  )\n  .alias(\"help\", \"h\")\n  .version(`v${version}`)\n  .alias(\"version\", \"v\")\n  .hide(\"paths\")\n  .option(\"print\", {\n    alias: \"p\",\n    type: \"boolean\",\n    default: false,\n    describe: \"Print mistakes non-interactively\",\n  })\n  .option(\"no-colors\", {\n    alias: \"n\",\n    type: \"boolean\",\n    default: false,\n    describe: \"Disable output colors\",\n  })\n  .option(\"language\", {\n    alias: \"l\",\n    type: \"string\",\n    default: \"config\",\n    describe: \"Set the language of the text\",\n    choices: languageOptions,\n  })\n  .option(\"disable\", {\n    alias: \"d\",\n    type: \"string\",\n    describe: \"Disable specific rule\",\n    default: [],\n    choices: ruleOptions,\n  })\n  .option(\"enable\", {\n    alias: \"e\",\n    type: \"string\",\n    describe: \"Enable specific rule\",\n    default: [],\n    choices: ruleOptions,\n  })\n  .option(\"all\", {\n    alias: \"a\",\n    type: \"boolean\",\n    default: false,\n    describe: \"Add -a flag to git commit command\",\n  })\n  .option(\"global\", {\n    alias: \"g\",\n    type: \"boolean\",\n    default: false,\n    describe: \"Use global configuration file with 'config' command\",\n  })\n  .option(\"markdown\", {\n    alias: \"m\",\n    type: \"boolean\",\n    default: false,\n    describe: \"Treat the text as markdown\",\n  })\n  .option(\"port\", {\n    type: \"number\",\n    describe: \"Set the port number of local API server\",\n  })\n  .demandCommand().argv\n"
  },
  {
    "path": "src/cli.test.js",
    "content": "const shell = require(\"shelljs\")\nconst fs = require(\"fs\")\n\nconst prepareData = (text) => {\n  if (!fs.existsSync(\"test-temp\")) {\n    fs.mkdirSync(\"test-temp\")\n  }\n\n  fs.writeFileSync(\"test-temp/example.txt\", text)\n}\n\nconst removeData = () => {\n  shell.rm(\"-rf\", \"test-temp\")\n}\n\ndescribe(\"'listen' command\", () => {\n  it(\"prints potential mistakes with '--print' option\", () => {\n    const result = shell.exec(\n      \"node src/cli.js listen --print 'There is a mistkae'\",\n    )\n\n    expect(result.code).toEqual(1)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"Context\")).not.toEqual(\"\")\n    expect(result.grep(\"Suggested fix\")).not.toEqual(\"\")\n  })\n\n  it(\"prints potential mistakes with '-p' option\", () => {\n    const result = shell.exec(\"node src/cli.js listen -p 'There is a mistkae'\")\n\n    expect(result.code).toEqual(1)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"Context\")).not.toEqual(\"\")\n    expect(result.grep(\"Suggested fix\")).not.toEqual(\"\")\n  })\n\n  it(\"prints no mistakes with '--print' option\", () => {\n    const result = shell.exec(\n      \"node src/cli.js listen --print 'There are no mistakes'\",\n    )\n\n    expect(result.code).toEqual(0)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"No mistakes found!\")).not.toEqual(\"\")\n  })\n\n  it(\"prints no mistakes with '-p' option\", () => {\n    const result = shell.exec(\n      \"node src/cli.js listen -p 'There are no mistakes'\",\n    )\n\n    expect(result.code).toEqual(0)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"No mistakes found!\")).not.toEqual(\"\")\n  })\n})\n\ndescribe(\"'check' command\", () => {\n  it(\"prints potential mistakes with '--print' option\", () => {\n    prepareData(\"There is a mistkae\")\n    const result = shell.exec(\n      \"node src/cli.js check --print test-temp/example.txt\",\n    )\n\n    expect(result.code).toEqual(1)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"Context\")).not.toEqual(\"\")\n    expect(result.grep(\"Suggested fix\")).not.toEqual(\"\")\n    removeData()\n  })\n\n  it(\"prints potential mistakes with '-p' option\", () => {\n    prepareData(\"There is a mistkae\")\n    const result = shell.exec(\"node src/cli.js check -p test-temp/example.txt\")\n\n    expect(result.code).toEqual(1)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"Context\")).not.toEqual(\"\")\n    expect(result.grep(\"Suggested fix\")).not.toEqual(\"\")\n    removeData()\n  })\n\n  it(\"prints no mistakes with '--print' option\", () => {\n    prepareData(\"There are no mistakes\")\n    const result = shell.exec(\n      \"node src/cli.js check --print test-temp/example.txt\",\n    )\n\n    expect(result.code).toEqual(0)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"No mistakes found!\")).not.toEqual(\"\")\n    removeData()\n  })\n\n  it(\"prints no mistakes with '-p' option\", () => {\n    prepareData(\"There are no mistakes\")\n    const result = shell.exec(\"node src/cli.js check -p test-temp/example.txt\")\n\n    expect(result.code).toEqual(0)\n    expect(result.stderr).toEqual(\"\")\n    expect(result.grep(\"No mistakes found!\")).not.toEqual(\"\")\n    removeData()\n  })\n})\n"
  },
  {
    "path": "src/commands/check.js",
    "content": "const intercept = require(\"intercept-stdout\")\nconst kleur = require(\"kleur\")\nconst fs = require(\"fs\")\nconst checkNonInteractively = require(\"../actions/checkNonInteractively\")\nconst checkInteractively = require(\"../actions/checkInteractively\")\nconst save = require(\"../actions/save\")\nconst stripStyles = require(\"../utils/stripStyles\")\n\nconst check = async (argv, cfg) => {\n  if (!argv.file) {\n    console.log(kleur.red(\"Please provide a file path.\"))\n    process.exit(1)\n  }\n\n  if (!fs.existsSync(argv.file) || argv.file === \".\" || argv.file === \"..\") {\n    console.log(kleur.red(\"There is no such file!\"))\n    process.exit(1)\n  }\n\n  const initialText = fs.readFileSync(argv.file).toString()\n\n  if (argv.print) {\n    const noColors = argv[\"no-colors\"]\n\n    if (noColors) {\n      intercept(stripStyles)\n    }\n\n    const status = await checkNonInteractively(initialText, cfg, !noColors)\n    process.exit(status)\n  } else {\n    const { changed, text } = await checkInteractively(initialText, cfg)\n    if (changed) {\n      await save(text, \"FILE\", argv.file)\n    }\n    process.exit()\n  }\n}\n\nmodule.exports = check\n"
  },
  {
    "path": "src/commands/commit.js",
    "content": "const fs = require(\"fs\")\nconst { execSync } = require(\"child_process\")\nconst path = require(\"path\")\nconst checkInteractively = require(\"../actions/checkInteractively\")\n\nconst commit = async (argv, cfg) => {\n  const { text } = await checkInteractively(argv.text, cfg)\n\n  try {\n    if (fs.existsSync(path.join(process.cwd(), \".gramma.json\"))) {\n      execSync(`git add .gramma.json`)\n    }\n\n    const output = argv.all\n      ? execSync(`git commit -am \"${text}\"`)\n      : execSync(`git commit -m \"${text}\"`)\n\n    process.stdout.write(output)\n  } catch (error) {\n    process.stderr.write(error.stdout)\n  }\n  process.exit()\n}\n\nmodule.exports = commit\n"
  },
  {
    "path": "src/commands/config.js",
    "content": "const kleur = require(\"kleur\")\nconst configure = require(\"../actions/configure\")\nconst confirmConfig = require(\"../prompts/confirmConfig\")\n\nconst config = async (argv, cfg) => {\n  if (!argv.global && !cfg.paths.localConfigFile) {\n    const { useGlobal } = await confirmConfig()\n\n    if (useGlobal) {\n      argv.global = true // eslint-disable-line\n    } else {\n      console.log(kleur.yellow(\"Aborting\"))\n      process.exit()\n    }\n  }\n\n  configure(argv.key, argv.value, cfg, argv.global)\n  console.log(kleur.green(\"Done!\"))\n}\n\nmodule.exports = config\n"
  },
  {
    "path": "src/commands/debug.js",
    "content": "const debug = async (argv, cfg) => {\n  console.log(\"config:\")\n  console.log(cfg)\n  console.log(\"------------------------------------\")\n  console.log(\"argv:\")\n  console.log(argv)\n  console.log(\"------------------------------------\")\n}\n\nmodule.exports = debug\n"
  },
  {
    "path": "src/commands/hook.js",
    "content": "const kleur = require(\"kleur\")\nconst fs = require(\"fs\")\nconst path = require(\"path\")\nconst os = require(\"os\")\nconst { execSync } = require(\"child_process\")\nconst checkInteractively = require(\"../actions/checkInteractively\")\nconst saveNow = require(\"../actions/saveNow\")\nconst appLocation = require(\"../utils/appLocation\")\n\nconst sys = os.platform()\n\nconst REDIRECT_STDIN = \"\\n\\nexec < /dev/tty\"\n\nconst getHookCode = (command, stdin = true) => {\n  const stdinCode = stdin ? REDIRECT_STDIN : \"\"\n\n  return {\n    linux: {\n      full: `#!/bin/sh${stdinCode}\\n\\n${command}\\n`,\n      partial: `${stdinCode}\\n\\n${command}\\n`,\n    },\n    darwin: {\n      full: `#!/bin/sh${stdinCode}\\n\\n${command}\\n`,\n      partial: `${stdinCode}\\n\\n${command}\\n`,\n    },\n    win32: {\n      full: `#!/bin/sh${stdinCode}\\n\\n${command}\\n`.replace(/\\\\/g, \"/\"),\n      partial: `${stdinCode}\\n\\n${command}\\n`.replace(/\\\\/g, \"/\"),\n    },\n  }\n}\n\nconst gitRoot = path.join(process.cwd(), \".git\")\n\nconst checkGit = () => {\n  return fs.existsSync(gitRoot)\n}\n\nconst createEmptyFile = (file) => {\n  if (!fs.existsSync(file)) {\n    fs.closeSync(fs.openSync(file, \"w\"))\n  }\n}\n\nconst addHookCode = (hookFile, hookCode, onlyCreate, name) => {\n  if (fs.existsSync(hookFile)) {\n    const content = fs.readFileSync(hookFile).toString()\n    const alreadyExists = content.includes(hookCode[sys].partial)\n\n    if (alreadyExists && !onlyCreate) {\n      const newContent = content.replace(hookCode[sys].partial, \"\")\n      fs.writeFileSync(hookFile, newContent)\n      console.log(kleur.green(`Hook (${name}) removed!`))\n    } else if (alreadyExists) {\n      console.log(kleur.yellow(`Hook (${name}) already exists!`))\n    } else {\n      fs.appendFileSync(hookFile, hookCode[sys].partial)\n      console.log(kleur.green(`Hook (${name}) created!`))\n    }\n  } else {\n    fs.writeFileSync(hookFile, hookCode[sys].full)\n    fs.chmodSync(hookFile, \"755\")\n    console.log(kleur.green(`Hook (${name}) created!`))\n  }\n}\n\nconst addHooksCode = (onlyCreate = false) => {\n  const hasGit = checkGit()\n\n  if (!hasGit) {\n    console.log(kleur.red(\"No .git in this directory\"))\n    process.exit(1)\n  }\n\n  const hooksConfig = fs\n    .readFileSync(path.join(gitRoot, \"config\"))\n    .toString()\n    .match(/hooksPath *=.*/gi)\n\n  const hooksFolder = hooksConfig && hooksConfig[0].split(\"=\")[1].trim()\n\n  const hookFileCommitMsg = hooksFolder\n    ? path.resolve(process.cwd(), hooksFolder, \"commit-msg\")\n    : path.resolve(process.cwd(), \".git\", \"hooks\", \"commit-msg\")\n\n  const hookFilePostCommit = hooksFolder\n    ? path.resolve(process.cwd(), hooksFolder, \"post-commit\")\n    : path.resolve(process.cwd(), \".git\", \"hooks\", \"post-commit\")\n\n  const commandCommitMsg = fs.existsSync(\"node_modules\")\n    ? \"npx gramma hook $1\"\n    : `${appLocation} hook $1`\n\n  const commandPostCommit = fs.existsSync(\"node_modules\")\n    ? \"npx gramma hook cleanup\"\n    : `${appLocation} hook cleanup`\n\n  const hookCodeCommitMsg = getHookCode(commandCommitMsg)\n  const hookCodePostCommit = getHookCode(commandPostCommit, false)\n\n  addHookCode(hookFileCommitMsg, hookCodeCommitMsg, onlyCreate, \"commit-msg\")\n  addHookCode(hookFilePostCommit, hookCodePostCommit, onlyCreate, \"post-commit\")\n}\n\nconst hook = async (argv, cfg) => {\n  const arg =\n    process.argv[process.argv.length - 1] !== \"hook\"\n      ? process.argv[process.argv.length - 1]\n      : null\n\n  // No arg - execute the default command\n  if (!arg) {\n    addHooksCode()\n    process.exit()\n  }\n\n  // Temporary file to coordinate git hooks\n  // See: https://stackoverflow.com/a/12802592/4713502\n  const tempFile = path.join(cfg.paths.globalConfigDir, \".commit\")\n\n  // Code executed by `post-commit` hook\n  if (arg === \"cleanup\") {\n    if (cfg.paths.localConfigFile && fs.existsSync(tempFile)) {\n      fs.unlinkSync(tempFile)\n\n      try {\n        execSync(`git add ${cfg.paths.localConfigFile}`)\n        execSync(`git commit --amend --no-edit --no-verify`)\n      } catch (e) {} // eslint-disable-line\n    }\n\n    process.exit()\n  }\n\n  // Code executed by `commit-msg` hook\n  createEmptyFile(tempFile)\n\n  const file = arg\n\n  const commitText = fs\n    .readFileSync(file)\n    .toString()\n    .replace(/# ------------------------ >8[\\S\\s]*/m, \"\") // Remove diff part on --verbose\n    .replace(/#.*/g, \"\") // Remove other comments\n\n  const { changed, text } = await checkInteractively(commitText, cfg)\n\n  if (changed) {\n    await saveNow(text, file)\n  }\n\n  process.exit()\n}\n\nexports.checkGit = checkGit\nexports.addHookCode = addHooksCode\nexports.hook = hook\n"
  },
  {
    "path": "src/commands/init.js",
    "content": "const kleur = require(\"kleur\")\nconst fs = require(\"fs\")\nconst path = require(\"path\")\nconst initialConfig = require(\"../initialConfig\")\nconst confirmInit = require(\"../prompts/confirmInit\")\nconst { addHookCode, checkGit } = require(\"./hook\")\n\nconst localConfigFile = path.join(process.cwd(), \".gramma.json\")\n\nconst init = async (argv, cfg) => {\n  if (!fs.existsSync(cfg.paths.localConfigFile)) {\n    const hasGit = checkGit()\n    const { hook, api } = await confirmInit(hasGit)\n\n    if (!api) {\n      console.log(kleur.yellow(\"Aborting!\"))\n      process.exit(1)\n    }\n\n    const content = JSON.stringify({ ...initialConfig, api_url: api }, null, 2)\n\n    fs.writeFileSync(localConfigFile, content)\n    console.log(kleur.green(\"Gramma config created!\"))\n\n    if (hook) {\n      addHookCode(true)\n    }\n  } else {\n    console.log(kleur.red(\"Gramma config already exists for this project!\"))\n  }\n}\n\nmodule.exports = init\n"
  },
  {
    "path": "src/commands/listen.js",
    "content": "const intercept = require(\"intercept-stdout\")\nconst checkNonInteractively = require(\"../actions/checkNonInteractively\")\nconst checkInteractively = require(\"../actions/checkInteractively\")\nconst save = require(\"../actions/save\")\nconst stripStyles = require(\"../utils/stripStyles\")\n\nconst listen = async (argv, cfg) => {\n  if (argv.print) {\n    const noColors = argv[\"no-colors\"]\n\n    if (noColors) {\n      intercept(stripStyles)\n    }\n\n    const status = await checkNonInteractively(argv.text, cfg, !noColors)\n    process.exit(status)\n  } else {\n    const { changed, text } = await checkInteractively(argv.text, cfg)\n    if (changed) {\n      await save(text, \"TEXT\")\n    }\n    process.exit()\n  }\n}\n\nmodule.exports = listen\n"
  },
  {
    "path": "src/commands/paths.js",
    "content": "const appLocation = require(\"../utils/appLocation\")\n\nconst paths = (argv, cfg) => {\n  console.log(`Global config: ${cfg.paths.globalConfigFile}`)\n  console.log(`App location:  ${appLocation}`)\n  console.log(`Local server:  ${cfg.global.server_path || \"not installed\"}`)\n}\n\nmodule.exports = paths\n"
  },
  {
    "path": "src/commands/server.js",
    "content": "const kleur = require(\"kleur\")\nconst installServer = require(\"../server/installServer\")\nconst startServer = require(\"../server/startServer\")\nconst stopServer = require(\"../server/stopServer\")\nconst getServerPID = require(\"../server/getServerPID\")\nconst getServerInfo = require(\"../server/getServerInfo\")\nconst showServerGUI = require(\"../server/showServerGUI\")\n\nconst server = async (argv, cfg) => {\n  const availableOptions = [\"install\", \"start\", \"stop\", \"pid\", \"info\", \"gui\"]\n\n  if (!availableOptions.includes(argv.action)) {\n    console.log(kleur.red(\"There is no such command!\"))\n    console.log(\n      `Available options for gramma server: ${availableOptions.join(\" | \")}`,\n    )\n    process.exit(1)\n  }\n\n  if (argv.action === \"install\") {\n    await installServer(cfg)\n    process.exit()\n  }\n\n  if (argv.action === \"start\") {\n    await startServer(cfg, {\n      port: argv.port,\n      viaCommand: true,\n    })\n    process.exit()\n  }\n\n  if (argv.action === \"stop\") {\n    await stopServer(cfg)\n    process.exit()\n  }\n\n  if (argv.action === \"pid\") {\n    getServerPID(cfg)\n    process.exit()\n  }\n\n  if (argv.action === \"info\") {\n    getServerInfo(cfg)\n    process.exit()\n  }\n\n  if (argv.action === \"gui\") {\n    showServerGUI(cfg)\n    process.exit()\n  }\n}\n\nmodule.exports = server\n"
  },
  {
    "path": "src/components/FixMenu.js",
    "content": "const kleur = require(\"kleur\")\n\nconst FixOptions = (fixes) => {\n  if (fixes.length === 0) {\n    return \"\"\n  }\n  if (fixes.length === 1) {\n    return kleur.bold().green(\"1\") + kleur.reset(`: fix\\n`)\n  }\n  return kleur.bold().green(`1-${fixes.length}`) + kleur.reset(`: choose fix\\n`)\n}\n\nconst FixMenu = (fixes, issue) => {\n  const defaultFix = kleur.bold().green(fixes.length > 0 ? 1 : 0)\n\n  // prettier-ignore\n  const dictionaryOptions =\n    issue === \"misspelling\"\n      ? `${kleur.bold().green(\"l\")\n        }${kleur.reset(`: add to local dictionary\\n`)\n        }${kleur.bold().green(\"g\")\n        }${kleur.reset(`: add to global dictionary\\n`)}`\n      : \"\"\n\n  // prettier-ignore\n  return (\n    `What do you want to do?\\n${ \n    kleur.bold().green(\"Enter\") \n    }${kleur.reset(`: default (${defaultFix})\\n`) \n    }${FixOptions(fixes) \n    }${kleur.bold().green(\"0\") \n    }${kleur.reset(`: custom fix\\n`) \n    }${kleur.bold().green(\"i\") \n    }${kleur.reset(`: ignore\\n`) \n    }${dictionaryOptions\n    }${kleur.bold().green(\"n\") \n    }${kleur.reset(`: next\\n`)}`\n  )\n}\n\nmodule.exports = FixMenu\n"
  },
  {
    "path": "src/components/FixMenu.test.js",
    "content": "const stripStyles = require(\"../utils/stripStyles\")\nconst FixMenu = require(\"./FixMenu\")\n\ndescribe(\"FixMenu component\", () => {\n  it(\"renders menu with multiple fix propositions for mistake\", () => {\n    const expected =\n      \"What do you want to do?\\n\" +\n      \"Enter: default (1)\\n\" +\n      \"1-3: choose fix\\n\" +\n      \"0: custom fix\\n\" +\n      \"i: ignore\\n\" +\n      \"n: next\\n\"\n\n    const result = FixMenu([{}, {}, {}])\n\n    const rawResult = stripStyles(result)\n\n    expect(rawResult).toEqual(expected)\n  })\n\n  it(\"renders menu with single fix proposition for mistake\", () => {\n    const expected =\n      \"What do you want to do?\\n\" +\n      \"Enter: default (1)\\n\" +\n      \"1: fix\\n\" +\n      \"0: custom fix\\n\" +\n      \"i: ignore\\n\" +\n      \"n: next\\n\"\n\n    const result = FixMenu([{}])\n\n    const rawResult = stripStyles(result)\n\n    expect(rawResult).toEqual(expected)\n  })\n\n  it(\"renders menu with no fix propositions for mistake\", () => {\n    const expected =\n      \"What do you want to do?\\n\" +\n      \"Enter: default (0)\\n\" +\n      \"0: custom fix\\n\" +\n      \"i: ignore\\n\" +\n      \"n: next\\n\"\n\n    const result = FixMenu([])\n\n    const rawResult = stripStyles(result)\n\n    expect(rawResult).toEqual(expected)\n  })\n\n  it(\"renders dictionary options on spelling mistake\", () => {\n    const expected =\n      \"What do you want to do?\\n\" +\n      \"Enter: default (0)\\n\" +\n      \"0: custom fix\\n\" +\n      \"i: ignore\\n\" +\n      \"l: add to local dictionary\\n\" +\n      \"g: add to global dictionary\\n\" +\n      \"n: next\\n\"\n\n    const result = FixMenu([], \"misspelling\")\n\n    const rawResult = stripStyles(result)\n\n    expect(rawResult).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "src/components/Mistake.js",
    "content": "const kleur = require(\"kleur\")\nconst replace = require(\"../text-manipulation/replace\")\n\nconst getMistakeColor = (type) => {\n  if (type === \"grammar\") {\n    return \"red\"\n  }\n\n  if (type === \"style\") {\n    return \"blue\"\n  }\n\n  return \"yellow\"\n}\n\nconst highlightMistake = (context, type, offset, length) => {\n  const color = getMistakeColor(type)\n  const change = (mistake) => kleur[color](mistake)\n\n  return replace(context, change, offset, length)\n}\n\nconst Mistake = (match, style = true) => {\n  const context = highlightMistake(\n    match.context.text,\n    match.rule.issueType,\n    match.context.offset,\n    match.context.length,\n  )\n\n  const replacements = match.replacements\n    .map(\n      (replacement, index) =>\n        `${kleur.bold().green(index + 1)}) ${replacement.value}`,\n    )\n    .join(\"  \")\n\n  const fixes =\n    match.replacements.length > 0\n      ? `${kleur.bold(\"Suggested fix:\")} ${replacements}\\n`\n      : \"\"\n\n  const word = style ? \"\" : `Word: ${match.word}\\n`\n\n  // prettier-ignore\n  return (\n    `---------------------------------\\n\\n${\n    kleur.dim(`${kleur.bold(\"Rule:\")} ${match.rule.category.id.toLowerCase()}\\n`)\n    }${kleur.dim(`${kleur.bold(\"Explanation:\")} ${match.message}\\n\\n`)\n    }${word\n    }${kleur.bold(\"Context:\")} ${context}\\n${\n    fixes}`\n  )\n}\n\nmodule.exports = Mistake\n"
  },
  {
    "path": "src/components/Mistake.test.js",
    "content": "const stripStyles = require(\"../utils/stripStyles\")\nconst Mistake = require(\"./Mistake\")\n\ndescribe(\"Mistake component\", () => {\n  it(\"renders info about mistake without suggestions\", () => {\n    const expected =\n      `---------------------------------\\n\\n` +\n      `Rule: typos\\n` +\n      `Explanation: Did you mean \"is\"?\\n\\n` +\n      `Context:  It are a perfect English sentence. \\n`\n\n    const result = Mistake({\n      message: 'Did you mean \"is\"?',\n      replacements: [],\n      context: {\n        text: \" It are a perfect English sentence. \",\n        offset: 4,\n        length: 3,\n      },\n      rule: {\n        category: {\n          id: \"typos\",\n        },\n      },\n    })\n\n    const rawResult = stripStyles(result)\n\n    expect(rawResult).toEqual(expected)\n  })\n\n  it(\"renders info about mistake with single suggestion\", () => {\n    const expected =\n      `---------------------------------\\n\\n` +\n      `Rule: typos\\n` +\n      `Explanation: Some message\\n\\n` +\n      `Context: Some context\\n` +\n      `Suggested fix: 1) foo\\n`\n\n    const result = Mistake({\n      message: \"Some message\",\n      replacements: [{ value: \"foo\" }],\n      context: {\n        text: \"Some context\",\n        offset: 4,\n        length: 3,\n      },\n      rule: {\n        category: {\n          id: \"typos\",\n        },\n      },\n    })\n\n    const rawResult = stripStyles(result)\n\n    expect(rawResult).toEqual(expected)\n  })\n\n  it(\"renders info about mistake with multiple suggestions\", () => {\n    const expected =\n      `---------------------------------\\n\\n` +\n      `Rule: typos\\n` +\n      `Explanation: Some message\\n\\n` +\n      `Context: Some context\\n` +\n      `Suggested fix: 1) foo  2) bar  3) baz\\n`\n\n    const result = Mistake({\n      message: \"Some message\",\n      replacements: [{ value: \"foo\" }, { value: \"bar\" }, { value: \"baz\" }],\n      context: {\n        text: \"Some context\",\n        offset: 4,\n        length: 3,\n      },\n      rule: {\n        category: {\n          id: \"typos\",\n        },\n      },\n    })\n\n    const rawResult = stripStyles(result)\n\n    expect(rawResult).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "src/context.js",
    "content": "const context = {\n  argv: null,\n}\n\nmodule.exports = context\n"
  },
  {
    "path": "src/index.d.ts",
    "content": "import check = require(\"./requests/checkViaAPI\")\nimport replaceAll = require(\"./text-manipulation/replaceAll\")\nexport { check, replaceAll }\n"
  },
  {
    "path": "src/index.js",
    "content": "require(\"isomorphic-fetch\")\n\nconst check = require(\"./requests/checkViaAPI\")\nconst replaceAll = require(\"./text-manipulation/replaceAll\")\n\nmodule.exports = {\n  check,\n  replaceAll,\n}\n"
  },
  {
    "path": "src/initialConfig.js",
    "content": "const { ruleOptions } = require(\"./validators/rules\")\n\nconst rules = {}\n\nruleOptions.forEach((rule) => {\n  rules[rule] = true\n})\n\nconst initialConfig = {\n  api_url: \"https://api.languagetool.org/v2/check\",\n  api_key: \"\",\n  dictionary: [],\n  language: \"en-US\",\n  rules,\n}\n\nmodule.exports = initialConfig\n"
  },
  {
    "path": "src/prompts/confirmConfig.js",
    "content": "const prompts = require(\"prompts\")\n\nconst confirmConfig = () => {\n  return prompts([\n    {\n      type: \"toggle\",\n      name: \"useGlobal\",\n      message:\n        \"Local config not found. Should I use the global config instead?\",\n      initial: true,\n      active: \"yes\",\n      inactive: \"no\",\n    },\n  ])\n}\n\nmodule.exports = confirmConfig\n"
  },
  {
    "path": "src/prompts/confirmInit.js",
    "content": "const prompts = require(\"prompts\")\nconst initialConfig = require(\"../initialConfig\")\n\nconst confirmInit = (hasGit) => {\n  return prompts([\n    {\n      type: \"select\",\n      name: \"api\",\n      message: \"Choose API url:\",\n      choices: [\n        { title: \"languagetool.org\", value: initialConfig.api_url },\n        {\n          title: \"Inherit from global config\",\n          value: \"inherit\",\n        },\n      ],\n      initial: 0,\n    },\n    {\n      type: hasGit ? \"toggle\" : null,\n      name: \"hook\",\n      message: \"Add Git hook?\",\n      initial: true,\n      active: \"yes\",\n      inactive: \"no\",\n    },\n  ])\n}\n\nmodule.exports = confirmInit\n"
  },
  {
    "path": "src/prompts/confirmPort.js",
    "content": "const prompts = require(\"prompts\")\n\nconst confirmPort = () => {\n  return prompts([\n    {\n      type: \"toggle\",\n      name: \"autoPort\",\n      message: \"Port is in use, should I automatically find another port?\",\n      initial: true,\n      active: \"yes\",\n      inactive: \"no\",\n    },\n  ])\n}\n\nmodule.exports = confirmPort\n"
  },
  {
    "path": "src/prompts/confirmServerReinstall.js",
    "content": "const prompts = require(\"prompts\")\n\nconst confirmServerReinstall = () => {\n  return prompts([\n    {\n      type: \"confirm\",\n      name: \"reinstall\",\n      message: \"Server already installed. Do you want to reinstall?\",\n      initial: true,\n    },\n  ])\n}\n\nmodule.exports = confirmServerReinstall\n"
  },
  {
    "path": "src/prompts/handleMistake.js",
    "content": "const prompts = require(\"prompts\")\nconst FixMenu = require(\"../components/FixMenu\")\n\nconst handleMistake = (fixes, issue) => {\n  console.log(\"---------------------------------\")\n\n  const dictionaryOptions = issue === \"misspelling\" ? [\"l\", \"g\"] : []\n  const validInputs = [\n    ...fixes.map((_, index) => String(index + 1)),\n    \"0\",\n    \"i\",\n    ...dictionaryOptions,\n    \"n\",\n  ]\n\n  const initialInput = fixes.length > 0 ? \"1\" : \"0\"\n\n  return prompts([\n    {\n      type: \"text\",\n      name: \"option\",\n      message: FixMenu(fixes, issue),\n      initial: initialInput,\n      validate(input) {\n        return validInputs.includes(input)\n          ? true\n          : `Please enter a valid option...`\n      },\n    },\n    {\n      type: (prev) => (prev === \"0\" ? \"text\" : null),\n      name: \"replacement\",\n      message: \"Provide replacement\",\n    },\n  ])\n}\n\nmodule.exports = handleMistake\n"
  },
  {
    "path": "src/prompts/handleSave.js",
    "content": "const prompts = require(\"prompts\")\nconst { platform } = require(\"os\")\n\nconst initialFileName = (originalFile) => {\n  const date =\n    platform() === \"win32\"\n      ? new Date().toISOString().replace(/[.:-]/g, \"\")\n      : new Date().toISOString()\n\n  return originalFile ? `${date}-${originalFile}` : `${date}-gramma.txt`\n}\n\nconst handleSave = (mode, originalFile = null) => {\n  const choices = [\n    ...(mode === \"FILE\" ? [{ title: \"replace file\", value: \"replace\" }] : []),\n    { title: \"save as\", value: \"save-as\" },\n    { title: \"print on screen\", value: \"print\" },\n  ]\n\n  const initialInput = mode === \"FILE\" ? 0 : 1\n\n  return prompts([\n    {\n      type: \"select\",\n      name: \"saveOption\",\n      message: \"What do you want to do?\",\n      initial: initialInput,\n      choices,\n    },\n    {\n      type: (prev) => (prev === \"save-as\" ? \"text\" : null),\n      name: \"fileName\",\n      initial: initialFileName(originalFile),\n      message: \"Please provide a file path\",\n    },\n  ])\n}\n\nmodule.exports = handleSave\n"
  },
  {
    "path": "src/prompts/mainMenu.js",
    "content": "const prompts = require(\"prompts\")\n\nconst mainMenu = () => {\n  const choices = [\n    { title: \"check file\", value: \"check\" },\n    { title: \"check text\", value: \"listen\" },\n  ]\n\n  return prompts([\n    {\n      type: \"select\",\n      name: \"saveOption\",\n      message: \"What do you want to do?\",\n      choices,\n    },\n    {\n      type: (prev) => (prev === \"check\" ? \"text\" : null),\n      name: \"fileName\",\n      message: \"Chose file path (relative or absolute)\",\n    },\n  ])\n}\n\nmodule.exports = mainMenu\n"
  },
  {
    "path": "src/requests/checkViaAPI.d.ts",
    "content": "export = checkViaAPI\n/**\n * Calls the provided LanguageTool API\n * and returns grammar checker suggestions.\n *\n * @param text text to check\n * @param options request config\n *\n * @returns grammar checker suggestions\n */\ndeclare function checkViaAPI(\n  text: any,\n  options?: {\n    api_url?: string\n    api_key?: string\n    language?: string\n    rules?: { [ruleName: string]: boolean }\n    dictionary?: string[]\n    markdown?: boolean\n  },\n): Promise<{\n  language: {\n    name: string\n    code: string\n    [key: string]: any\n  }\n  matches: {\n    message: string\n    shortMessage: string\n    replacements: { value: string; [key: string]: any }[]\n    offset: number\n    length: number\n    context: { text: string; offset: number; length: number }\n    sentence: string\n    type: { typeName: string }\n    rule: {\n      id: string\n      description: string\n      issueType: string\n      category: { id: string; name: string }\n      isPremium: false\n    }\n    word: string\n    [key: string]: any\n  }[]\n  [key: string]: any\n}>\n"
  },
  {
    "path": "src/requests/checkViaAPI.js",
    "content": "const queryString = require(\"query-string\")\nconst initialConfig = require(\"../initialConfig\")\n// @ts-ignore\nconst prepareMarkdown = require(\"../utils/prepareMarkdown\").default\n\nconst addWordFields = (matches) => {\n  return matches.map((match) => {\n    const word = match.context.text.substr(\n      match.context.offset,\n      match.context.length,\n    )\n\n    return { ...match, word }\n  })\n}\n\nconst removeFalsePositives = (matches, dictionary, disabledRules) => {\n  return matches.filter(\n    (match) =>\n      !disabledRules.includes(match.rule.category.id) &&\n      !(\n        match.rule.issueType === \"misspelling\" &&\n        dictionary.includes(match.word)\n      ),\n  )\n}\n\nconst MAX_REPLACEMENTS = 30\n\n/**\n * Calls the provided LanguageTool API\n * and returns grammar checker suggestions.\n *\n * @param {string} text text to check\n * @param {Object} options request config\n *\n * @returns {Promise<Object>} grammar checker suggestions\n */\nconst checkViaAPI = async (text, options = {}) => {\n  const cfg = { ...initialConfig, ...options }\n  const disabledRules = Object.entries(cfg.rules)\n    // eslint-disable-next-line no-unused-vars\n    .filter(([rule, value]) => value === false)\n    .map(([rule]) => rule.toUpperCase())\n\n  const disabledRulesEntry =\n    disabledRules.length === 0 || cfg.api_url.includes(\"grammarbot\")\n      ? {}\n      : { disabledCategories: disabledRules.join(\",\") }\n\n  const input = options.markdown ? { data: prepareMarkdown(text) } : { text }\n\n  const postData = queryString.stringify({\n    api_key: cfg.api_key,\n    language: cfg.language,\n    ...input,\n    ...disabledRulesEntry,\n  })\n\n  // eslint-disable-next-line\n  const response = await fetch(cfg.api_url, {\n    headers: {\n      \"Content-Type\": \"application/x-www-form-urlencoded\",\n    },\n    body: postData,\n    method: \"POST\",\n  })\n\n  const body = await response.text()\n\n  let result\n\n  try {\n    result = JSON.parse(body)\n  } catch (e) {\n    if (cfg.api_url.includes(\"grammarbot\")) {\n      throw new Error(\n        \"Language not available at grammarbot.io.\\n\" +\n          \"Please consider installing a local LanguageTool server:\\n\" +\n          \"https://github.com/caderek/gramma#installing-local-server\",\n      )\n    } else {\n      throw new Error(body)\n    }\n  }\n\n  const resultWithWords = {\n    ...result,\n    matches: removeFalsePositives(\n      addWordFields(result.matches),\n      cfg.dictionary,\n      cfg.api_url === initialConfig.api_url ? disabledRules : [],\n    ),\n  }\n\n  resultWithWords.matches.forEach((match) => {\n    if (match.replacements.length > MAX_REPLACEMENTS) {\n      match.replacements.length = MAX_REPLACEMENTS // eslint-disable-line\n    }\n  })\n\n  return resultWithWords\n}\n\nmodule.exports = checkViaAPI\n"
  },
  {
    "path": "src/requests/checkViaCmd.js",
    "content": "const fs = require(\"fs\")\nconst path = require(\"path\")\nconst kleur = require(\"kleur\")\nconst { execSync } = require(\"child_process\")\nconst initialConfig = require(\"../initialConfig\")\n\nconst addWordFields = (matches) => {\n  return matches.map((match) => {\n    const word = match.context.text.substr(\n      match.context.offset,\n      match.context.length,\n    )\n\n    return { ...match, word }\n  })\n}\n\nconst removeFalsePositives = (matches, dictionary, disabledRules) => {\n  return matches.filter(\n    (match) =>\n      !disabledRules.includes(match.rule.category.id) &&\n      !(\n        match.rule.issueType === \"misspelling\" &&\n        dictionary.includes(match.word)\n      ),\n  )\n}\n\nconst createTempFile = (file, text) => {\n  fs.writeFileSync(file, text)\n}\n\nconst removeTempFile = (file) => {\n  fs.unlinkSync(file)\n}\n\nconst MAX_REPLACEMENTS = 30\n\n/**\n * Calls the provided LanguageTool API\n * and returns grammar checker suggestions.\n *\n * @param {string} text text to check\n * @param {Object} options request config\n *\n * @returns {Promise<Object>} grammar checker suggestions\n */\nconst checkViaCmd = async (\n  text,\n  options = {},\n  serverDirPath,\n  configDirPath,\n) => {\n  const cfg = { ...initialConfig, ...options }\n  // console.log({ cfg, serverDirPath, configDirPath })\n\n  const disabledRules = Object.entries(cfg.rules)\n    // eslint-disable-next-line no-unused-vars\n    .filter(([rule, value]) => value === false)\n    .map(([rule]) => rule.toUpperCase())\n\n  const tempFile = path.join(configDirPath, \".temp\")\n\n  createTempFile(tempFile, text)\n\n  const jar = path.join(serverDirPath, \"languagetool-commandline.jar\")\n  const lang = cfg.language === \"auto\" ? \" -adl\" : ` -l ${cfg.language}`\n  const disabled =\n    disabledRules.length === 0 ? \"\" : ` -d ${disabledRules.join(\",\")}`\n\n  const cmd = `java -jar ${jar}${lang}${disabled} --json ${tempFile}`\n\n  let response\n  let result\n\n  try {\n    response = execSync(cmd, { stdio: \"pipe\" })\n    response = response.toString().split(\"\\n\")\n    result = JSON.parse(response[response.length - 1])\n  } catch (e) {\n    removeTempFile(tempFile)\n\n    console.log(kleur.red(\"Cannot execute command via local LanguageTool cmd\"))\n    console.log(\"Please check if your command if valid.\")\n    process.exit(1)\n  }\n\n  removeTempFile(tempFile)\n\n  const resultWithWords = {\n    ...result,\n    matches: removeFalsePositives(\n      addWordFields(result.matches),\n      cfg.dictionary,\n      cfg.api_url === initialConfig.api_url ? disabledRules : [],\n    ),\n  }\n\n  resultWithWords.matches.forEach((match) => {\n    if (match.replacements.length > MAX_REPLACEMENTS) {\n      match.replacements.length = MAX_REPLACEMENTS // eslint-disable-line\n    }\n  })\n\n  return resultWithWords\n}\n\nmodule.exports = checkViaCmd\n"
  },
  {
    "path": "src/requests/checkWithFallback.js",
    "content": "const kleur = require(\"kleur\")\nconst startServer = require(\"../server/startServer\")\nconst checkViaAPI = require(\"./checkViaAPI\")\nconst checkViaCmd = require(\"./checkViaCmd\")\nconst stopServer = require(\"../server/stopServer\")\n\nconst checkWithFallback = async (text, cfg) => {\n  const { session, global } = cfg\n  let response\n\n  try {\n    console.info(`Checking via ${cfg.session.api_url}...`)\n\n    response = await checkViaAPI(text, session)\n\n    if (\n      cfg.session.api_url.includes(\"localhost\") &&\n      cfg.session.server_once === \"true\"\n    ) {\n      await stopServer(cfg)\n    }\n  } catch (error) {\n    if (error.code === \"ECONNREFUSED\" || cfg.session.api_url === \"localhost\") {\n      if (global.server_path) {\n        if (!session.markdown) {\n          console.info(`Checking via local LanguageTool cmd...`)\n\n          response = await checkViaCmd(\n            text,\n            session,\n            global.server_path,\n            cfg.paths.globalConfigDir,\n          )\n        } else {\n          const { server, api_url } = await startServer(cfg)\n          console.clear()\n          const updatedSession = { ...session, api_url }\n          response = await checkViaAPI(text, updatedSession)\n\n          if (global.server_once === \"true\") {\n            server.kill()\n          }\n        }\n      } else {\n        console.log(kleur.red(`API server ${session.api_url} not available!`))\n        console.log(\"Please make sure that the server is running.\")\n        console.log(\n          \"TIP: Gramma is able to automatically start local API server if you install it via: gramma server install\",\n        )\n        process.exit(1)\n      }\n    } else {\n      console.log(\"Gramma was unable to get a response from API server.\")\n      console.log(`Details: ${error.message}`)\n      process.exit(1)\n    }\n  }\n\n  return response\n}\n\nmodule.exports = checkWithFallback\n"
  },
  {
    "path": "src/requests/updates.js",
    "content": "const fs = require(\"fs\")\nconst path = require(\"path\")\nconst kleur = require(\"kleur\")\nconst { version } = require(\"../../package.json\")\n\nconst checkForUpdates = async (configDir) => {\n  const updateFile = path.join(configDir, \".update\")\n\n  if (fs.existsSync(updateFile)) {\n    const lastCheck = Number(fs.readFileSync(updateFile).toString())\n    const fullDay = 24 * 60 * 60 * 1000\n\n    if (Date.now() - lastCheck < fullDay) {\n      return { available: false }\n    }\n  }\n\n  const timeout = () => new Promise((_, reject) => setTimeout(reject, 1000))\n\n  try {\n    const response = await Promise.race([\n      fetch(\"https://api.github.com/repos/caderek/gramma/releases/latest\"),\n      timeout(),\n    ])\n    fs.writeFileSync(updateFile, String(Date.now()))\n\n    const data = await response.json()\n\n    const remoteVersion = data.tag_name\n    const [remoteMajor, remoteMinor, remotePatch] = remoteVersion\n      .slice(1)\n      .split(\".\")\n      .map(Number)\n    const [major, minor, patch] = version.split(\".\").map(Number)\n\n    const oldVersion = major * 1e8 + minor * 1e5 + patch * 1e2\n    const newVersion = remoteMajor * 1e8 + remoteMinor * 1e5 + remotePatch * 1e2\n\n    if (newVersion > oldVersion) {\n      return { available: true, newVersion: remoteVersion }\n    }\n\n    return { available: false }\n  } catch (e) {\n    return { available: false }\n  }\n}\n\nconst displayUpdates = async (configDir) => {\n  const { available, newVersion } = await checkForUpdates(configDir)\n\n  if (available) {\n    console.log(\n      kleur.yellow(`\nUpdate available: ${newVersion}\nInstall via NPM or download the new binary from:\nhttps://caderek.github.io/gramma/\n`),\n    )\n  }\n}\n\nexports.checkForUpdates = checkForUpdates\nexports.displayUpdates = displayUpdates\n"
  },
  {
    "path": "src/server/getServerInfo.js",
    "content": "const kleur = require(\"kleur\")\n\nconst getServerInfo = (cfg) => {\n  if (cfg.global.server_pid) {\n    console.log(kleur.green(\"PID: \"), kleur.white(cfg.global.server_pid))\n    console.log(kleur.green(\"Url: \"), kleur.white(cfg.global.api_url))\n    console.log(kleur.green(\"Path:\"), kleur.white(cfg.global.server_path))\n  } else {\n    console.log(kleur.yellow(\"API server is not running!\"))\n  }\n}\n\nmodule.exports = getServerInfo\n"
  },
  {
    "path": "src/server/getServerPID.js",
    "content": "const kleur = require(\"kleur\")\n\nconst getServerPID = (cfg) => {\n  if (cfg.global.server_pid) {\n    console.log(kleur.green(`API server PID: ${cfg.global.server_pid}`))\n  } else {\n    console.log(kleur.yellow(\"API server is not running!\"))\n  }\n}\n\nmodule.exports = getServerPID\n"
  },
  {
    "path": "src/server/installServer.js",
    "content": "const path = require(\"path\")\nconst fs = require(\"fs\")\nconst kleur = require(\"kleur\")\nconst rimraf = require(\"rimraf\")\nconst downloadFile = require(\"../utils/downloadFile\")\nconst unzipFile = require(\"../utils/unzipFile\")\nconst configure = require(\"../actions/configure\")\nconst confirmServerReinstall = require(\"../prompts/confirmServerReinstall\")\n\nconst installServer = async (cfg) => {\n  const serverDir = path.join(cfg.paths.home, \".languagetool\")\n  const zipPath = path.join(serverDir, \"languagetool.zip\")\n\n  if (fs.existsSync(serverDir)) {\n    const { reinstall } = await confirmServerReinstall()\n\n    if (reinstall) {\n      rimraf.sync(serverDir)\n    } else {\n      console.log(\"Aborting!\")\n      process.exit()\n    }\n  }\n\n  fs.mkdirSync(serverDir)\n\n  await downloadFile(\n    \"https://languagetool.org/download/LanguageTool-stable.zip\",\n    zipPath,\n  )\n\n  console.log(\"Unpacking...\")\n\n  await unzipFile(zipPath, serverDir)\n\n  rimraf.sync(zipPath)\n\n  console.log(\"Configuring...\")\n\n  const [unpackedDirName] = fs.readdirSync(serverDir)\n  const serverPath = path.join(serverDir, unpackedDirName)\n\n  configure(\"server_path\", serverPath, cfg, true, true)\n  configure(\"api_url\", \"localhost\", cfg, true, true)\n\n  console.log(kleur.green(`Server installed in: ${serverDir}`))\n}\n\nmodule.exports = installServer\n"
  },
  {
    "path": "src/server/showServerGUI.js",
    "content": "const { spawn } = require(\"child_process\")\nconst path = require(\"path\")\nconst kleur = require(\"kleur\")\n\nconst showServerGUI = async (cfg) => {\n  if (!cfg.global.server_path) {\n    console.log(\n      kleur.red(`Please install local server via: gramma server install`),\n    )\n    return false\n  }\n\n  console.log(\"Starting local server GUI...\")\n\n  const command = \"java\"\n\n  const params = [\"-jar\", path.join(cfg.global.server_path, \"languagetool.jar\")]\n\n  const gui = spawn(command, params, { windowsHide: true, detached: true })\n\n  gui.on(\"error\", (error) => {\n    if (error) {\n      console.log(kleur.red(\"Cannot start local server GUI automatically.\"))\n      process.exit(1)\n    }\n  })\n\n  return true\n}\n\nmodule.exports = showServerGUI\n"
  },
  {
    "path": "src/server/startServer.js",
    "content": "const { spawn } = require(\"child_process\")\nconst path = require(\"path\")\nconst kleur = require(\"kleur\")\nconst portfinder = require(\"portfinder\")\nconst tcpPortUsed = require(\"tcp-port-used\")\nconst configure = require(\"../actions/configure\")\nconst confirmPort = require(\"../prompts/confirmPort\")\n\nconst delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms))\n\nconst pingServer = async (url) => {\n  console.log(\"Waiting for local API server...\")\n  const response = await fetch(`${url}?language=en-US&text=`).catch(() => {\n    return {\n      status: 500,\n    }\n  })\n\n  if (response.status === 200) {\n    return\n  }\n\n  await delay(1000)\n  await pingServer(url)\n}\n\nconst startServer = async (cfg, { port = null, viaCommand = false } = {}) => {\n  if (!cfg.global.server_path) {\n    console.log(\n      kleur.red(`Please install local server via: gramma server install`),\n    )\n    process.exit(1)\n  }\n\n  if (port !== null) {\n    const inUse = tcpPortUsed.check(port)\n\n    if (inUse) {\n      const { autoPort } = await confirmPort()\n\n      if (!autoPort) {\n        console.log(kleur.yellow(\"Aborted!\"))\n        process.exit(1)\n      }\n    }\n  }\n\n  console.log(\"Starting local API server...\")\n\n  const PORT = await portfinder.getPortPromise({\n    port: port || 8081,\n  })\n\n  const command = \"java\"\n\n  const params = [\n    \"-cp\",\n    path.join(cfg.global.server_path, \"languagetool-server.jar\"),\n    \"org.languagetool.server.HTTPServer\",\n    \"--port\",\n    String(PORT),\n    \"--allow-origin\",\n    \"'*'\",\n  ]\n\n  const server = spawn(command, params, { windowsHide: true, detached: true })\n\n  server.on(\"error\", (error) => {\n    if (error) {\n      console.log(kleur.red(\"Cannot start local API server automatically.\"))\n      process.exit(1)\n    }\n  })\n\n  // eslint-disable-next-line camelcase\n  const api_url = `http://localhost:${PORT}/v2/check`\n\n  await pingServer(api_url)\n\n  configure(\"api_url\", api_url, cfg, true, true)\n\n  if (cfg.global.server_once !== \"true\" || viaCommand) {\n    configure(\"server_pid\", server.pid, cfg, true, true)\n  }\n\n  console.log(\n    kleur.green(`API server started!\\nPID: ${server.pid}\\nAPI URL: ${api_url}`),\n  )\n\n  return { server, api_url }\n}\n\nmodule.exports = startServer\n"
  },
  {
    "path": "src/server/stopServer.js",
    "content": "const { exec } = require(\"child_process\")\nconst kleur = require(\"kleur\")\nconst { platform } = require(\"os\")\nconst configure = require(\"../actions/configure\")\n\nconst stopServer = async (cfg) => {\n  if (cfg.global.server_pid) {\n    const command =\n      platform() === \"win32\"\n        ? `taskkill /PID ${cfg.global.server_pid} /F`\n        : `kill ${cfg.global.server_pid}`\n\n    return new Promise((resolve, reject) => {\n      exec(command, (error) => {\n        if (error) {\n          reject(error)\n        } else {\n          resolve()\n        }\n      })\n    })\n      .then(() => {\n        console.log(kleur.green(\"API server stopped!\"))\n      })\n      .catch(() => {\n        console.log(kleur.yellow(\"API server is not running!\"))\n      })\n      .then(() => {\n        configure(\"server_pid\", \"\", cfg, true, true)\n      })\n  }\n\n  console.log(kleur.yellow(\"API server is not running!\"))\n  return false\n}\n\nmodule.exports = stopServer\n"
  },
  {
    "path": "src/text-manipulation/replace.js",
    "content": "const replace = (text, change, offset, length) => {\n  const before = text.slice(0, offset)\n  const mistake = text.slice(offset, offset + length)\n  const after = text.slice(offset + length)\n\n  const newPhrase = typeof change === \"function\" ? change(mistake) : change\n\n  return `${before}${newPhrase}${after}`\n}\n\nmodule.exports = replace\n"
  },
  {
    "path": "src/text-manipulation/replace.test.js",
    "content": "const replace = require(\"./replace\")\n\ndescribe(\"Replace\", () => {\n  it(\"changes specified part of the text with provides word/phrase\", () => {\n    const text = \"Foo CHANGE_ME baz.\"\n    const change = \"bar\"\n    const offset = 4\n    const length = 9\n\n    const expected = \"Foo bar baz.\"\n    const result = replace(text, change, offset, length)\n\n    expect(result).toEqual(expected)\n  })\n\n  it(\"changes specified part of the text according to provided function\", () => {\n    const text = \"Foo CHANGE_ME baz.\"\n    const change = (mistake) => mistake.toLowerCase()\n    const offset = 4\n    const length = 9\n\n    const expected = \"Foo change_me baz.\"\n    const result = replace(text, change, offset, length)\n\n    expect(result).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "src/text-manipulation/replaceAll.d.ts",
    "content": "export = replaceAll\n/**\n * Modifies provided text with specified transformations.\n *\n * @param text base text\n * @param transformations descriptions of changes to the text\n */\ndeclare function replaceAll(\n  text: string,\n  transformations: { offset: number; length: number; change: string }[],\n): string\n"
  },
  {
    "path": "src/text-manipulation/replaceAll.js",
    "content": "const replace = require(\"./replace\")\n\n/**\n * Modifies provided text with specified transformations.\n *\n * @param text base text\n * @param transformations descriptions of changes to the text\n */\nconst replaceAll = (text, transformations) => {\n  return transformations\n    .sort((a, b) => b.offset - a.offset)\n    .reduce((previousText, { change, offset, length }) => {\n      return replace(previousText, change, offset, length)\n    }, text)\n}\n\nmodule.exports = replaceAll\n"
  },
  {
    "path": "src/text-manipulation/replaceAll.test.js",
    "content": "const replaceAll = require(\"./replaceAll\")\n\ndescribe(\"Replace all\", () => {\n  it.only(\"changes all places according to provided transformations\", () => {\n    const text = \"Foo CHANGE_ONE baz CHANGE_TWO.\"\n    const transformations = [\n      {\n        offset: 4,\n        length: 10,\n        change: \"bar\",\n      },\n      {\n        offset: 19,\n        length: 10,\n        change: \"bat\",\n      },\n    ]\n\n    const expected = \"Foo bar baz bat.\"\n    const result = replaceAll(text, transformations)\n\n    expect(result).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "src/utils/appLocation.js",
    "content": "const path = require(\"path\")\nconst fs = require(\"fs\")\n\nconst binDir = path.dirname(process.execPath)\nconst scriptDir = __dirname\n\nlet appLocation\n\nif (scriptDir.includes(\"snapshot\")) {\n  const executable = fs.readdirSync(binDir)[0]\n  appLocation = path.resolve(binDir, executable)\n} else {\n  appLocation = path.resolve(scriptDir, \"..\", \"cli.js\")\n}\n\nmodule.exports = appLocation\n"
  },
  {
    "path": "src/utils/downloadFile.js",
    "content": "const fs = require(\"fs\")\nconst progressStream = require(\"progress-stream\")\nconst cliProgress = require(\"cli-progress\")\n\nconst toMegabytes = (bytes) => {\n  return Number((bytes / (1000 * 1000)).toFixed(2))\n}\n\nconst downloadFile = async (url, path) => {\n  const res = await fetch(url)\n  const dataLength = res.headers.get(\"content-length\")\n  const bar = new cliProgress.Bar({\n    barCompleteChar: \"#\",\n    barIncompleteChar: \".\",\n    format: \"Downloading: [{bar}] {percentage}% | {value}/{total}MB\",\n  })\n  bar.start(toMegabytes(dataLength), 0)\n\n  const str = progressStream({\n    length: dataLength,\n    time: 100,\n  }).on(\"progress\", (progress) => bar.update(toMegabytes(progress.transferred)))\n\n  const fileStream = fs.createWriteStream(path)\n\n  return new Promise((resolve, reject) => {\n    res.body.pipe(str).pipe(fileStream)\n    res.body.on(\"error\", (err) => {\n      reject(err)\n    })\n    fileStream.on(\"finish\", () => {\n      bar.stop()\n      resolve()\n    })\n  })\n}\n\nmodule.exports = downloadFile\n"
  },
  {
    "path": "src/utils/equal.js",
    "content": "const { deepEqual } = require(\"assert\")\n\nconst equal = (a, b) => {\n  try {\n    deepEqual(a, b)\n    return true\n  } catch (e) {\n    return false\n  }\n}\n\nmodule.exports = equal\n"
  },
  {
    "path": "src/utils/findUpSync.js",
    "content": "var __create = Object.create\nvar __defProp = Object.defineProperty\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor\nvar __getOwnPropNames = Object.getOwnPropertyNames\nvar __getProtoOf = Object.getPrototypeOf\nvar __hasOwnProp = Object.prototype.hasOwnProperty\nvar __markAsModule = (target) =>\n  __defProp(target, \"__esModule\", { value: true })\nvar __export = (target, all) => {\n  __markAsModule(target)\n  for (var name in all)\n    __defProp(target, name, { get: all[name], enumerable: true })\n}\nvar __reExport = (target, module2, desc) => {\n  if (\n    (module2 && typeof module2 === \"object\") ||\n    typeof module2 === \"function\"\n  ) {\n    for (let key of __getOwnPropNames(module2))\n      if (!__hasOwnProp.call(target, key) && key !== \"default\")\n        __defProp(target, key, {\n          get: () => module2[key],\n          enumerable:\n            !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable,\n        })\n  }\n  return target\n}\nvar __toModule = (module2) => {\n  return __reExport(\n    __markAsModule(\n      __defProp(\n        module2 != null ? __create(__getProtoOf(module2)) : {},\n        \"default\",\n        module2 && module2.__esModule && \"default\" in module2\n          ? { get: () => module2.default, enumerable: true }\n          : { value: module2, enumerable: true },\n      ),\n    ),\n    module2,\n  )\n}\n\n// lib/findUpSync.mjs\n__export(exports, {\n  default: () => findUpSync_default,\n})\n\n// lib/node_modules/find-up/index.js\nvar import_path = __toModule(require(\"path\"))\n\n// lib/node_modules/locate-path/index.js\nvar import_node_process = __toModule(require(\"process\"))\nvar import_node_path = __toModule(require(\"path\"))\nvar import_node_fs = __toModule(require(\"fs\"))\n\n// lib/node_modules/yocto-queue/index.js\nvar Node = class {\n  value\n  next\n  constructor(value) {\n    this.value = value\n  }\n}\nvar Queue = class {\n  #head\n  #tail\n  #size\n  constructor() {\n    this.clear()\n  }\n  enqueue(value) {\n    const node = new Node(value)\n    if (this.#head) {\n      this.#tail.next = node\n      this.#tail = node\n    } else {\n      this.#head = node\n      this.#tail = node\n    }\n    this.#size++\n  }\n  dequeue() {\n    const current = this.#head\n    if (!current) {\n      return\n    }\n    this.#head = this.#head.next\n    this.#size--\n    return current.value\n  }\n  clear() {\n    this.#head = void 0\n    this.#tail = void 0\n    this.#size = 0\n  }\n  get size() {\n    return this.#size\n  }\n  *[Symbol.iterator]() {\n    let current = this.#head\n    while (current) {\n      yield current.value\n      current = current.next\n    }\n  }\n}\n\n// lib/node_modules/locate-path/index.js\nvar typeMappings = {\n  directory: \"isDirectory\",\n  file: \"isFile\",\n}\nfunction checkType(type) {\n  if (type in typeMappings) {\n    return\n  }\n  throw new Error(`Invalid type specified: ${type}`)\n}\nvar matchType = (type, stat) => type === void 0 || stat[typeMappings[type]]()\nfunction locatePathSync(\n  paths,\n  {\n    cwd = import_node_process.default.cwd(),\n    type = \"file\",\n    allowSymlinks = true,\n  } = {},\n) {\n  checkType(type)\n  const statFunction = allowSymlinks\n    ? import_node_fs.default.statSync\n    : import_node_fs.default.lstatSync\n  for (const path_ of paths) {\n    try {\n      const stat = statFunction(import_node_path.default.resolve(cwd, path_))\n      if (matchType(type, stat)) {\n        return path_\n      }\n    } catch {}\n  }\n}\n\n// lib/node_modules/path-exists/index.js\nvar import_node_fs2 = __toModule(require(\"fs\"))\n\n// lib/node_modules/find-up/index.js\nvar findUpStop = Symbol(\"findUpStop\")\nfunction findUpMultipleSync(name, options = {}) {\n  let directory = import_path.default.resolve(options.cwd || \"\")\n  const { root } = import_path.default.parse(directory)\n  const stopAt = options.stopAt || root\n  const limit = options.limit || Number.POSITIVE_INFINITY\n  const paths = [name].flat()\n  const runMatcher = (locateOptions) => {\n    if (typeof name !== \"function\") {\n      return locatePathSync(paths, locateOptions)\n    }\n    const foundPath = name(locateOptions.cwd)\n    if (typeof foundPath === \"string\") {\n      return locatePathSync([foundPath], locateOptions)\n    }\n    return foundPath\n  }\n  const matches = []\n  while (true) {\n    const foundPath = runMatcher({ ...options, cwd: directory })\n    if (foundPath === findUpStop) {\n      break\n    }\n    if (foundPath) {\n      matches.push(import_path.default.resolve(directory, foundPath))\n    }\n    if (directory === stopAt || matches.length >= limit) {\n      break\n    }\n    directory = import_path.default.dirname(directory)\n  }\n  return matches\n}\nfunction findUpSync(name, options = {}) {\n  const matches = findUpMultipleSync(name, { ...options, limit: 1 })\n  return matches[0]\n}\n\n// lib/findUpSync.mjs\nvar findUpSync_default = findUpSync\n// Annotate the CommonJS export names for ESM import in node:\n0 && (module.exports = {})\n"
  },
  {
    "path": "src/utils/prepareMarkdown.js",
    "content": "// @ts-nocheck\n/**\n * Generated via:\n * esbuild lib/prepareMarkdown.mjs --bundle --outfile=src/utils/prepareMarkdown.js --format=cjs\n *\n * Do not edit directly!\n */\n\nvar __create = Object.create\nvar __defProp = Object.defineProperty\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor\nvar __getOwnPropNames = Object.getOwnPropertyNames\nvar __getProtoOf = Object.getPrototypeOf\nvar __hasOwnProp = Object.prototype.hasOwnProperty\nvar __markAsModule = (target) =>\n  __defProp(target, \"__esModule\", { value: true })\nvar __commonJS = (cb, mod) =>\n  function __require() {\n    return (\n      mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod),\n      mod.exports\n    )\n  }\nvar __export = (target, all2) => {\n  __markAsModule(target)\n  for (var name in all2)\n    __defProp(target, name, { get: all2[name], enumerable: true })\n}\nvar __reExport = (target, module2, desc) => {\n  if (\n    (module2 && typeof module2 === \"object\") ||\n    typeof module2 === \"function\"\n  ) {\n    for (let key of __getOwnPropNames(module2))\n      if (!__hasOwnProp.call(target, key) && key !== \"default\")\n        __defProp(target, key, {\n          get: () => module2[key],\n          enumerable:\n            !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable,\n        })\n  }\n  return target\n}\nvar __toModule = (module2) => {\n  return __reExport(\n    __markAsModule(\n      __defProp(\n        module2 != null ? __create(__getProtoOf(module2)) : {},\n        \"default\",\n        module2 && module2.__esModule && \"default\" in module2\n          ? { get: () => module2.default, enumerable: true }\n          : { value: module2, enumerable: true },\n      ),\n    ),\n    module2,\n  )\n}\n\n// node_modules/format/format.js\nvar require_format = __commonJS({\n  \"node_modules/format/format.js\"(exports, module2) {\n    ;(function () {\n      var namespace\n      if (typeof module2 !== \"undefined\") {\n        namespace = module2.exports = format\n      } else {\n        namespace = (function () {\n          return this || (1, eval)(\"this\")\n        })()\n      }\n      namespace.format = format\n      namespace.vsprintf = vsprintf\n      if (typeof console !== \"undefined\" && typeof console.log === \"function\") {\n        namespace.printf = printf\n      }\n      function printf() {\n        console.log(format.apply(null, arguments))\n      }\n      function vsprintf(fmt, replacements) {\n        return format.apply(null, [fmt].concat(replacements))\n      }\n      function format(fmt) {\n        var argIndex = 1,\n          args = [].slice.call(arguments),\n          i = 0,\n          n = fmt.length,\n          result = \"\",\n          c,\n          escaped = false,\n          arg,\n          tmp,\n          leadingZero = false,\n          precision,\n          nextArg = function () {\n            return args[argIndex++]\n          },\n          slurpNumber = function () {\n            var digits = \"\"\n            while (/\\d/.test(fmt[i])) {\n              digits += fmt[i++]\n              c = fmt[i]\n            }\n            return digits.length > 0 ? parseInt(digits) : null\n          }\n        for (; i < n; ++i) {\n          c = fmt[i]\n          if (escaped) {\n            escaped = false\n            if (c == \".\") {\n              leadingZero = false\n              c = fmt[++i]\n            } else if (c == \"0\" && fmt[i + 1] == \".\") {\n              leadingZero = true\n              i += 2\n              c = fmt[i]\n            } else {\n              leadingZero = true\n            }\n            precision = slurpNumber()\n            switch (c) {\n              case \"b\":\n                result += parseInt(nextArg(), 10).toString(2)\n                break\n              case \"c\":\n                arg = nextArg()\n                if (typeof arg === \"string\" || arg instanceof String)\n                  result += arg\n                else result += String.fromCharCode(parseInt(arg, 10))\n                break\n              case \"d\":\n                result += parseInt(nextArg(), 10)\n                break\n              case \"f\":\n                tmp = String(parseFloat(nextArg()).toFixed(precision || 6))\n                result += leadingZero ? tmp : tmp.replace(/^0/, \"\")\n                break\n              case \"j\":\n                result += JSON.stringify(nextArg())\n                break\n              case \"o\":\n                result += \"0\" + parseInt(nextArg(), 10).toString(8)\n                break\n              case \"s\":\n                result += nextArg()\n                break\n              case \"x\":\n                result += \"0x\" + parseInt(nextArg(), 10).toString(16)\n                break\n              case \"X\":\n                result +=\n                  \"0x\" + parseInt(nextArg(), 10).toString(16).toUpperCase()\n                break\n              default:\n                result += c\n                break\n            }\n          } else if (c === \"%\") {\n            escaped = true\n          } else {\n            result += c\n          }\n        }\n        return result\n      }\n    })()\n  },\n})\n\n// node_modules/is-buffer/index.js\nvar require_is_buffer = __commonJS({\n  \"node_modules/is-buffer/index.js\"(exports, module2) {\n    module2.exports = function isBuffer2(obj) {\n      return (\n        obj != null &&\n        obj.constructor != null &&\n        typeof obj.constructor.isBuffer === \"function\" &&\n        obj.constructor.isBuffer(obj)\n      )\n    }\n  },\n})\n\n// node_modules/extend/index.js\nvar require_extend = __commonJS({\n  \"node_modules/extend/index.js\"(exports, module2) {\n    \"use strict\"\n    var hasOwn = Object.prototype.hasOwnProperty\n    var toStr = Object.prototype.toString\n    var defineProperty = Object.defineProperty\n    var gOPD = Object.getOwnPropertyDescriptor\n    var isArray = function isArray2(arr) {\n      if (typeof Array.isArray === \"function\") {\n        return Array.isArray(arr)\n      }\n      return toStr.call(arr) === \"[object Array]\"\n    }\n    var isPlainObject2 = function isPlainObject3(obj) {\n      if (!obj || toStr.call(obj) !== \"[object Object]\") {\n        return false\n      }\n      var hasOwnConstructor = hasOwn.call(obj, \"constructor\")\n      var hasIsPrototypeOf =\n        obj.constructor &&\n        obj.constructor.prototype &&\n        hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\")\n      if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {\n        return false\n      }\n      var key\n      for (key in obj) {\n      }\n      return typeof key === \"undefined\" || hasOwn.call(obj, key)\n    }\n    var setProperty = function setProperty2(target, options) {\n      if (defineProperty && options.name === \"__proto__\") {\n        defineProperty(target, options.name, {\n          enumerable: true,\n          configurable: true,\n          value: options.newValue,\n          writable: true,\n        })\n      } else {\n        target[options.name] = options.newValue\n      }\n    }\n    var getProperty = function getProperty2(obj, name) {\n      if (name === \"__proto__\") {\n        if (!hasOwn.call(obj, name)) {\n          return void 0\n        } else if (gOPD) {\n          return gOPD(obj, name).value\n        }\n      }\n      return obj[name]\n    }\n    module2.exports = function extend2() {\n      var options, name, src, copy, copyIsArray, clone\n      var target = arguments[0]\n      var i = 1\n      var length = arguments.length\n      var deep = false\n      if (typeof target === \"boolean\") {\n        deep = target\n        target = arguments[1] || {}\n        i = 2\n      }\n      if (\n        target == null ||\n        (typeof target !== \"object\" && typeof target !== \"function\")\n      ) {\n        target = {}\n      }\n      for (; i < length; ++i) {\n        options = arguments[i]\n        if (options != null) {\n          for (name in options) {\n            src = getProperty(target, name)\n            copy = getProperty(options, name)\n            if (target !== copy) {\n              if (\n                deep &&\n                copy &&\n                (isPlainObject2(copy) || (copyIsArray = isArray(copy)))\n              ) {\n                if (copyIsArray) {\n                  copyIsArray = false\n                  clone = src && isArray(src) ? src : []\n                } else {\n                  clone = src && isPlainObject2(src) ? src : {}\n                }\n                setProperty(target, {\n                  name,\n                  newValue: extend2(deep, clone, copy),\n                })\n              } else if (typeof copy !== \"undefined\") {\n                setProperty(target, { name, newValue: copy })\n              }\n            }\n          }\n        }\n      }\n      return target\n    }\n  },\n})\n\n// lib/prepareMarkdown.mjs\n__export(exports, {\n  default: () => prepareMarkdown_default,\n})\n\n// node_modules/annotatedtext/out/index.js\nvar defaults = {\n  children(node) {\n    return node.children\n  },\n  annotatetextnode(node, text3) {\n    if (node.type === \"text\") {\n      return {\n        offset: {\n          end: node.position.end.offset,\n          start: node.position.start.offset,\n        },\n        text: text3.substring(\n          node.position.start.offset,\n          node.position.end.offset,\n        ),\n      }\n    } else {\n      return null\n    }\n  },\n  interpretmarkup(text3 = \"\") {\n    return text3\n  },\n}\nfunction collecttextnodes(ast, text3, options = defaults) {\n  const textannotations = []\n  function recurse(node) {\n    const annotation = options.annotatetextnode(node, text3)\n    if (annotation !== null) {\n      textannotations.push(annotation)\n    }\n    const children = options.children(node)\n    if (children !== null && Array.isArray(children)) {\n      children.forEach(recurse)\n    }\n  }\n  recurse(ast)\n  return textannotations\n}\nfunction composeannotation(text3, annotatedtextnodes, options = defaults) {\n  const annotations = []\n  let prior = {\n    offset: {\n      end: 0,\n      start: 0,\n    },\n  }\n  for (const current of annotatedtextnodes) {\n    const currenttext = text3.substring(prior.offset.end, current.offset.start)\n    annotations.push({\n      interpretAs: options.interpretmarkup(currenttext),\n      markup: currenttext,\n      offset: {\n        end: current.offset.start,\n        start: prior.offset.end,\n      },\n    })\n    annotations.push(current)\n    prior = current\n  }\n  const finaltext = text3.substring(prior.offset.end, text3.length)\n  annotations.push({\n    interpretAs: options.interpretmarkup(finaltext),\n    markup: finaltext,\n    offset: {\n      end: text3.length,\n      start: prior.offset.end,\n    },\n  })\n  return { annotation: annotations }\n}\nfunction build(text3, parse3, options = defaults) {\n  const nodes = parse3(text3)\n  const textnodes = collecttextnodes(nodes, text3, options)\n  return composeannotation(text3, textnodes, options)\n}\n\n// node_modules/fault/index.js\nvar import_format = __toModule(require_format())\nvar fault = Object.assign(create(Error), {\n  eval: create(EvalError),\n  range: create(RangeError),\n  reference: create(ReferenceError),\n  syntax: create(SyntaxError),\n  type: create(TypeError),\n  uri: create(URIError),\n})\nfunction create(Constructor) {\n  FormattedError.displayName = Constructor.displayName || Constructor.name\n  return FormattedError\n  function FormattedError(format, ...values) {\n    var reason = format ? (0, import_format.default)(format, ...values) : format\n    return new Constructor(reason)\n  }\n}\n\n// node_modules/micromark-extension-frontmatter/matters.js\nvar own = {}.hasOwnProperty\nvar markers = {\n  yaml: \"-\",\n  toml: \"+\",\n}\nfunction matters(options = \"yaml\") {\n  const results = []\n  let index2 = -1\n  if (!Array.isArray(options)) {\n    options = [options]\n  }\n  while (++index2 < options.length) {\n    results[index2] = matter(options[index2])\n  }\n  return results\n}\nfunction matter(option) {\n  let result = option\n  if (typeof result === \"string\") {\n    if (!own.call(markers, result)) {\n      throw fault(\"Missing matter definition for `%s`\", result)\n    }\n    result = {\n      type: result,\n      marker: markers[result],\n    }\n  } else if (typeof result !== \"object\") {\n    throw fault(\"Expected matter to be an object, not `%j`\", result)\n  }\n  if (!own.call(result, \"type\")) {\n    throw fault(\"Missing `type` in matter `%j`\", result)\n  }\n  if (!own.call(result, \"fence\") && !own.call(result, \"marker\")) {\n    throw fault(\"Missing `marker` or `fence` in matter `%j`\", result)\n  }\n  return result\n}\n\n// node_modules/micromark-util-character/lib/unicode-punctuation-regex.js\nvar unicodePunctuationRegex =\n  /[!-/:-@[-`{-~\\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]/\n\n// node_modules/micromark-util-character/index.js\nvar asciiAlpha = regexCheck(/[A-Za-z]/)\nvar asciiDigit = regexCheck(/\\d/)\nvar asciiHexDigit = regexCheck(/[\\dA-Fa-f]/)\nvar asciiAlphanumeric = regexCheck(/[\\dA-Za-z]/)\nvar asciiPunctuation = regexCheck(/[!-/:-@[-`{-~]/)\nvar asciiAtext = regexCheck(/[#-'*+\\--9=?A-Z^-~]/)\nfunction asciiControl(code) {\n  return code !== null && (code < 32 || code === 127)\n}\nfunction markdownLineEndingOrSpace(code) {\n  return code !== null && (code < 0 || code === 32)\n}\nfunction markdownLineEnding(code) {\n  return code !== null && code < -2\n}\nfunction markdownSpace(code) {\n  return code === -2 || code === -1 || code === 32\n}\nvar unicodeWhitespace = regexCheck(/\\s/)\nvar unicodePunctuation = regexCheck(unicodePunctuationRegex)\nfunction regexCheck(regex) {\n  return check\n  function check(code) {\n    return code !== null && regex.test(String.fromCharCode(code))\n  }\n}\n\n// node_modules/micromark-extension-frontmatter/lib/syntax.js\nfunction frontmatter(options) {\n  const settings = matters(options)\n  const flow3 = {}\n  let index2 = -1\n  let matter2\n  let code\n  while (++index2 < settings.length) {\n    matter2 = settings[index2]\n    code = fence(matter2, \"open\").charCodeAt(0)\n    if (code in flow3) {\n      flow3[code].push(parse(matter2))\n    } else {\n      flow3[code] = [parse(matter2)]\n    }\n  }\n  return {\n    flow: flow3,\n  }\n}\nfunction parse(matter2) {\n  const name = matter2.type\n  const anywhere = matter2.anywhere\n  const valueType = name + \"Value\"\n  const fenceType = name + \"Fence\"\n  const sequenceType = fenceType + \"Sequence\"\n  const fenceConstruct = {\n    tokenize: tokenizeFence,\n    partial: true,\n  }\n  let buffer2\n  return {\n    tokenize: tokenizeFrontmatter,\n    concrete: true,\n  }\n  function tokenizeFrontmatter(effects, ok, nok) {\n    const self = this\n    return start\n    function start(code) {\n      const position2 = self.now()\n      if (position2.column !== 1 || (!anywhere && position2.line !== 1)) {\n        return nok(code)\n      }\n      effects.enter(name)\n      buffer2 = fence(matter2, \"open\")\n      return effects.attempt(fenceConstruct, afterOpeningFence, nok)(code)\n    }\n    function afterOpeningFence(code) {\n      buffer2 = fence(matter2, \"close\")\n      return lineEnd(code)\n    }\n    function lineStart(code) {\n      if (code === null || markdownLineEnding(code)) {\n        return lineEnd(code)\n      }\n      effects.enter(valueType)\n      return lineData(code)\n    }\n    function lineData(code) {\n      if (code === null || markdownLineEnding(code)) {\n        effects.exit(valueType)\n        return lineEnd(code)\n      }\n      effects.consume(code)\n      return lineData\n    }\n    function lineEnd(code) {\n      if (code === null) {\n        return nok(code)\n      }\n      effects.enter(\"lineEnding\")\n      effects.consume(code)\n      effects.exit(\"lineEnding\")\n      return effects.attempt(fenceConstruct, after, lineStart)\n    }\n    function after(code) {\n      effects.exit(name)\n      return ok(code)\n    }\n  }\n  function tokenizeFence(effects, ok, nok) {\n    let bufferIndex = 0\n    return start\n    function start(code) {\n      if (code === buffer2.charCodeAt(bufferIndex)) {\n        effects.enter(fenceType)\n        effects.enter(sequenceType)\n        return insideSequence(code)\n      }\n      return nok(code)\n    }\n    function insideSequence(code) {\n      if (bufferIndex === buffer2.length) {\n        effects.exit(sequenceType)\n        if (markdownSpace(code)) {\n          effects.enter(\"whitespace\")\n          return insideWhitespace(code)\n        }\n        return fenceEnd(code)\n      }\n      if (code === buffer2.charCodeAt(bufferIndex++)) {\n        effects.consume(code)\n        return insideSequence\n      }\n      return nok(code)\n    }\n    function insideWhitespace(code) {\n      if (markdownSpace(code)) {\n        effects.consume(code)\n        return insideWhitespace\n      }\n      effects.exit(\"whitespace\")\n      return fenceEnd(code)\n    }\n    function fenceEnd(code) {\n      if (code === null || markdownLineEnding(code)) {\n        effects.exit(fenceType)\n        return ok(code)\n      }\n      return nok(code)\n    }\n  }\n}\nfunction fence(matter2, prop) {\n  return matter2.marker\n    ? pick(matter2.marker, prop).repeat(3)\n    : pick(matter2.fence, prop)\n}\nfunction pick(schema, prop) {\n  return typeof schema === \"string\" ? schema : schema[prop]\n}\n\n// node_modules/mdast-util-frontmatter/index.js\nfunction frontmatterFromMarkdown(options) {\n  const settings = matters(options)\n  const enter = {}\n  const exit2 = {}\n  let index2 = -1\n  while (++index2 < settings.length) {\n    const matter2 = settings[index2]\n    enter[matter2.type] = opener(matter2)\n    exit2[matter2.type] = close\n    exit2[matter2.type + \"Value\"] = value\n  }\n  return { enter, exit: exit2 }\n}\nfunction opener(matter2) {\n  return open\n  function open(token) {\n    this.enter({ type: matter2.type, value: \"\" }, token)\n    this.buffer()\n  }\n}\nfunction close(token) {\n  const data = this.resume()\n  this.exit(token).value = data.replace(/^(\\r?\\n|\\r)|(\\r?\\n|\\r)$/g, \"\")\n}\nfunction value(token) {\n  this.config.enter.data.call(this, token)\n  this.config.exit.data.call(this, token)\n}\nfunction frontmatterToMarkdown(options) {\n  const unsafe = []\n  const handlers = {}\n  const settings = matters(options)\n  let index2 = -1\n  while (++index2 < settings.length) {\n    const matter2 = settings[index2]\n    handlers[matter2.type] = handler(matter2)\n    unsafe.push({ atBreak: true, character: fence2(matter2, \"open\").charAt(0) })\n  }\n  return { unsafe, handlers }\n}\nfunction handler(matter2) {\n  const open = fence2(matter2, \"open\")\n  const close2 = fence2(matter2, \"close\")\n  return handle\n  function handle(node) {\n    return open + (node.value ? \"\\n\" + node.value : \"\") + \"\\n\" + close2\n  }\n}\nfunction fence2(matter2, prop) {\n  return matter2.marker\n    ? pick2(matter2.marker, prop).repeat(3)\n    : pick2(matter2.fence, prop)\n}\nfunction pick2(schema, prop) {\n  return typeof schema === \"string\" ? schema : schema[prop]\n}\n\n// node_modules/remark-frontmatter/index.js\nfunction remarkFrontmatter(options = \"yaml\") {\n  const data = this.data()\n  add(\"micromarkExtensions\", frontmatter(options))\n  add(\"fromMarkdownExtensions\", frontmatterFromMarkdown(options))\n  add(\"toMarkdownExtensions\", frontmatterToMarkdown(options))\n  function add(field, value2) {\n    const list2 = data[field] ? data[field] : (data[field] = [])\n    list2.push(value2)\n  }\n}\n\n// node_modules/mdast-util-to-string/index.js\nfunction toString(node, options) {\n  var { includeImageAlt = true } = options || {}\n  return one(node, includeImageAlt)\n}\nfunction one(node, includeImageAlt) {\n  return (\n    (node &&\n      typeof node === \"object\" &&\n      (node.value ||\n        (includeImageAlt ? node.alt : \"\") ||\n        (\"children\" in node && all(node.children, includeImageAlt)) ||\n        (Array.isArray(node) && all(node, includeImageAlt)))) ||\n    \"\"\n  )\n}\nfunction all(values, includeImageAlt) {\n  var result = []\n  var index2 = -1\n  while (++index2 < values.length) {\n    result[index2] = one(values[index2], includeImageAlt)\n  }\n  return result.join(\"\")\n}\n\n// node_modules/micromark-util-chunked/index.js\nfunction splice(list2, start, remove, items) {\n  const end = list2.length\n  let chunkStart = 0\n  let parameters\n  if (start < 0) {\n    start = -start > end ? 0 : end + start\n  } else {\n    start = start > end ? end : start\n  }\n  remove = remove > 0 ? remove : 0\n  if (items.length < 1e4) {\n    parameters = Array.from(items)\n    parameters.unshift(start, remove)\n    ;[].splice.apply(list2, parameters)\n  } else {\n    if (remove) [].splice.apply(list2, [start, remove])\n    while (chunkStart < items.length) {\n      parameters = items.slice(chunkStart, chunkStart + 1e4)\n      parameters.unshift(start, 0)\n      ;[].splice.apply(list2, parameters)\n      chunkStart += 1e4\n      start += 1e4\n    }\n  }\n}\nfunction push(list2, items) {\n  if (list2.length > 0) {\n    splice(list2, list2.length, 0, items)\n    return list2\n  }\n  return items\n}\n\n// node_modules/micromark-util-combine-extensions/index.js\nvar hasOwnProperty = {}.hasOwnProperty\nfunction combineExtensions(extensions) {\n  const all2 = {}\n  let index2 = -1\n  while (++index2 < extensions.length) {\n    syntaxExtension(all2, extensions[index2])\n  }\n  return all2\n}\nfunction syntaxExtension(all2, extension2) {\n  let hook\n  for (hook in extension2) {\n    const maybe = hasOwnProperty.call(all2, hook) ? all2[hook] : void 0\n    const left = maybe || (all2[hook] = {})\n    const right = extension2[hook]\n    let code\n    for (code in right) {\n      if (!hasOwnProperty.call(left, code)) left[code] = []\n      const value2 = right[code]\n      constructs(\n        left[code],\n        Array.isArray(value2) ? value2 : value2 ? [value2] : [],\n      )\n    }\n  }\n}\nfunction constructs(existing, list2) {\n  let index2 = -1\n  const before = []\n  while (++index2 < list2.length) {\n    ;(list2[index2].add === \"after\" ? existing : before).push(list2[index2])\n  }\n  splice(existing, 0, 0, before)\n}\n\n// node_modules/micromark-factory-space/index.js\nfunction factorySpace(effects, ok, type, max) {\n  const limit = max ? max - 1 : Number.POSITIVE_INFINITY\n  let size = 0\n  return start\n  function start(code) {\n    if (markdownSpace(code)) {\n      effects.enter(type)\n      return prefix(code)\n    }\n    return ok(code)\n  }\n  function prefix(code) {\n    if (markdownSpace(code) && size++ < limit) {\n      effects.consume(code)\n      return prefix\n    }\n    effects.exit(type)\n    return ok(code)\n  }\n}\n\n// node_modules/micromark/lib/initialize/content.js\nvar content = {\n  tokenize: initializeContent,\n}\nfunction initializeContent(effects) {\n  const contentStart = effects.attempt(\n    this.parser.constructs.contentInitial,\n    afterContentStartConstruct,\n    paragraphInitial,\n  )\n  let previous2\n  return contentStart\n  function afterContentStartConstruct(code) {\n    if (code === null) {\n      effects.consume(code)\n      return\n    }\n    effects.enter(\"lineEnding\")\n    effects.consume(code)\n    effects.exit(\"lineEnding\")\n    return factorySpace(effects, contentStart, \"linePrefix\")\n  }\n  function paragraphInitial(code) {\n    effects.enter(\"paragraph\")\n    return lineStart(code)\n  }\n  function lineStart(code) {\n    const token = effects.enter(\"chunkText\", {\n      contentType: \"text\",\n      previous: previous2,\n    })\n    if (previous2) {\n      previous2.next = token\n    }\n    previous2 = token\n    return data(code)\n  }\n  function data(code) {\n    if (code === null) {\n      effects.exit(\"chunkText\")\n      effects.exit(\"paragraph\")\n      effects.consume(code)\n      return\n    }\n    if (markdownLineEnding(code)) {\n      effects.consume(code)\n      effects.exit(\"chunkText\")\n      return lineStart\n    }\n    effects.consume(code)\n    return data\n  }\n}\n\n// node_modules/micromark/lib/initialize/document.js\nvar document2 = {\n  tokenize: initializeDocument,\n}\nvar containerConstruct = {\n  tokenize: tokenizeContainer,\n}\nfunction initializeDocument(effects) {\n  const self = this\n  const stack = []\n  let continued = 0\n  let childFlow\n  let childToken\n  let lineStartOffset\n  return start\n  function start(code) {\n    if (continued < stack.length) {\n      const item = stack[continued]\n      self.containerState = item[1]\n      return effects.attempt(\n        item[0].continuation,\n        documentContinue,\n        checkNewContainers,\n      )(code)\n    }\n    return checkNewContainers(code)\n  }\n  function documentContinue(code) {\n    continued++\n    if (self.containerState._closeFlow) {\n      self.containerState._closeFlow = void 0\n      if (childFlow) {\n        closeFlow()\n      }\n      const indexBeforeExits = self.events.length\n      let indexBeforeFlow = indexBeforeExits\n      let point2\n      while (indexBeforeFlow--) {\n        if (\n          self.events[indexBeforeFlow][0] === \"exit\" &&\n          self.events[indexBeforeFlow][1].type === \"chunkFlow\"\n        ) {\n          point2 = self.events[indexBeforeFlow][1].end\n          break\n        }\n      }\n      exitContainers(continued)\n      let index2 = indexBeforeExits\n      while (index2 < self.events.length) {\n        self.events[index2][1].end = Object.assign({}, point2)\n        index2++\n      }\n      splice(\n        self.events,\n        indexBeforeFlow + 1,\n        0,\n        self.events.slice(indexBeforeExits),\n      )\n      self.events.length = index2\n      return checkNewContainers(code)\n    }\n    return start(code)\n  }\n  function checkNewContainers(code) {\n    if (continued === stack.length) {\n      if (!childFlow) {\n        return documentContinued(code)\n      }\n      if (childFlow.currentConstruct && childFlow.currentConstruct.concrete) {\n        return flowStart(code)\n      }\n      self.interrupt = Boolean(childFlow.currentConstruct)\n    }\n    self.containerState = {}\n    return effects.check(\n      containerConstruct,\n      thereIsANewContainer,\n      thereIsNoNewContainer,\n    )(code)\n  }\n  function thereIsANewContainer(code) {\n    if (childFlow) closeFlow()\n    exitContainers(continued)\n    return documentContinued(code)\n  }\n  function thereIsNoNewContainer(code) {\n    self.parser.lazy[self.now().line] = continued !== stack.length\n    lineStartOffset = self.now().offset\n    return flowStart(code)\n  }\n  function documentContinued(code) {\n    self.containerState = {}\n    return effects.attempt(\n      containerConstruct,\n      containerContinue,\n      flowStart,\n    )(code)\n  }\n  function containerContinue(code) {\n    continued++\n    stack.push([self.currentConstruct, self.containerState])\n    return documentContinued(code)\n  }\n  function flowStart(code) {\n    if (code === null) {\n      if (childFlow) closeFlow()\n      exitContainers(0)\n      effects.consume(code)\n      return\n    }\n    childFlow = childFlow || self.parser.flow(self.now())\n    effects.enter(\"chunkFlow\", {\n      contentType: \"flow\",\n      previous: childToken,\n      _tokenizer: childFlow,\n    })\n    return flowContinue(code)\n  }\n  function flowContinue(code) {\n    if (code === null) {\n      writeToChild(effects.exit(\"chunkFlow\"), true)\n      exitContainers(0)\n      effects.consume(code)\n      return\n    }\n    if (markdownLineEnding(code)) {\n      effects.consume(code)\n      writeToChild(effects.exit(\"chunkFlow\"))\n      continued = 0\n      self.interrupt = void 0\n      return start\n    }\n    effects.consume(code)\n    return flowContinue\n  }\n  function writeToChild(token, eof) {\n    const stream = self.sliceStream(token)\n    if (eof) stream.push(null)\n    token.previous = childToken\n    if (childToken) childToken.next = token\n    childToken = token\n    childFlow.defineSkip(token.start)\n    childFlow.write(stream)\n    if (self.parser.lazy[token.start.line]) {\n      let index2 = childFlow.events.length\n      while (index2--) {\n        if (\n          childFlow.events[index2][1].start.offset < lineStartOffset &&\n          (!childFlow.events[index2][1].end ||\n            childFlow.events[index2][1].end.offset > lineStartOffset)\n        ) {\n          return\n        }\n      }\n      const indexBeforeExits = self.events.length\n      let indexBeforeFlow = indexBeforeExits\n      let seen\n      let point2\n      while (indexBeforeFlow--) {\n        if (\n          self.events[indexBeforeFlow][0] === \"exit\" &&\n          self.events[indexBeforeFlow][1].type === \"chunkFlow\"\n        ) {\n          if (seen) {\n            point2 = self.events[indexBeforeFlow][1].end\n            break\n          }\n          seen = true\n        }\n      }\n      exitContainers(continued)\n      index2 = indexBeforeExits\n      while (index2 < self.events.length) {\n        self.events[index2][1].end = Object.assign({}, point2)\n        index2++\n      }\n      splice(\n        self.events,\n        indexBeforeFlow + 1,\n        0,\n        self.events.slice(indexBeforeExits),\n      )\n      self.events.length = index2\n    }\n  }\n  function exitContainers(size) {\n    let index2 = stack.length\n    while (index2-- > size) {\n      const entry = stack[index2]\n      self.containerState = entry[1]\n      entry[0].exit.call(self, effects)\n    }\n    stack.length = size\n  }\n  function closeFlow() {\n    childFlow.write([null])\n    childToken = void 0\n    childFlow = void 0\n    self.containerState._closeFlow = void 0\n  }\n}\nfunction tokenizeContainer(effects, ok, nok) {\n  return factorySpace(\n    effects,\n    effects.attempt(this.parser.constructs.document, ok, nok),\n    \"linePrefix\",\n    this.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4,\n  )\n}\n\n// node_modules/micromark-util-classify-character/index.js\nfunction classifyCharacter(code) {\n  if (\n    code === null ||\n    markdownLineEndingOrSpace(code) ||\n    unicodeWhitespace(code)\n  ) {\n    return 1\n  }\n  if (unicodePunctuation(code)) {\n    return 2\n  }\n}\n\n// node_modules/micromark-util-resolve-all/index.js\nfunction resolveAll(constructs2, events, context) {\n  const called = []\n  let index2 = -1\n  while (++index2 < constructs2.length) {\n    const resolve = constructs2[index2].resolveAll\n    if (resolve && !called.includes(resolve)) {\n      events = resolve(events, context)\n      called.push(resolve)\n    }\n  }\n  return events\n}\n\n// node_modules/micromark-core-commonmark/lib/attention.js\nvar attention = {\n  name: \"attention\",\n  tokenize: tokenizeAttention,\n  resolveAll: resolveAllAttention,\n}\nfunction resolveAllAttention(events, context) {\n  let index2 = -1\n  let open\n  let group\n  let text3\n  let openingSequence\n  let closingSequence\n  let use\n  let nextEvents\n  let offset\n  while (++index2 < events.length) {\n    if (\n      events[index2][0] === \"enter\" &&\n      events[index2][1].type === \"attentionSequence\" &&\n      events[index2][1]._close\n    ) {\n      open = index2\n      while (open--) {\n        if (\n          events[open][0] === \"exit\" &&\n          events[open][1].type === \"attentionSequence\" &&\n          events[open][1]._open &&\n          context.sliceSerialize(events[open][1]).charCodeAt(0) ===\n            context.sliceSerialize(events[index2][1]).charCodeAt(0)\n        ) {\n          if (\n            (events[open][1]._close || events[index2][1]._open) &&\n            (events[index2][1].end.offset - events[index2][1].start.offset) %\n              3 &&\n            !(\n              (events[open][1].end.offset -\n                events[open][1].start.offset +\n                events[index2][1].end.offset -\n                events[index2][1].start.offset) %\n              3\n            )\n          ) {\n            continue\n          }\n          use =\n            events[open][1].end.offset - events[open][1].start.offset > 1 &&\n            events[index2][1].end.offset - events[index2][1].start.offset > 1\n              ? 2\n              : 1\n          const start = Object.assign({}, events[open][1].end)\n          const end = Object.assign({}, events[index2][1].start)\n          movePoint(start, -use)\n          movePoint(end, use)\n          openingSequence = {\n            type: use > 1 ? \"strongSequence\" : \"emphasisSequence\",\n            start,\n            end: Object.assign({}, events[open][1].end),\n          }\n          closingSequence = {\n            type: use > 1 ? \"strongSequence\" : \"emphasisSequence\",\n            start: Object.assign({}, events[index2][1].start),\n            end,\n          }\n          text3 = {\n            type: use > 1 ? \"strongText\" : \"emphasisText\",\n            start: Object.assign({}, events[open][1].end),\n            end: Object.assign({}, events[index2][1].start),\n          }\n          group = {\n            type: use > 1 ? \"strong\" : \"emphasis\",\n            start: Object.assign({}, openingSequence.start),\n            end: Object.assign({}, closingSequence.end),\n          }\n          events[open][1].end = Object.assign({}, openingSequence.start)\n          events[index2][1].start = Object.assign({}, closingSequence.end)\n          nextEvents = []\n          if (events[open][1].end.offset - events[open][1].start.offset) {\n            nextEvents = push(nextEvents, [\n              [\"enter\", events[open][1], context],\n              [\"exit\", events[open][1], context],\n            ])\n          }\n          nextEvents = push(nextEvents, [\n            [\"enter\", group, context],\n            [\"enter\", openingSequence, context],\n            [\"exit\", openingSequence, context],\n            [\"enter\", text3, context],\n          ])\n          nextEvents = push(\n            nextEvents,\n            resolveAll(\n              context.parser.constructs.insideSpan.null,\n              events.slice(open + 1, index2),\n              context,\n            ),\n          )\n          nextEvents = push(nextEvents, [\n            [\"exit\", text3, context],\n            [\"enter\", closingSequence, context],\n            [\"exit\", closingSequence, context],\n            [\"exit\", group, context],\n          ])\n          if (events[index2][1].end.offset - events[index2][1].start.offset) {\n            offset = 2\n            nextEvents = push(nextEvents, [\n              [\"enter\", events[index2][1], context],\n              [\"exit\", events[index2][1], context],\n            ])\n          } else {\n            offset = 0\n          }\n          splice(events, open - 1, index2 - open + 3, nextEvents)\n          index2 = open + nextEvents.length - offset - 2\n          break\n        }\n      }\n    }\n  }\n  index2 = -1\n  while (++index2 < events.length) {\n    if (events[index2][1].type === \"attentionSequence\") {\n      events[index2][1].type = \"data\"\n    }\n  }\n  return events\n}\nfunction tokenizeAttention(effects, ok) {\n  const attentionMarkers2 = this.parser.constructs.attentionMarkers.null\n  const previous2 = this.previous\n  const before = classifyCharacter(previous2)\n  let marker\n  return start\n  function start(code) {\n    effects.enter(\"attentionSequence\")\n    marker = code\n    return sequence(code)\n  }\n  function sequence(code) {\n    if (code === marker) {\n      effects.consume(code)\n      return sequence\n    }\n    const token = effects.exit(\"attentionSequence\")\n    const after = classifyCharacter(code)\n    const open =\n      !after || (after === 2 && before) || attentionMarkers2.includes(code)\n    const close2 =\n      !before ||\n      (before === 2 && after) ||\n      attentionMarkers2.includes(previous2)\n    token._open = Boolean(marker === 42 ? open : open && (before || !close2))\n    token._close = Boolean(marker === 42 ? close2 : close2 && (after || !open))\n    return ok(code)\n  }\n}\nfunction movePoint(point2, offset) {\n  point2.column += offset\n  point2.offset += offset\n  point2._bufferIndex += offset\n}\n\n// node_modules/micromark-core-commonmark/lib/autolink.js\nvar autolink = {\n  name: \"autolink\",\n  tokenize: tokenizeAutolink,\n}\nfunction tokenizeAutolink(effects, ok, nok) {\n  let size = 1\n  return start\n  function start(code) {\n    effects.enter(\"autolink\")\n    effects.enter(\"autolinkMarker\")\n    effects.consume(code)\n    effects.exit(\"autolinkMarker\")\n    effects.enter(\"autolinkProtocol\")\n    return open\n  }\n  function open(code) {\n    if (asciiAlpha(code)) {\n      effects.consume(code)\n      return schemeOrEmailAtext\n    }\n    return asciiAtext(code) ? emailAtext(code) : nok(code)\n  }\n  function schemeOrEmailAtext(code) {\n    return code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)\n      ? schemeInsideOrEmailAtext(code)\n      : emailAtext(code)\n  }\n  function schemeInsideOrEmailAtext(code) {\n    if (code === 58) {\n      effects.consume(code)\n      return urlInside\n    }\n    if (\n      (code === 43 || code === 45 || code === 46 || asciiAlphanumeric(code)) &&\n      size++ < 32\n    ) {\n      effects.consume(code)\n      return schemeInsideOrEmailAtext\n    }\n    return emailAtext(code)\n  }\n  function urlInside(code) {\n    if (code === 62) {\n      effects.exit(\"autolinkProtocol\")\n      return end(code)\n    }\n    if (code === null || code === 32 || code === 60 || asciiControl(code)) {\n      return nok(code)\n    }\n    effects.consume(code)\n    return urlInside\n  }\n  function emailAtext(code) {\n    if (code === 64) {\n      effects.consume(code)\n      size = 0\n      return emailAtSignOrDot\n    }\n    if (asciiAtext(code)) {\n      effects.consume(code)\n      return emailAtext\n    }\n    return nok(code)\n  }\n  function emailAtSignOrDot(code) {\n    return asciiAlphanumeric(code) ? emailLabel(code) : nok(code)\n  }\n  function emailLabel(code) {\n    if (code === 46) {\n      effects.consume(code)\n      size = 0\n      return emailAtSignOrDot\n    }\n    if (code === 62) {\n      effects.exit(\"autolinkProtocol\").type = \"autolinkEmail\"\n      return end(code)\n    }\n    return emailValue(code)\n  }\n  function emailValue(code) {\n    if ((code === 45 || asciiAlphanumeric(code)) && size++ < 63) {\n      effects.consume(code)\n      return code === 45 ? emailValue : emailLabel\n    }\n    return nok(code)\n  }\n  function end(code) {\n    effects.enter(\"autolinkMarker\")\n    effects.consume(code)\n    effects.exit(\"autolinkMarker\")\n    effects.exit(\"autolink\")\n    return ok\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/blank-line.js\nvar blankLine = {\n  tokenize: tokenizeBlankLine,\n  partial: true,\n}\nfunction tokenizeBlankLine(effects, ok, nok) {\n  return factorySpace(effects, afterWhitespace, \"linePrefix\")\n  function afterWhitespace(code) {\n    return code === null || markdownLineEnding(code) ? ok(code) : nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/block-quote.js\nvar blockQuote = {\n  name: \"blockQuote\",\n  tokenize: tokenizeBlockQuoteStart,\n  continuation: {\n    tokenize: tokenizeBlockQuoteContinuation,\n  },\n  exit,\n}\nfunction tokenizeBlockQuoteStart(effects, ok, nok) {\n  const self = this\n  return start\n  function start(code) {\n    if (code === 62) {\n      const state = self.containerState\n      if (!state.open) {\n        effects.enter(\"blockQuote\", {\n          _container: true,\n        })\n        state.open = true\n      }\n      effects.enter(\"blockQuotePrefix\")\n      effects.enter(\"blockQuoteMarker\")\n      effects.consume(code)\n      effects.exit(\"blockQuoteMarker\")\n      return after\n    }\n    return nok(code)\n  }\n  function after(code) {\n    if (markdownSpace(code)) {\n      effects.enter(\"blockQuotePrefixWhitespace\")\n      effects.consume(code)\n      effects.exit(\"blockQuotePrefixWhitespace\")\n      effects.exit(\"blockQuotePrefix\")\n      return ok\n    }\n    effects.exit(\"blockQuotePrefix\")\n    return ok(code)\n  }\n}\nfunction tokenizeBlockQuoteContinuation(effects, ok, nok) {\n  return factorySpace(\n    effects,\n    effects.attempt(blockQuote, ok, nok),\n    \"linePrefix\",\n    this.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4,\n  )\n}\nfunction exit(effects) {\n  effects.exit(\"blockQuote\")\n}\n\n// node_modules/micromark-core-commonmark/lib/character-escape.js\nvar characterEscape = {\n  name: \"characterEscape\",\n  tokenize: tokenizeCharacterEscape,\n}\nfunction tokenizeCharacterEscape(effects, ok, nok) {\n  return start\n  function start(code) {\n    effects.enter(\"characterEscape\")\n    effects.enter(\"escapeMarker\")\n    effects.consume(code)\n    effects.exit(\"escapeMarker\")\n    return open\n  }\n  function open(code) {\n    if (asciiPunctuation(code)) {\n      effects.enter(\"characterEscapeValue\")\n      effects.consume(code)\n      effects.exit(\"characterEscapeValue\")\n      effects.exit(\"characterEscape\")\n      return ok\n    }\n    return nok(code)\n  }\n}\n\n// node_modules/parse-entities/decode-entity.browser.js\nvar semicolon = 59\nvar element\nfunction decodeEntity(characters) {\n  var entity = \"&\" + characters + \";\"\n  var char\n  element = element || document.createElement(\"i\")\n  element.innerHTML = entity\n  char = element.textContent\n  if (char.charCodeAt(char.length - 1) === semicolon && characters !== \"semi\") {\n    return false\n  }\n  return char === entity ? false : char\n}\n\n// node_modules/micromark-core-commonmark/lib/character-reference.js\nvar characterReference = {\n  name: \"characterReference\",\n  tokenize: tokenizeCharacterReference,\n}\nfunction tokenizeCharacterReference(effects, ok, nok) {\n  const self = this\n  let size = 0\n  let max\n  let test\n  return start\n  function start(code) {\n    effects.enter(\"characterReference\")\n    effects.enter(\"characterReferenceMarker\")\n    effects.consume(code)\n    effects.exit(\"characterReferenceMarker\")\n    return open\n  }\n  function open(code) {\n    if (code === 35) {\n      effects.enter(\"characterReferenceMarkerNumeric\")\n      effects.consume(code)\n      effects.exit(\"characterReferenceMarkerNumeric\")\n      return numeric\n    }\n    effects.enter(\"characterReferenceValue\")\n    max = 31\n    test = asciiAlphanumeric\n    return value2(code)\n  }\n  function numeric(code) {\n    if (code === 88 || code === 120) {\n      effects.enter(\"characterReferenceMarkerHexadecimal\")\n      effects.consume(code)\n      effects.exit(\"characterReferenceMarkerHexadecimal\")\n      effects.enter(\"characterReferenceValue\")\n      max = 6\n      test = asciiHexDigit\n      return value2\n    }\n    effects.enter(\"characterReferenceValue\")\n    max = 7\n    test = asciiDigit\n    return value2(code)\n  }\n  function value2(code) {\n    let token\n    if (code === 59 && size) {\n      token = effects.exit(\"characterReferenceValue\")\n      if (\n        test === asciiAlphanumeric &&\n        !decodeEntity(self.sliceSerialize(token))\n      ) {\n        return nok(code)\n      }\n      effects.enter(\"characterReferenceMarker\")\n      effects.consume(code)\n      effects.exit(\"characterReferenceMarker\")\n      effects.exit(\"characterReference\")\n      return ok\n    }\n    if (test(code) && size++ < max) {\n      effects.consume(code)\n      return value2\n    }\n    return nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/code-fenced.js\nvar codeFenced = {\n  name: \"codeFenced\",\n  tokenize: tokenizeCodeFenced,\n  concrete: true,\n}\nfunction tokenizeCodeFenced(effects, ok, nok) {\n  const self = this\n  const closingFenceConstruct = {\n    tokenize: tokenizeClosingFence,\n    partial: true,\n  }\n  const nonLazyLine = {\n    tokenize: tokenizeNonLazyLine,\n    partial: true,\n  }\n  const tail = this.events[this.events.length - 1]\n  const initialPrefix =\n    tail && tail[1].type === \"linePrefix\"\n      ? tail[2].sliceSerialize(tail[1], true).length\n      : 0\n  let sizeOpen = 0\n  let marker\n  return start\n  function start(code) {\n    effects.enter(\"codeFenced\")\n    effects.enter(\"codeFencedFence\")\n    effects.enter(\"codeFencedFenceSequence\")\n    marker = code\n    return sequenceOpen(code)\n  }\n  function sequenceOpen(code) {\n    if (code === marker) {\n      effects.consume(code)\n      sizeOpen++\n      return sequenceOpen\n    }\n    effects.exit(\"codeFencedFenceSequence\")\n    return sizeOpen < 3\n      ? nok(code)\n      : factorySpace(effects, infoOpen, \"whitespace\")(code)\n  }\n  function infoOpen(code) {\n    if (code === null || markdownLineEnding(code)) {\n      return openAfter(code)\n    }\n    effects.enter(\"codeFencedFenceInfo\")\n    effects.enter(\"chunkString\", {\n      contentType: \"string\",\n    })\n    return info(code)\n  }\n  function info(code) {\n    if (code === null || markdownLineEndingOrSpace(code)) {\n      effects.exit(\"chunkString\")\n      effects.exit(\"codeFencedFenceInfo\")\n      return factorySpace(effects, infoAfter, \"whitespace\")(code)\n    }\n    if (code === 96 && code === marker) return nok(code)\n    effects.consume(code)\n    return info\n  }\n  function infoAfter(code) {\n    if (code === null || markdownLineEnding(code)) {\n      return openAfter(code)\n    }\n    effects.enter(\"codeFencedFenceMeta\")\n    effects.enter(\"chunkString\", {\n      contentType: \"string\",\n    })\n    return meta(code)\n  }\n  function meta(code) {\n    if (code === null || markdownLineEnding(code)) {\n      effects.exit(\"chunkString\")\n      effects.exit(\"codeFencedFenceMeta\")\n      return openAfter(code)\n    }\n    if (code === 96 && code === marker) return nok(code)\n    effects.consume(code)\n    return meta\n  }\n  function openAfter(code) {\n    effects.exit(\"codeFencedFence\")\n    return self.interrupt ? ok(code) : contentStart(code)\n  }\n  function contentStart(code) {\n    if (code === null) {\n      return after(code)\n    }\n    if (markdownLineEnding(code)) {\n      return effects.attempt(\n        nonLazyLine,\n        effects.attempt(\n          closingFenceConstruct,\n          after,\n          initialPrefix\n            ? factorySpace(\n                effects,\n                contentStart,\n                \"linePrefix\",\n                initialPrefix + 1,\n              )\n            : contentStart,\n        ),\n        after,\n      )(code)\n    }\n    effects.enter(\"codeFlowValue\")\n    return contentContinue(code)\n  }\n  function contentContinue(code) {\n    if (code === null || markdownLineEnding(code)) {\n      effects.exit(\"codeFlowValue\")\n      return contentStart(code)\n    }\n    effects.consume(code)\n    return contentContinue\n  }\n  function after(code) {\n    effects.exit(\"codeFenced\")\n    return ok(code)\n  }\n  function tokenizeNonLazyLine(effects2, ok2, nok2) {\n    const self2 = this\n    return start2\n    function start2(code) {\n      effects2.enter(\"lineEnding\")\n      effects2.consume(code)\n      effects2.exit(\"lineEnding\")\n      return lineStart\n    }\n    function lineStart(code) {\n      return self2.parser.lazy[self2.now().line] ? nok2(code) : ok2(code)\n    }\n  }\n  function tokenizeClosingFence(effects2, ok2, nok2) {\n    let size = 0\n    return factorySpace(\n      effects2,\n      closingSequenceStart,\n      \"linePrefix\",\n      this.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4,\n    )\n    function closingSequenceStart(code) {\n      effects2.enter(\"codeFencedFence\")\n      effects2.enter(\"codeFencedFenceSequence\")\n      return closingSequence(code)\n    }\n    function closingSequence(code) {\n      if (code === marker) {\n        effects2.consume(code)\n        size++\n        return closingSequence\n      }\n      if (size < sizeOpen) return nok2(code)\n      effects2.exit(\"codeFencedFenceSequence\")\n      return factorySpace(effects2, closingSequenceEnd, \"whitespace\")(code)\n    }\n    function closingSequenceEnd(code) {\n      if (code === null || markdownLineEnding(code)) {\n        effects2.exit(\"codeFencedFence\")\n        return ok2(code)\n      }\n      return nok2(code)\n    }\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/code-indented.js\nvar codeIndented = {\n  name: \"codeIndented\",\n  tokenize: tokenizeCodeIndented,\n}\nvar indentedContent = {\n  tokenize: tokenizeIndentedContent,\n  partial: true,\n}\nfunction tokenizeCodeIndented(effects, ok, nok) {\n  const self = this\n  return start\n  function start(code) {\n    effects.enter(\"codeIndented\")\n    return factorySpace(effects, afterStartPrefix, \"linePrefix\", 4 + 1)(code)\n  }\n  function afterStartPrefix(code) {\n    const tail = self.events[self.events.length - 1]\n    return tail &&\n      tail[1].type === \"linePrefix\" &&\n      tail[2].sliceSerialize(tail[1], true).length >= 4\n      ? afterPrefix(code)\n      : nok(code)\n  }\n  function afterPrefix(code) {\n    if (code === null) {\n      return after(code)\n    }\n    if (markdownLineEnding(code)) {\n      return effects.attempt(indentedContent, afterPrefix, after)(code)\n    }\n    effects.enter(\"codeFlowValue\")\n    return content3(code)\n  }\n  function content3(code) {\n    if (code === null || markdownLineEnding(code)) {\n      effects.exit(\"codeFlowValue\")\n      return afterPrefix(code)\n    }\n    effects.consume(code)\n    return content3\n  }\n  function after(code) {\n    effects.exit(\"codeIndented\")\n    return ok(code)\n  }\n}\nfunction tokenizeIndentedContent(effects, ok, nok) {\n  const self = this\n  return start\n  function start(code) {\n    if (self.parser.lazy[self.now().line]) {\n      return nok(code)\n    }\n    if (markdownLineEnding(code)) {\n      effects.enter(\"lineEnding\")\n      effects.consume(code)\n      effects.exit(\"lineEnding\")\n      return start\n    }\n    return factorySpace(effects, afterPrefix, \"linePrefix\", 4 + 1)(code)\n  }\n  function afterPrefix(code) {\n    const tail = self.events[self.events.length - 1]\n    return tail &&\n      tail[1].type === \"linePrefix\" &&\n      tail[2].sliceSerialize(tail[1], true).length >= 4\n      ? ok(code)\n      : markdownLineEnding(code)\n      ? start(code)\n      : nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/code-text.js\nvar codeText = {\n  name: \"codeText\",\n  tokenize: tokenizeCodeText,\n  resolve: resolveCodeText,\n  previous,\n}\nfunction resolveCodeText(events) {\n  let tailExitIndex = events.length - 4\n  let headEnterIndex = 3\n  let index2\n  let enter\n  if (\n    (events[headEnterIndex][1].type === \"lineEnding\" ||\n      events[headEnterIndex][1].type === \"space\") &&\n    (events[tailExitIndex][1].type === \"lineEnding\" ||\n      events[tailExitIndex][1].type === \"space\")\n  ) {\n    index2 = headEnterIndex\n    while (++index2 < tailExitIndex) {\n      if (events[index2][1].type === \"codeTextData\") {\n        events[headEnterIndex][1].type = \"codeTextPadding\"\n        events[tailExitIndex][1].type = \"codeTextPadding\"\n        headEnterIndex += 2\n        tailExitIndex -= 2\n        break\n      }\n    }\n  }\n  index2 = headEnterIndex - 1\n  tailExitIndex++\n  while (++index2 <= tailExitIndex) {\n    if (enter === void 0) {\n      if (index2 !== tailExitIndex && events[index2][1].type !== \"lineEnding\") {\n        enter = index2\n      }\n    } else if (\n      index2 === tailExitIndex ||\n      events[index2][1].type === \"lineEnding\"\n    ) {\n      events[enter][1].type = \"codeTextData\"\n      if (index2 !== enter + 2) {\n        events[enter][1].end = events[index2 - 1][1].end\n        events.splice(enter + 2, index2 - enter - 2)\n        tailExitIndex -= index2 - enter - 2\n        index2 = enter + 2\n      }\n      enter = void 0\n    }\n  }\n  return events\n}\nfunction previous(code) {\n  return (\n    code !== 96 ||\n    this.events[this.events.length - 1][1].type === \"characterEscape\"\n  )\n}\nfunction tokenizeCodeText(effects, ok, nok) {\n  const self = this\n  let sizeOpen = 0\n  let size\n  let token\n  return start\n  function start(code) {\n    effects.enter(\"codeText\")\n    effects.enter(\"codeTextSequence\")\n    return openingSequence(code)\n  }\n  function openingSequence(code) {\n    if (code === 96) {\n      effects.consume(code)\n      sizeOpen++\n      return openingSequence\n    }\n    effects.exit(\"codeTextSequence\")\n    return gap(code)\n  }\n  function gap(code) {\n    if (code === null) {\n      return nok(code)\n    }\n    if (code === 96) {\n      token = effects.enter(\"codeTextSequence\")\n      size = 0\n      return closingSequence(code)\n    }\n    if (code === 32) {\n      effects.enter(\"space\")\n      effects.consume(code)\n      effects.exit(\"space\")\n      return gap\n    }\n    if (markdownLineEnding(code)) {\n      effects.enter(\"lineEnding\")\n      effects.consume(code)\n      effects.exit(\"lineEnding\")\n      return gap\n    }\n    effects.enter(\"codeTextData\")\n    return data(code)\n  }\n  function data(code) {\n    if (\n      code === null ||\n      code === 32 ||\n      code === 96 ||\n      markdownLineEnding(code)\n    ) {\n      effects.exit(\"codeTextData\")\n      return gap(code)\n    }\n    effects.consume(code)\n    return data\n  }\n  function closingSequence(code) {\n    if (code === 96) {\n      effects.consume(code)\n      size++\n      return closingSequence\n    }\n    if (size === sizeOpen) {\n      effects.exit(\"codeTextSequence\")\n      effects.exit(\"codeText\")\n      return ok(code)\n    }\n    token.type = \"codeTextData\"\n    return data(code)\n  }\n}\n\n// node_modules/micromark-util-subtokenize/index.js\nfunction subtokenize(events) {\n  const jumps = {}\n  let index2 = -1\n  let event\n  let lineIndex\n  let otherIndex\n  let otherEvent\n  let parameters\n  let subevents\n  let more\n  while (++index2 < events.length) {\n    while (index2 in jumps) {\n      index2 = jumps[index2]\n    }\n    event = events[index2]\n    if (\n      index2 &&\n      event[1].type === \"chunkFlow\" &&\n      events[index2 - 1][1].type === \"listItemPrefix\"\n    ) {\n      subevents = event[1]._tokenizer.events\n      otherIndex = 0\n      if (\n        otherIndex < subevents.length &&\n        subevents[otherIndex][1].type === \"lineEndingBlank\"\n      ) {\n        otherIndex += 2\n      }\n      if (\n        otherIndex < subevents.length &&\n        subevents[otherIndex][1].type === \"content\"\n      ) {\n        while (++otherIndex < subevents.length) {\n          if (subevents[otherIndex][1].type === \"content\") {\n            break\n          }\n          if (subevents[otherIndex][1].type === \"chunkText\") {\n            subevents[otherIndex][1]._isInFirstContentOfListItem = true\n            otherIndex++\n          }\n        }\n      }\n    }\n    if (event[0] === \"enter\") {\n      if (event[1].contentType) {\n        Object.assign(jumps, subcontent(events, index2))\n        index2 = jumps[index2]\n        more = true\n      }\n    } else if (event[1]._container) {\n      otherIndex = index2\n      lineIndex = void 0\n      while (otherIndex--) {\n        otherEvent = events[otherIndex]\n        if (\n          otherEvent[1].type === \"lineEnding\" ||\n          otherEvent[1].type === \"lineEndingBlank\"\n        ) {\n          if (otherEvent[0] === \"enter\") {\n            if (lineIndex) {\n              events[lineIndex][1].type = \"lineEndingBlank\"\n            }\n            otherEvent[1].type = \"lineEnding\"\n            lineIndex = otherIndex\n          }\n        } else {\n          break\n        }\n      }\n      if (lineIndex) {\n        event[1].end = Object.assign({}, events[lineIndex][1].start)\n        parameters = events.slice(lineIndex, index2)\n        parameters.unshift(event)\n        splice(events, lineIndex, index2 - lineIndex + 1, parameters)\n      }\n    }\n  }\n  return !more\n}\nfunction subcontent(events, eventIndex) {\n  const token = events[eventIndex][1]\n  const context = events[eventIndex][2]\n  let startPosition = eventIndex - 1\n  const startPositions = []\n  const tokenizer =\n    token._tokenizer || context.parser[token.contentType](token.start)\n  const childEvents = tokenizer.events\n  const jumps = []\n  const gaps = {}\n  let stream\n  let previous2\n  let index2 = -1\n  let current = token\n  let adjust = 0\n  let start = 0\n  const breaks = [start]\n  while (current) {\n    while (events[++startPosition][1] !== current) {}\n    startPositions.push(startPosition)\n    if (!current._tokenizer) {\n      stream = context.sliceStream(current)\n      if (!current.next) {\n        stream.push(null)\n      }\n      if (previous2) {\n        tokenizer.defineSkip(current.start)\n      }\n      if (current._isInFirstContentOfListItem) {\n        tokenizer._gfmTasklistFirstContentOfListItem = true\n      }\n      tokenizer.write(stream)\n      if (current._isInFirstContentOfListItem) {\n        tokenizer._gfmTasklistFirstContentOfListItem = void 0\n      }\n    }\n    previous2 = current\n    current = current.next\n  }\n  current = token\n  while (++index2 < childEvents.length) {\n    if (\n      childEvents[index2][0] === \"exit\" &&\n      childEvents[index2 - 1][0] === \"enter\" &&\n      childEvents[index2][1].type === childEvents[index2 - 1][1].type &&\n      childEvents[index2][1].start.line !== childEvents[index2][1].end.line\n    ) {\n      start = index2 + 1\n      breaks.push(start)\n      current._tokenizer = void 0\n      current.previous = void 0\n      current = current.next\n    }\n  }\n  tokenizer.events = []\n  if (current) {\n    current._tokenizer = void 0\n    current.previous = void 0\n  } else {\n    breaks.pop()\n  }\n  index2 = breaks.length\n  while (index2--) {\n    const slice = childEvents.slice(breaks[index2], breaks[index2 + 1])\n    const start2 = startPositions.pop()\n    jumps.unshift([start2, start2 + slice.length - 1])\n    splice(events, start2, 2, slice)\n  }\n  index2 = -1\n  while (++index2 < jumps.length) {\n    gaps[adjust + jumps[index2][0]] = adjust + jumps[index2][1]\n    adjust += jumps[index2][1] - jumps[index2][0] - 1\n  }\n  return gaps\n}\n\n// node_modules/micromark-core-commonmark/lib/content.js\nvar content2 = {\n  tokenize: tokenizeContent,\n  resolve: resolveContent,\n}\nvar continuationConstruct = {\n  tokenize: tokenizeContinuation,\n  partial: true,\n}\nfunction resolveContent(events) {\n  subtokenize(events)\n  return events\n}\nfunction tokenizeContent(effects, ok) {\n  let previous2\n  return start\n  function start(code) {\n    effects.enter(\"content\")\n    previous2 = effects.enter(\"chunkContent\", {\n      contentType: \"content\",\n    })\n    return data(code)\n  }\n  function data(code) {\n    if (code === null) {\n      return contentEnd(code)\n    }\n    if (markdownLineEnding(code)) {\n      return effects.check(\n        continuationConstruct,\n        contentContinue,\n        contentEnd,\n      )(code)\n    }\n    effects.consume(code)\n    return data\n  }\n  function contentEnd(code) {\n    effects.exit(\"chunkContent\")\n    effects.exit(\"content\")\n    return ok(code)\n  }\n  function contentContinue(code) {\n    effects.consume(code)\n    effects.exit(\"chunkContent\")\n    previous2.next = effects.enter(\"chunkContent\", {\n      contentType: \"content\",\n      previous: previous2,\n    })\n    previous2 = previous2.next\n    return data\n  }\n}\nfunction tokenizeContinuation(effects, ok, nok) {\n  const self = this\n  return startLookahead\n  function startLookahead(code) {\n    effects.exit(\"chunkContent\")\n    effects.enter(\"lineEnding\")\n    effects.consume(code)\n    effects.exit(\"lineEnding\")\n    return factorySpace(effects, prefixed, \"linePrefix\")\n  }\n  function prefixed(code) {\n    if (code === null || markdownLineEnding(code)) {\n      return nok(code)\n    }\n    const tail = self.events[self.events.length - 1]\n    if (\n      !self.parser.constructs.disable.null.includes(\"codeIndented\") &&\n      tail &&\n      tail[1].type === \"linePrefix\" &&\n      tail[2].sliceSerialize(tail[1], true).length >= 4\n    ) {\n      return ok(code)\n    }\n    return effects.interrupt(self.parser.constructs.flow, nok, ok)(code)\n  }\n}\n\n// node_modules/micromark-factory-destination/index.js\nfunction factoryDestination(\n  effects,\n  ok,\n  nok,\n  type,\n  literalType,\n  literalMarkerType,\n  rawType,\n  stringType,\n  max,\n) {\n  const limit = max || Number.POSITIVE_INFINITY\n  let balance = 0\n  return start\n  function start(code) {\n    if (code === 60) {\n      effects.enter(type)\n      effects.enter(literalType)\n      effects.enter(literalMarkerType)\n      effects.consume(code)\n      effects.exit(literalMarkerType)\n      return destinationEnclosedBefore\n    }\n    if (code === null || code === 41 || asciiControl(code)) {\n      return nok(code)\n    }\n    effects.enter(type)\n    effects.enter(rawType)\n    effects.enter(stringType)\n    effects.enter(\"chunkString\", {\n      contentType: \"string\",\n    })\n    return destinationRaw(code)\n  }\n  function destinationEnclosedBefore(code) {\n    if (code === 62) {\n      effects.enter(literalMarkerType)\n      effects.consume(code)\n      effects.exit(literalMarkerType)\n      effects.exit(literalType)\n      effects.exit(type)\n      return ok\n    }\n    effects.enter(stringType)\n    effects.enter(\"chunkString\", {\n      contentType: \"string\",\n    })\n    return destinationEnclosed(code)\n  }\n  function destinationEnclosed(code) {\n    if (code === 62) {\n      effects.exit(\"chunkString\")\n      effects.exit(stringType)\n      return destinationEnclosedBefore(code)\n    }\n    if (code === null || code === 60 || markdownLineEnding(code)) {\n      return nok(code)\n    }\n    effects.consume(code)\n    return code === 92 ? destinationEnclosedEscape : destinationEnclosed\n  }\n  function destinationEnclosedEscape(code) {\n    if (code === 60 || code === 62 || code === 92) {\n      effects.consume(code)\n      return destinationEnclosed\n    }\n    return destinationEnclosed(code)\n  }\n  function destinationRaw(code) {\n    if (code === 40) {\n      if (++balance > limit) return nok(code)\n      effects.consume(code)\n      return destinationRaw\n    }\n    if (code === 41) {\n      if (!balance--) {\n        effects.exit(\"chunkString\")\n        effects.exit(stringType)\n        effects.exit(rawType)\n        effects.exit(type)\n        return ok(code)\n      }\n      effects.consume(code)\n      return destinationRaw\n    }\n    if (code === null || markdownLineEndingOrSpace(code)) {\n      if (balance) return nok(code)\n      effects.exit(\"chunkString\")\n      effects.exit(stringType)\n      effects.exit(rawType)\n      effects.exit(type)\n      return ok(code)\n    }\n    if (asciiControl(code)) return nok(code)\n    effects.consume(code)\n    return code === 92 ? destinationRawEscape : destinationRaw\n  }\n  function destinationRawEscape(code) {\n    if (code === 40 || code === 41 || code === 92) {\n      effects.consume(code)\n      return destinationRaw\n    }\n    return destinationRaw(code)\n  }\n}\n\n// node_modules/micromark-factory-label/index.js\nfunction factoryLabel(effects, ok, nok, type, markerType, stringType) {\n  const self = this\n  let size = 0\n  let data\n  return start\n  function start(code) {\n    effects.enter(type)\n    effects.enter(markerType)\n    effects.consume(code)\n    effects.exit(markerType)\n    effects.enter(stringType)\n    return atBreak\n  }\n  function atBreak(code) {\n    if (\n      code === null ||\n      code === 91 ||\n      (code === 93 && !data) ||\n      (code === 94 &&\n        !size &&\n        \"_hiddenFootnoteSupport\" in self.parser.constructs) ||\n      size > 999\n    ) {\n      return nok(code)\n    }\n    if (code === 93) {\n      effects.exit(stringType)\n      effects.enter(markerType)\n      effects.consume(code)\n      effects.exit(markerType)\n      effects.exit(type)\n      return ok\n    }\n    if (markdownLineEnding(code)) {\n      effects.enter(\"lineEnding\")\n      effects.consume(code)\n      effects.exit(\"lineEnding\")\n      return atBreak\n    }\n    effects.enter(\"chunkString\", {\n      contentType: \"string\",\n    })\n    return label(code)\n  }\n  function label(code) {\n    if (\n      code === null ||\n      code === 91 ||\n      code === 93 ||\n      markdownLineEnding(code) ||\n      size++ > 999\n    ) {\n      effects.exit(\"chunkString\")\n      return atBreak(code)\n    }\n    effects.consume(code)\n    data = data || !markdownSpace(code)\n    return code === 92 ? labelEscape : label\n  }\n  function labelEscape(code) {\n    if (code === 91 || code === 92 || code === 93) {\n      effects.consume(code)\n      size++\n      return label\n    }\n    return label(code)\n  }\n}\n\n// node_modules/micromark-factory-title/index.js\nfunction factoryTitle(effects, ok, nok, type, markerType, stringType) {\n  let marker\n  return start\n  function start(code) {\n    effects.enter(type)\n    effects.enter(markerType)\n    effects.consume(code)\n    effects.exit(markerType)\n    marker = code === 40 ? 41 : code\n    return atFirstTitleBreak\n  }\n  function atFirstTitleBreak(code) {\n    if (code === marker) {\n      effects.enter(markerType)\n      effects.consume(code)\n      effects.exit(markerType)\n      effects.exit(type)\n      return ok\n    }\n    effects.enter(stringType)\n    return atTitleBreak(code)\n  }\n  function atTitleBreak(code) {\n    if (code === marker) {\n      effects.exit(stringType)\n      return atFirstTitleBreak(marker)\n    }\n    if (code === null) {\n      return nok(code)\n    }\n    if (markdownLineEnding(code)) {\n      effects.enter(\"lineEnding\")\n      effects.consume(code)\n      effects.exit(\"lineEnding\")\n      return factorySpace(effects, atTitleBreak, \"linePrefix\")\n    }\n    effects.enter(\"chunkString\", {\n      contentType: \"string\",\n    })\n    return title(code)\n  }\n  function title(code) {\n    if (code === marker || code === null || markdownLineEnding(code)) {\n      effects.exit(\"chunkString\")\n      return atTitleBreak(code)\n    }\n    effects.consume(code)\n    return code === 92 ? titleEscape : title\n  }\n  function titleEscape(code) {\n    if (code === marker || code === 92) {\n      effects.consume(code)\n      return title\n    }\n    return title(code)\n  }\n}\n\n// node_modules/micromark-factory-whitespace/index.js\nfunction factoryWhitespace(effects, ok) {\n  let seen\n  return start\n  function start(code) {\n    if (markdownLineEnding(code)) {\n      effects.enter(\"lineEnding\")\n      effects.consume(code)\n      effects.exit(\"lineEnding\")\n      seen = true\n      return start\n    }\n    if (markdownSpace(code)) {\n      return factorySpace(\n        effects,\n        start,\n        seen ? \"linePrefix\" : \"lineSuffix\",\n      )(code)\n    }\n    return ok(code)\n  }\n}\n\n// node_modules/micromark-util-normalize-identifier/index.js\nfunction normalizeIdentifier(value2) {\n  return value2\n    .replace(/[\\t\\n\\r ]+/g, \" \")\n    .replace(/^ | $/g, \"\")\n    .toLowerCase()\n    .toUpperCase()\n}\n\n// node_modules/micromark-core-commonmark/lib/definition.js\nvar definition = {\n  name: \"definition\",\n  tokenize: tokenizeDefinition,\n}\nvar titleConstruct = {\n  tokenize: tokenizeTitle,\n  partial: true,\n}\nfunction tokenizeDefinition(effects, ok, nok) {\n  const self = this\n  let identifier\n  return start\n  function start(code) {\n    effects.enter(\"definition\")\n    return factoryLabel.call(\n      self,\n      effects,\n      labelAfter,\n      nok,\n      \"definitionLabel\",\n      \"definitionLabelMarker\",\n      \"definitionLabelString\",\n    )(code)\n  }\n  function labelAfter(code) {\n    identifier = normalizeIdentifier(\n      self.sliceSerialize(self.events[self.events.length - 1][1]).slice(1, -1),\n    )\n    if (code === 58) {\n      effects.enter(\"definitionMarker\")\n      effects.consume(code)\n      effects.exit(\"definitionMarker\")\n      return factoryWhitespace(\n        effects,\n        factoryDestination(\n          effects,\n          effects.attempt(\n            titleConstruct,\n            factorySpace(effects, after, \"whitespace\"),\n            factorySpace(effects, after, \"whitespace\"),\n          ),\n          nok,\n          \"definitionDestination\",\n          \"definitionDestinationLiteral\",\n          \"definitionDestinationLiteralMarker\",\n          \"definitionDestinationRaw\",\n          \"definitionDestinationString\",\n        ),\n      )\n    }\n    return nok(code)\n  }\n  function after(code) {\n    if (code === null || markdownLineEnding(code)) {\n      effects.exit(\"definition\")\n      if (!self.parser.defined.includes(identifier)) {\n        self.parser.defined.push(identifier)\n      }\n      return ok(code)\n    }\n    return nok(code)\n  }\n}\nfunction tokenizeTitle(effects, ok, nok) {\n  return start\n  function start(code) {\n    return markdownLineEndingOrSpace(code)\n      ? factoryWhitespace(effects, before)(code)\n      : nok(code)\n  }\n  function before(code) {\n    if (code === 34 || code === 39 || code === 40) {\n      return factoryTitle(\n        effects,\n        factorySpace(effects, after, \"whitespace\"),\n        nok,\n        \"definitionTitle\",\n        \"definitionTitleMarker\",\n        \"definitionTitleString\",\n      )(code)\n    }\n    return nok(code)\n  }\n  function after(code) {\n    return code === null || markdownLineEnding(code) ? ok(code) : nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/hard-break-escape.js\nvar hardBreakEscape = {\n  name: \"hardBreakEscape\",\n  tokenize: tokenizeHardBreakEscape,\n}\nfunction tokenizeHardBreakEscape(effects, ok, nok) {\n  return start\n  function start(code) {\n    effects.enter(\"hardBreakEscape\")\n    effects.enter(\"escapeMarker\")\n    effects.consume(code)\n    return open\n  }\n  function open(code) {\n    if (markdownLineEnding(code)) {\n      effects.exit(\"escapeMarker\")\n      effects.exit(\"hardBreakEscape\")\n      return ok(code)\n    }\n    return nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/heading-atx.js\nvar headingAtx = {\n  name: \"headingAtx\",\n  tokenize: tokenizeHeadingAtx,\n  resolve: resolveHeadingAtx,\n}\nfunction resolveHeadingAtx(events, context) {\n  let contentEnd = events.length - 2\n  let contentStart = 3\n  let content3\n  let text3\n  if (events[contentStart][1].type === \"whitespace\") {\n    contentStart += 2\n  }\n  if (\n    contentEnd - 2 > contentStart &&\n    events[contentEnd][1].type === \"whitespace\"\n  ) {\n    contentEnd -= 2\n  }\n  if (\n    events[contentEnd][1].type === \"atxHeadingSequence\" &&\n    (contentStart === contentEnd - 1 ||\n      (contentEnd - 4 > contentStart &&\n        events[contentEnd - 2][1].type === \"whitespace\"))\n  ) {\n    contentEnd -= contentStart + 1 === contentEnd ? 2 : 4\n  }\n  if (contentEnd > contentStart) {\n    content3 = {\n      type: \"atxHeadingText\",\n      start: events[contentStart][1].start,\n      end: events[contentEnd][1].end,\n    }\n    text3 = {\n      type: \"chunkText\",\n      start: events[contentStart][1].start,\n      end: events[contentEnd][1].end,\n      contentType: \"text\",\n    }\n    splice(events, contentStart, contentEnd - contentStart + 1, [\n      [\"enter\", content3, context],\n      [\"enter\", text3, context],\n      [\"exit\", text3, context],\n      [\"exit\", content3, context],\n    ])\n  }\n  return events\n}\nfunction tokenizeHeadingAtx(effects, ok, nok) {\n  const self = this\n  let size = 0\n  return start\n  function start(code) {\n    effects.enter(\"atxHeading\")\n    effects.enter(\"atxHeadingSequence\")\n    return fenceOpenInside(code)\n  }\n  function fenceOpenInside(code) {\n    if (code === 35 && size++ < 6) {\n      effects.consume(code)\n      return fenceOpenInside\n    }\n    if (code === null || markdownLineEndingOrSpace(code)) {\n      effects.exit(\"atxHeadingSequence\")\n      return self.interrupt ? ok(code) : headingBreak(code)\n    }\n    return nok(code)\n  }\n  function headingBreak(code) {\n    if (code === 35) {\n      effects.enter(\"atxHeadingSequence\")\n      return sequence(code)\n    }\n    if (code === null || markdownLineEnding(code)) {\n      effects.exit(\"atxHeading\")\n      return ok(code)\n    }\n    if (markdownSpace(code)) {\n      return factorySpace(effects, headingBreak, \"whitespace\")(code)\n    }\n    effects.enter(\"atxHeadingText\")\n    return data(code)\n  }\n  function sequence(code) {\n    if (code === 35) {\n      effects.consume(code)\n      return sequence\n    }\n    effects.exit(\"atxHeadingSequence\")\n    return headingBreak(code)\n  }\n  function data(code) {\n    if (code === null || code === 35 || markdownLineEndingOrSpace(code)) {\n      effects.exit(\"atxHeadingText\")\n      return headingBreak(code)\n    }\n    effects.consume(code)\n    return data\n  }\n}\n\n// node_modules/micromark-util-html-tag-name/index.js\nvar htmlBlockNames = [\n  \"address\",\n  \"article\",\n  \"aside\",\n  \"base\",\n  \"basefont\",\n  \"blockquote\",\n  \"body\",\n  \"caption\",\n  \"center\",\n  \"col\",\n  \"colgroup\",\n  \"dd\",\n  \"details\",\n  \"dialog\",\n  \"dir\",\n  \"div\",\n  \"dl\",\n  \"dt\",\n  \"fieldset\",\n  \"figcaption\",\n  \"figure\",\n  \"footer\",\n  \"form\",\n  \"frame\",\n  \"frameset\",\n  \"h1\",\n  \"h2\",\n  \"h3\",\n  \"h4\",\n  \"h5\",\n  \"h6\",\n  \"head\",\n  \"header\",\n  \"hr\",\n  \"html\",\n  \"iframe\",\n  \"legend\",\n  \"li\",\n  \"link\",\n  \"main\",\n  \"menu\",\n  \"menuitem\",\n  \"nav\",\n  \"noframes\",\n  \"ol\",\n  \"optgroup\",\n  \"option\",\n  \"p\",\n  \"param\",\n  \"section\",\n  \"source\",\n  \"summary\",\n  \"table\",\n  \"tbody\",\n  \"td\",\n  \"tfoot\",\n  \"th\",\n  \"thead\",\n  \"title\",\n  \"tr\",\n  \"track\",\n  \"ul\",\n]\nvar htmlRawNames = [\"pre\", \"script\", \"style\", \"textarea\"]\n\n// node_modules/micromark-core-commonmark/lib/html-flow.js\nvar htmlFlow = {\n  name: \"htmlFlow\",\n  tokenize: tokenizeHtmlFlow,\n  resolveTo: resolveToHtmlFlow,\n  concrete: true,\n}\nvar nextBlankConstruct = {\n  tokenize: tokenizeNextBlank,\n  partial: true,\n}\nfunction resolveToHtmlFlow(events) {\n  let index2 = events.length\n  while (index2--) {\n    if (\n      events[index2][0] === \"enter\" &&\n      events[index2][1].type === \"htmlFlow\"\n    ) {\n      break\n    }\n  }\n  if (index2 > 1 && events[index2 - 2][1].type === \"linePrefix\") {\n    events[index2][1].start = events[index2 - 2][1].start\n    events[index2 + 1][1].start = events[index2 - 2][1].start\n    events.splice(index2 - 2, 2)\n  }\n  return events\n}\nfunction tokenizeHtmlFlow(effects, ok, nok) {\n  const self = this\n  let kind\n  let startTag\n  let buffer2\n  let index2\n  let marker\n  return start\n  function start(code) {\n    effects.enter(\"htmlFlow\")\n    effects.enter(\"htmlFlowData\")\n    effects.consume(code)\n    return open\n  }\n  function open(code) {\n    if (code === 33) {\n      effects.consume(code)\n      return declarationStart\n    }\n    if (code === 47) {\n      effects.consume(code)\n      return tagCloseStart\n    }\n    if (code === 63) {\n      effects.consume(code)\n      kind = 3\n      return self.interrupt ? ok : continuationDeclarationInside\n    }\n    if (asciiAlpha(code)) {\n      effects.consume(code)\n      buffer2 = String.fromCharCode(code)\n      startTag = true\n      return tagName\n    }\n    return nok(code)\n  }\n  function declarationStart(code) {\n    if (code === 45) {\n      effects.consume(code)\n      kind = 2\n      return commentOpenInside\n    }\n    if (code === 91) {\n      effects.consume(code)\n      kind = 5\n      buffer2 = \"CDATA[\"\n      index2 = 0\n      return cdataOpenInside\n    }\n    if (asciiAlpha(code)) {\n      effects.consume(code)\n      kind = 4\n      return self.interrupt ? ok : continuationDeclarationInside\n    }\n    return nok(code)\n  }\n  function commentOpenInside(code) {\n    if (code === 45) {\n      effects.consume(code)\n      return self.interrupt ? ok : continuationDeclarationInside\n    }\n    return nok(code)\n  }\n  function cdataOpenInside(code) {\n    if (code === buffer2.charCodeAt(index2++)) {\n      effects.consume(code)\n      return index2 === buffer2.length\n        ? self.interrupt\n          ? ok\n          : continuation\n        : cdataOpenInside\n    }\n    return nok(code)\n  }\n  function tagCloseStart(code) {\n    if (asciiAlpha(code)) {\n      effects.consume(code)\n      buffer2 = String.fromCharCode(code)\n      return tagName\n    }\n    return nok(code)\n  }\n  function tagName(code) {\n    if (\n      code === null ||\n      code === 47 ||\n      code === 62 ||\n      markdownLineEndingOrSpace(code)\n    ) {\n      if (\n        code !== 47 &&\n        startTag &&\n        htmlRawNames.includes(buffer2.toLowerCase())\n      ) {\n        kind = 1\n        return self.interrupt ? ok(code) : continuation(code)\n      }\n      if (htmlBlockNames.includes(buffer2.toLowerCase())) {\n        kind = 6\n        if (code === 47) {\n          effects.consume(code)\n          return basicSelfClosing\n        }\n        return self.interrupt ? ok(code) : continuation(code)\n      }\n      kind = 7\n      return self.interrupt && !self.parser.lazy[self.now().line]\n        ? nok(code)\n        : startTag\n        ? completeAttributeNameBefore(code)\n        : completeClosingTagAfter(code)\n    }\n    if (code === 45 || asciiAlphanumeric(code)) {\n      effects.consume(code)\n      buffer2 += String.fromCharCode(code)\n      return tagName\n    }\n    return nok(code)\n  }\n  function basicSelfClosing(code) {\n    if (code === 62) {\n      effects.consume(code)\n      return self.interrupt ? ok : continuation\n    }\n    return nok(code)\n  }\n  function completeClosingTagAfter(code) {\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return completeClosingTagAfter\n    }\n    return completeEnd(code)\n  }\n  function completeAttributeNameBefore(code) {\n    if (code === 47) {\n      effects.consume(code)\n      return completeEnd\n    }\n    if (code === 58 || code === 95 || asciiAlpha(code)) {\n      effects.consume(code)\n      return completeAttributeName\n    }\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return completeAttributeNameBefore\n    }\n    return completeEnd(code)\n  }\n  function completeAttributeName(code) {\n    if (\n      code === 45 ||\n      code === 46 ||\n      code === 58 ||\n      code === 95 ||\n      asciiAlphanumeric(code)\n    ) {\n      effects.consume(code)\n      return completeAttributeName\n    }\n    return completeAttributeNameAfter(code)\n  }\n  function completeAttributeNameAfter(code) {\n    if (code === 61) {\n      effects.consume(code)\n      return completeAttributeValueBefore\n    }\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return completeAttributeNameAfter\n    }\n    return completeAttributeNameBefore(code)\n  }\n  function completeAttributeValueBefore(code) {\n    if (\n      code === null ||\n      code === 60 ||\n      code === 61 ||\n      code === 62 ||\n      code === 96\n    ) {\n      return nok(code)\n    }\n    if (code === 34 || code === 39) {\n      effects.consume(code)\n      marker = code\n      return completeAttributeValueQuoted\n    }\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return completeAttributeValueBefore\n    }\n    marker = null\n    return completeAttributeValueUnquoted(code)\n  }\n  function completeAttributeValueQuoted(code) {\n    if (code === null || markdownLineEnding(code)) {\n      return nok(code)\n    }\n    if (code === marker) {\n      effects.consume(code)\n      return completeAttributeValueQuotedAfter\n    }\n    effects.consume(code)\n    return completeAttributeValueQuoted\n  }\n  function completeAttributeValueUnquoted(code) {\n    if (\n      code === null ||\n      code === 34 ||\n      code === 39 ||\n      code === 60 ||\n      code === 61 ||\n      code === 62 ||\n      code === 96 ||\n      markdownLineEndingOrSpace(code)\n    ) {\n      return completeAttributeNameAfter(code)\n    }\n    effects.consume(code)\n    return completeAttributeValueUnquoted\n  }\n  function completeAttributeValueQuotedAfter(code) {\n    if (code === 47 || code === 62 || markdownSpace(code)) {\n      return completeAttributeNameBefore(code)\n    }\n    return nok(code)\n  }\n  function completeEnd(code) {\n    if (code === 62) {\n      effects.consume(code)\n      return completeAfter\n    }\n    return nok(code)\n  }\n  function completeAfter(code) {\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return completeAfter\n    }\n    return code === null || markdownLineEnding(code)\n      ? continuation(code)\n      : nok(code)\n  }\n  function continuation(code) {\n    if (code === 45 && kind === 2) {\n      effects.consume(code)\n      return continuationCommentInside\n    }\n    if (code === 60 && kind === 1) {\n      effects.consume(code)\n      return continuationRawTagOpen\n    }\n    if (code === 62 && kind === 4) {\n      effects.consume(code)\n      return continuationClose\n    }\n    if (code === 63 && kind === 3) {\n      effects.consume(code)\n      return continuationDeclarationInside\n    }\n    if (code === 93 && kind === 5) {\n      effects.consume(code)\n      return continuationCharacterDataInside\n    }\n    if (markdownLineEnding(code) && (kind === 6 || kind === 7)) {\n      return effects.check(\n        nextBlankConstruct,\n        continuationClose,\n        continuationAtLineEnding,\n      )(code)\n    }\n    if (code === null || markdownLineEnding(code)) {\n      return continuationAtLineEnding(code)\n    }\n    effects.consume(code)\n    return continuation\n  }\n  function continuationAtLineEnding(code) {\n    effects.exit(\"htmlFlowData\")\n    return htmlContinueStart(code)\n  }\n  function htmlContinueStart(code) {\n    if (code === null) {\n      return done(code)\n    }\n    if (markdownLineEnding(code)) {\n      return effects.attempt(\n        {\n          tokenize: htmlLineEnd,\n          partial: true,\n        },\n        htmlContinueStart,\n        done,\n      )(code)\n    }\n    effects.enter(\"htmlFlowData\")\n    return continuation(code)\n  }\n  function htmlLineEnd(effects2, ok2, nok2) {\n    return start2\n    function start2(code) {\n      effects2.enter(\"lineEnding\")\n      effects2.consume(code)\n      effects2.exit(\"lineEnding\")\n      return lineStart\n    }\n    function lineStart(code) {\n      return self.parser.lazy[self.now().line] ? nok2(code) : ok2(code)\n    }\n  }\n  function continuationCommentInside(code) {\n    if (code === 45) {\n      effects.consume(code)\n      return continuationDeclarationInside\n    }\n    return continuation(code)\n  }\n  function continuationRawTagOpen(code) {\n    if (code === 47) {\n      effects.consume(code)\n      buffer2 = \"\"\n      return continuationRawEndTag\n    }\n    return continuation(code)\n  }\n  function continuationRawEndTag(code) {\n    if (code === 62 && htmlRawNames.includes(buffer2.toLowerCase())) {\n      effects.consume(code)\n      return continuationClose\n    }\n    if (asciiAlpha(code) && buffer2.length < 8) {\n      effects.consume(code)\n      buffer2 += String.fromCharCode(code)\n      return continuationRawEndTag\n    }\n    return continuation(code)\n  }\n  function continuationCharacterDataInside(code) {\n    if (code === 93) {\n      effects.consume(code)\n      return continuationDeclarationInside\n    }\n    return continuation(code)\n  }\n  function continuationDeclarationInside(code) {\n    if (code === 62) {\n      effects.consume(code)\n      return continuationClose\n    }\n    return continuation(code)\n  }\n  function continuationClose(code) {\n    if (code === null || markdownLineEnding(code)) {\n      effects.exit(\"htmlFlowData\")\n      return done(code)\n    }\n    effects.consume(code)\n    return continuationClose\n  }\n  function done(code) {\n    effects.exit(\"htmlFlow\")\n    return ok(code)\n  }\n}\nfunction tokenizeNextBlank(effects, ok, nok) {\n  return start\n  function start(code) {\n    effects.exit(\"htmlFlowData\")\n    effects.enter(\"lineEndingBlank\")\n    effects.consume(code)\n    effects.exit(\"lineEndingBlank\")\n    return effects.attempt(blankLine, ok, nok)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/html-text.js\nvar htmlText = {\n  name: \"htmlText\",\n  tokenize: tokenizeHtmlText,\n}\nfunction tokenizeHtmlText(effects, ok, nok) {\n  const self = this\n  let marker\n  let buffer2\n  let index2\n  let returnState\n  return start\n  function start(code) {\n    effects.enter(\"htmlText\")\n    effects.enter(\"htmlTextData\")\n    effects.consume(code)\n    return open\n  }\n  function open(code) {\n    if (code === 33) {\n      effects.consume(code)\n      return declarationOpen\n    }\n    if (code === 47) {\n      effects.consume(code)\n      return tagCloseStart\n    }\n    if (code === 63) {\n      effects.consume(code)\n      return instruction\n    }\n    if (asciiAlpha(code)) {\n      effects.consume(code)\n      return tagOpen\n    }\n    return nok(code)\n  }\n  function declarationOpen(code) {\n    if (code === 45) {\n      effects.consume(code)\n      return commentOpen\n    }\n    if (code === 91) {\n      effects.consume(code)\n      buffer2 = \"CDATA[\"\n      index2 = 0\n      return cdataOpen\n    }\n    if (asciiAlpha(code)) {\n      effects.consume(code)\n      return declaration\n    }\n    return nok(code)\n  }\n  function commentOpen(code) {\n    if (code === 45) {\n      effects.consume(code)\n      return commentStart\n    }\n    return nok(code)\n  }\n  function commentStart(code) {\n    if (code === null || code === 62) {\n      return nok(code)\n    }\n    if (code === 45) {\n      effects.consume(code)\n      return commentStartDash\n    }\n    return comment(code)\n  }\n  function commentStartDash(code) {\n    if (code === null || code === 62) {\n      return nok(code)\n    }\n    return comment(code)\n  }\n  function comment(code) {\n    if (code === null) {\n      return nok(code)\n    }\n    if (code === 45) {\n      effects.consume(code)\n      return commentClose\n    }\n    if (markdownLineEnding(code)) {\n      returnState = comment\n      return atLineEnding(code)\n    }\n    effects.consume(code)\n    return comment\n  }\n  function commentClose(code) {\n    if (code === 45) {\n      effects.consume(code)\n      return end\n    }\n    return comment(code)\n  }\n  function cdataOpen(code) {\n    if (code === buffer2.charCodeAt(index2++)) {\n      effects.consume(code)\n      return index2 === buffer2.length ? cdata : cdataOpen\n    }\n    return nok(code)\n  }\n  function cdata(code) {\n    if (code === null) {\n      return nok(code)\n    }\n    if (code === 93) {\n      effects.consume(code)\n      return cdataClose\n    }\n    if (markdownLineEnding(code)) {\n      returnState = cdata\n      return atLineEnding(code)\n    }\n    effects.consume(code)\n    return cdata\n  }\n  function cdataClose(code) {\n    if (code === 93) {\n      effects.consume(code)\n      return cdataEnd\n    }\n    return cdata(code)\n  }\n  function cdataEnd(code) {\n    if (code === 62) {\n      return end(code)\n    }\n    if (code === 93) {\n      effects.consume(code)\n      return cdataEnd\n    }\n    return cdata(code)\n  }\n  function declaration(code) {\n    if (code === null || code === 62) {\n      return end(code)\n    }\n    if (markdownLineEnding(code)) {\n      returnState = declaration\n      return atLineEnding(code)\n    }\n    effects.consume(code)\n    return declaration\n  }\n  function instruction(code) {\n    if (code === null) {\n      return nok(code)\n    }\n    if (code === 63) {\n      effects.consume(code)\n      return instructionClose\n    }\n    if (markdownLineEnding(code)) {\n      returnState = instruction\n      return atLineEnding(code)\n    }\n    effects.consume(code)\n    return instruction\n  }\n  function instructionClose(code) {\n    return code === 62 ? end(code) : instruction(code)\n  }\n  function tagCloseStart(code) {\n    if (asciiAlpha(code)) {\n      effects.consume(code)\n      return tagClose\n    }\n    return nok(code)\n  }\n  function tagClose(code) {\n    if (code === 45 || asciiAlphanumeric(code)) {\n      effects.consume(code)\n      return tagClose\n    }\n    return tagCloseBetween(code)\n  }\n  function tagCloseBetween(code) {\n    if (markdownLineEnding(code)) {\n      returnState = tagCloseBetween\n      return atLineEnding(code)\n    }\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return tagCloseBetween\n    }\n    return end(code)\n  }\n  function tagOpen(code) {\n    if (code === 45 || asciiAlphanumeric(code)) {\n      effects.consume(code)\n      return tagOpen\n    }\n    if (code === 47 || code === 62 || markdownLineEndingOrSpace(code)) {\n      return tagOpenBetween(code)\n    }\n    return nok(code)\n  }\n  function tagOpenBetween(code) {\n    if (code === 47) {\n      effects.consume(code)\n      return end\n    }\n    if (code === 58 || code === 95 || asciiAlpha(code)) {\n      effects.consume(code)\n      return tagOpenAttributeName\n    }\n    if (markdownLineEnding(code)) {\n      returnState = tagOpenBetween\n      return atLineEnding(code)\n    }\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return tagOpenBetween\n    }\n    return end(code)\n  }\n  function tagOpenAttributeName(code) {\n    if (\n      code === 45 ||\n      code === 46 ||\n      code === 58 ||\n      code === 95 ||\n      asciiAlphanumeric(code)\n    ) {\n      effects.consume(code)\n      return tagOpenAttributeName\n    }\n    return tagOpenAttributeNameAfter(code)\n  }\n  function tagOpenAttributeNameAfter(code) {\n    if (code === 61) {\n      effects.consume(code)\n      return tagOpenAttributeValueBefore\n    }\n    if (markdownLineEnding(code)) {\n      returnState = tagOpenAttributeNameAfter\n      return atLineEnding(code)\n    }\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return tagOpenAttributeNameAfter\n    }\n    return tagOpenBetween(code)\n  }\n  function tagOpenAttributeValueBefore(code) {\n    if (\n      code === null ||\n      code === 60 ||\n      code === 61 ||\n      code === 62 ||\n      code === 96\n    ) {\n      return nok(code)\n    }\n    if (code === 34 || code === 39) {\n      effects.consume(code)\n      marker = code\n      return tagOpenAttributeValueQuoted\n    }\n    if (markdownLineEnding(code)) {\n      returnState = tagOpenAttributeValueBefore\n      return atLineEnding(code)\n    }\n    if (markdownSpace(code)) {\n      effects.consume(code)\n      return tagOpenAttributeValueBefore\n    }\n    effects.consume(code)\n    marker = void 0\n    return tagOpenAttributeValueUnquoted\n  }\n  function tagOpenAttributeValueQuoted(code) {\n    if (code === marker) {\n      effects.consume(code)\n      return tagOpenAttributeValueQuotedAfter\n    }\n    if (code === null) {\n      return nok(code)\n    }\n    if (markdownLineEnding(code)) {\n      returnState = tagOpenAttributeValueQuoted\n      return atLineEnding(code)\n    }\n    effects.consume(code)\n    return tagOpenAttributeValueQuoted\n  }\n  function tagOpenAttributeValueQuotedAfter(code) {\n    if (code === 62 || code === 47 || markdownLineEndingOrSpace(code)) {\n      return tagOpenBetween(code)\n    }\n    return nok(code)\n  }\n  function tagOpenAttributeValueUnquoted(code) {\n    if (\n      code === null ||\n      code === 34 ||\n      code === 39 ||\n      code === 60 ||\n      code === 61 ||\n      code === 96\n    ) {\n      return nok(code)\n    }\n    if (code === 62 || markdownLineEndingOrSpace(code)) {\n      return tagOpenBetween(code)\n    }\n    effects.consume(code)\n    return tagOpenAttributeValueUnquoted\n  }\n  function atLineEnding(code) {\n    effects.exit(\"htmlTextData\")\n    effects.enter(\"lineEnding\")\n    effects.consume(code)\n    effects.exit(\"lineEnding\")\n    return factorySpace(\n      effects,\n      afterPrefix,\n      \"linePrefix\",\n      self.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4,\n    )\n  }\n  function afterPrefix(code) {\n    effects.enter(\"htmlTextData\")\n    return returnState(code)\n  }\n  function end(code) {\n    if (code === 62) {\n      effects.consume(code)\n      effects.exit(\"htmlTextData\")\n      effects.exit(\"htmlText\")\n      return ok\n    }\n    return nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/label-end.js\nvar labelEnd = {\n  name: \"labelEnd\",\n  tokenize: tokenizeLabelEnd,\n  resolveTo: resolveToLabelEnd,\n  resolveAll: resolveAllLabelEnd,\n}\nvar resourceConstruct = {\n  tokenize: tokenizeResource,\n}\nvar fullReferenceConstruct = {\n  tokenize: tokenizeFullReference,\n}\nvar collapsedReferenceConstruct = {\n  tokenize: tokenizeCollapsedReference,\n}\nfunction resolveAllLabelEnd(events) {\n  let index2 = -1\n  let token\n  while (++index2 < events.length) {\n    token = events[index2][1]\n    if (\n      token.type === \"labelImage\" ||\n      token.type === \"labelLink\" ||\n      token.type === \"labelEnd\"\n    ) {\n      events.splice(index2 + 1, token.type === \"labelImage\" ? 4 : 2)\n      token.type = \"data\"\n      index2++\n    }\n  }\n  return events\n}\nfunction resolveToLabelEnd(events, context) {\n  let index2 = events.length\n  let offset = 0\n  let token\n  let open\n  let close2\n  let media\n  while (index2--) {\n    token = events[index2][1]\n    if (open) {\n      if (\n        token.type === \"link\" ||\n        (token.type === \"labelLink\" && token._inactive)\n      ) {\n        break\n      }\n      if (events[index2][0] === \"enter\" && token.type === \"labelLink\") {\n        token._inactive = true\n      }\n    } else if (close2) {\n      if (\n        events[index2][0] === \"enter\" &&\n        (token.type === \"labelImage\" || token.type === \"labelLink\") &&\n        !token._balanced\n      ) {\n        open = index2\n        if (token.type !== \"labelLink\") {\n          offset = 2\n          break\n        }\n      }\n    } else if (token.type === \"labelEnd\") {\n      close2 = index2\n    }\n  }\n  const group = {\n    type: events[open][1].type === \"labelLink\" ? \"link\" : \"image\",\n    start: Object.assign({}, events[open][1].start),\n    end: Object.assign({}, events[events.length - 1][1].end),\n  }\n  const label = {\n    type: \"label\",\n    start: Object.assign({}, events[open][1].start),\n    end: Object.assign({}, events[close2][1].end),\n  }\n  const text3 = {\n    type: \"labelText\",\n    start: Object.assign({}, events[open + offset + 2][1].end),\n    end: Object.assign({}, events[close2 - 2][1].start),\n  }\n  media = [\n    [\"enter\", group, context],\n    [\"enter\", label, context],\n  ]\n  media = push(media, events.slice(open + 1, open + offset + 3))\n  media = push(media, [[\"enter\", text3, context]])\n  media = push(\n    media,\n    resolveAll(\n      context.parser.constructs.insideSpan.null,\n      events.slice(open + offset + 4, close2 - 3),\n      context,\n    ),\n  )\n  media = push(media, [\n    [\"exit\", text3, context],\n    events[close2 - 2],\n    events[close2 - 1],\n    [\"exit\", label, context],\n  ])\n  media = push(media, events.slice(close2 + 1))\n  media = push(media, [[\"exit\", group, context]])\n  splice(events, open, events.length, media)\n  return events\n}\nfunction tokenizeLabelEnd(effects, ok, nok) {\n  const self = this\n  let index2 = self.events.length\n  let labelStart\n  let defined\n  while (index2--) {\n    if (\n      (self.events[index2][1].type === \"labelImage\" ||\n        self.events[index2][1].type === \"labelLink\") &&\n      !self.events[index2][1]._balanced\n    ) {\n      labelStart = self.events[index2][1]\n      break\n    }\n  }\n  return start\n  function start(code) {\n    if (!labelStart) {\n      return nok(code)\n    }\n    if (labelStart._inactive) return balanced(code)\n    defined = self.parser.defined.includes(\n      normalizeIdentifier(\n        self.sliceSerialize({\n          start: labelStart.end,\n          end: self.now(),\n        }),\n      ),\n    )\n    effects.enter(\"labelEnd\")\n    effects.enter(\"labelMarker\")\n    effects.consume(code)\n    effects.exit(\"labelMarker\")\n    effects.exit(\"labelEnd\")\n    return afterLabelEnd\n  }\n  function afterLabelEnd(code) {\n    if (code === 40) {\n      return effects.attempt(\n        resourceConstruct,\n        ok,\n        defined ? ok : balanced,\n      )(code)\n    }\n    if (code === 91) {\n      return effects.attempt(\n        fullReferenceConstruct,\n        ok,\n        defined\n          ? effects.attempt(collapsedReferenceConstruct, ok, balanced)\n          : balanced,\n      )(code)\n    }\n    return defined ? ok(code) : balanced(code)\n  }\n  function balanced(code) {\n    labelStart._balanced = true\n    return nok(code)\n  }\n}\nfunction tokenizeResource(effects, ok, nok) {\n  return start\n  function start(code) {\n    effects.enter(\"resource\")\n    effects.enter(\"resourceMarker\")\n    effects.consume(code)\n    effects.exit(\"resourceMarker\")\n    return factoryWhitespace(effects, open)\n  }\n  function open(code) {\n    if (code === 41) {\n      return end(code)\n    }\n    return factoryDestination(\n      effects,\n      destinationAfter,\n      nok,\n      \"resourceDestination\",\n      \"resourceDestinationLiteral\",\n      \"resourceDestinationLiteralMarker\",\n      \"resourceDestinationRaw\",\n      \"resourceDestinationString\",\n      3,\n    )(code)\n  }\n  function destinationAfter(code) {\n    return markdownLineEndingOrSpace(code)\n      ? factoryWhitespace(effects, between)(code)\n      : end(code)\n  }\n  function between(code) {\n    if (code === 34 || code === 39 || code === 40) {\n      return factoryTitle(\n        effects,\n        factoryWhitespace(effects, end),\n        nok,\n        \"resourceTitle\",\n        \"resourceTitleMarker\",\n        \"resourceTitleString\",\n      )(code)\n    }\n    return end(code)\n  }\n  function end(code) {\n    if (code === 41) {\n      effects.enter(\"resourceMarker\")\n      effects.consume(code)\n      effects.exit(\"resourceMarker\")\n      effects.exit(\"resource\")\n      return ok\n    }\n    return nok(code)\n  }\n}\nfunction tokenizeFullReference(effects, ok, nok) {\n  const self = this\n  return start\n  function start(code) {\n    return factoryLabel.call(\n      self,\n      effects,\n      afterLabel,\n      nok,\n      \"reference\",\n      \"referenceMarker\",\n      \"referenceString\",\n    )(code)\n  }\n  function afterLabel(code) {\n    return self.parser.defined.includes(\n      normalizeIdentifier(\n        self\n          .sliceSerialize(self.events[self.events.length - 1][1])\n          .slice(1, -1),\n      ),\n    )\n      ? ok(code)\n      : nok(code)\n  }\n}\nfunction tokenizeCollapsedReference(effects, ok, nok) {\n  return start\n  function start(code) {\n    effects.enter(\"reference\")\n    effects.enter(\"referenceMarker\")\n    effects.consume(code)\n    effects.exit(\"referenceMarker\")\n    return open\n  }\n  function open(code) {\n    if (code === 93) {\n      effects.enter(\"referenceMarker\")\n      effects.consume(code)\n      effects.exit(\"referenceMarker\")\n      effects.exit(\"reference\")\n      return ok\n    }\n    return nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/label-start-image.js\nvar labelStartImage = {\n  name: \"labelStartImage\",\n  tokenize: tokenizeLabelStartImage,\n  resolveAll: labelEnd.resolveAll,\n}\nfunction tokenizeLabelStartImage(effects, ok, nok) {\n  const self = this\n  return start\n  function start(code) {\n    effects.enter(\"labelImage\")\n    effects.enter(\"labelImageMarker\")\n    effects.consume(code)\n    effects.exit(\"labelImageMarker\")\n    return open\n  }\n  function open(code) {\n    if (code === 91) {\n      effects.enter(\"labelMarker\")\n      effects.consume(code)\n      effects.exit(\"labelMarker\")\n      effects.exit(\"labelImage\")\n      return after\n    }\n    return nok(code)\n  }\n  function after(code) {\n    return code === 94 && \"_hiddenFootnoteSupport\" in self.parser.constructs\n      ? nok(code)\n      : ok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/label-start-link.js\nvar labelStartLink = {\n  name: \"labelStartLink\",\n  tokenize: tokenizeLabelStartLink,\n  resolveAll: labelEnd.resolveAll,\n}\nfunction tokenizeLabelStartLink(effects, ok, nok) {\n  const self = this\n  return start\n  function start(code) {\n    effects.enter(\"labelLink\")\n    effects.enter(\"labelMarker\")\n    effects.consume(code)\n    effects.exit(\"labelMarker\")\n    effects.exit(\"labelLink\")\n    return after\n  }\n  function after(code) {\n    return code === 94 && \"_hiddenFootnoteSupport\" in self.parser.constructs\n      ? nok(code)\n      : ok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/line-ending.js\nvar lineEnding = {\n  name: \"lineEnding\",\n  tokenize: tokenizeLineEnding,\n}\nfunction tokenizeLineEnding(effects, ok) {\n  return start\n  function start(code) {\n    effects.enter(\"lineEnding\")\n    effects.consume(code)\n    effects.exit(\"lineEnding\")\n    return factorySpace(effects, ok, \"linePrefix\")\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/thematic-break.js\nvar thematicBreak = {\n  name: \"thematicBreak\",\n  tokenize: tokenizeThematicBreak,\n}\nfunction tokenizeThematicBreak(effects, ok, nok) {\n  let size = 0\n  let marker\n  return start\n  function start(code) {\n    effects.enter(\"thematicBreak\")\n    marker = code\n    return atBreak(code)\n  }\n  function atBreak(code) {\n    if (code === marker) {\n      effects.enter(\"thematicBreakSequence\")\n      return sequence(code)\n    }\n    if (markdownSpace(code)) {\n      return factorySpace(effects, atBreak, \"whitespace\")(code)\n    }\n    if (size < 3 || (code !== null && !markdownLineEnding(code))) {\n      return nok(code)\n    }\n    effects.exit(\"thematicBreak\")\n    return ok(code)\n  }\n  function sequence(code) {\n    if (code === marker) {\n      effects.consume(code)\n      size++\n      return sequence\n    }\n    effects.exit(\"thematicBreakSequence\")\n    return atBreak(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/list.js\nvar list = {\n  name: \"list\",\n  tokenize: tokenizeListStart,\n  continuation: {\n    tokenize: tokenizeListContinuation,\n  },\n  exit: tokenizeListEnd,\n}\nvar listItemPrefixWhitespaceConstruct = {\n  tokenize: tokenizeListItemPrefixWhitespace,\n  partial: true,\n}\nvar indentConstruct = {\n  tokenize: tokenizeIndent,\n  partial: true,\n}\nfunction tokenizeListStart(effects, ok, nok) {\n  const self = this\n  const tail = self.events[self.events.length - 1]\n  let initialSize =\n    tail && tail[1].type === \"linePrefix\"\n      ? tail[2].sliceSerialize(tail[1], true).length\n      : 0\n  let size = 0\n  return start\n  function start(code) {\n    const kind =\n      self.containerState.type ||\n      (code === 42 || code === 43 || code === 45\n        ? \"listUnordered\"\n        : \"listOrdered\")\n    if (\n      kind === \"listUnordered\"\n        ? !self.containerState.marker || code === self.containerState.marker\n        : asciiDigit(code)\n    ) {\n      if (!self.containerState.type) {\n        self.containerState.type = kind\n        effects.enter(kind, {\n          _container: true,\n        })\n      }\n      if (kind === \"listUnordered\") {\n        effects.enter(\"listItemPrefix\")\n        return code === 42 || code === 45\n          ? effects.check(thematicBreak, nok, atMarker)(code)\n          : atMarker(code)\n      }\n      if (!self.interrupt || code === 49) {\n        effects.enter(\"listItemPrefix\")\n        effects.enter(\"listItemValue\")\n        return inside(code)\n      }\n    }\n    return nok(code)\n  }\n  function inside(code) {\n    if (asciiDigit(code) && ++size < 10) {\n      effects.consume(code)\n      return inside\n    }\n    if (\n      (!self.interrupt || size < 2) &&\n      (self.containerState.marker\n        ? code === self.containerState.marker\n        : code === 41 || code === 46)\n    ) {\n      effects.exit(\"listItemValue\")\n      return atMarker(code)\n    }\n    return nok(code)\n  }\n  function atMarker(code) {\n    effects.enter(\"listItemMarker\")\n    effects.consume(code)\n    effects.exit(\"listItemMarker\")\n    self.containerState.marker = self.containerState.marker || code\n    return effects.check(\n      blankLine,\n      self.interrupt ? nok : onBlank,\n      effects.attempt(\n        listItemPrefixWhitespaceConstruct,\n        endOfPrefix,\n        otherPrefix,\n      ),\n    )\n  }\n  function onBlank(code) {\n    self.containerState.initialBlankLine = true\n    initialSize++\n    return endOfPrefix(code)\n  }\n  function otherPrefix(code) {\n    if (markdownSpace(code)) {\n      effects.enter(\"listItemPrefixWhitespace\")\n      effects.consume(code)\n      effects.exit(\"listItemPrefixWhitespace\")\n      return endOfPrefix\n    }\n    return nok(code)\n  }\n  function endOfPrefix(code) {\n    self.containerState.size =\n      initialSize +\n      self.sliceSerialize(effects.exit(\"listItemPrefix\"), true).length\n    return ok(code)\n  }\n}\nfunction tokenizeListContinuation(effects, ok, nok) {\n  const self = this\n  self.containerState._closeFlow = void 0\n  return effects.check(blankLine, onBlank, notBlank)\n  function onBlank(code) {\n    self.containerState.furtherBlankLines =\n      self.containerState.furtherBlankLines ||\n      self.containerState.initialBlankLine\n    return factorySpace(\n      effects,\n      ok,\n      \"listItemIndent\",\n      self.containerState.size + 1,\n    )(code)\n  }\n  function notBlank(code) {\n    if (self.containerState.furtherBlankLines || !markdownSpace(code)) {\n      self.containerState.furtherBlankLines = void 0\n      self.containerState.initialBlankLine = void 0\n      return notInCurrentItem(code)\n    }\n    self.containerState.furtherBlankLines = void 0\n    self.containerState.initialBlankLine = void 0\n    return effects.attempt(indentConstruct, ok, notInCurrentItem)(code)\n  }\n  function notInCurrentItem(code) {\n    self.containerState._closeFlow = true\n    self.interrupt = void 0\n    return factorySpace(\n      effects,\n      effects.attempt(list, ok, nok),\n      \"linePrefix\",\n      self.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4,\n    )(code)\n  }\n}\nfunction tokenizeIndent(effects, ok, nok) {\n  const self = this\n  return factorySpace(\n    effects,\n    afterPrefix,\n    \"listItemIndent\",\n    self.containerState.size + 1,\n  )\n  function afterPrefix(code) {\n    const tail = self.events[self.events.length - 1]\n    return tail &&\n      tail[1].type === \"listItemIndent\" &&\n      tail[2].sliceSerialize(tail[1], true).length === self.containerState.size\n      ? ok(code)\n      : nok(code)\n  }\n}\nfunction tokenizeListEnd(effects) {\n  effects.exit(this.containerState.type)\n}\nfunction tokenizeListItemPrefixWhitespace(effects, ok, nok) {\n  const self = this\n  return factorySpace(\n    effects,\n    afterPrefix,\n    \"listItemPrefixWhitespace\",\n    self.parser.constructs.disable.null.includes(\"codeIndented\")\n      ? void 0\n      : 4 + 1,\n  )\n  function afterPrefix(code) {\n    const tail = self.events[self.events.length - 1]\n    return !markdownSpace(code) &&\n      tail &&\n      tail[1].type === \"listItemPrefixWhitespace\"\n      ? ok(code)\n      : nok(code)\n  }\n}\n\n// node_modules/micromark-core-commonmark/lib/setext-underline.js\nvar setextUnderline = {\n  name: \"setextUnderline\",\n  tokenize: tokenizeSetextUnderline,\n  resolveTo: resolveToSetextUnderline,\n}\nfunction resolveToSetextUnderline(events, context) {\n  let index2 = events.length\n  let content3\n  let text3\n  let definition2\n  while (index2--) {\n    if (events[index2][0] === \"enter\") {\n      if (events[index2][1].type === \"content\") {\n        content3 = index2\n        break\n      }\n      if (events[index2][1].type === \"paragraph\") {\n        text3 = index2\n      }\n    } else {\n      if (events[index2][1].type === \"content\") {\n        events.splice(index2, 1)\n      }\n      if (!definition2 && events[index2][1].type === \"definition\") {\n        definition2 = index2\n      }\n    }\n  }\n  const heading = {\n    type: \"setextHeading\",\n    start: Object.assign({}, events[text3][1].start),\n    end: Object.assign({}, events[events.length - 1][1].end),\n  }\n  events[text3][1].type = \"setextHeadingText\"\n  if (definition2) {\n    events.splice(text3, 0, [\"enter\", heading, context])\n    events.splice(definition2 + 1, 0, [\"exit\", events[content3][1], context])\n    events[content3][1].end = Object.assign({}, events[definition2][1].end)\n  } else {\n    events[content3][1] = heading\n  }\n  events.push([\"exit\", heading, context])\n  return events\n}\nfunction tokenizeSetextUnderline(effects, ok, nok) {\n  const self = this\n  let index2 = self.events.length\n  let marker\n  let paragraph\n  while (index2--) {\n    if (\n      self.events[index2][1].type !== \"lineEnding\" &&\n      self.events[index2][1].type !== \"linePrefix\" &&\n      self.events[index2][1].type !== \"content\"\n    ) {\n      paragraph = self.events[index2][1].type === \"paragraph\"\n      break\n    }\n  }\n  return start\n  function start(code) {\n    if (!self.parser.lazy[self.now().line] && (self.interrupt || paragraph)) {\n      effects.enter(\"setextHeadingLine\")\n      effects.enter(\"setextHeadingLineSequence\")\n      marker = code\n      return closingSequence(code)\n    }\n    return nok(code)\n  }\n  function closingSequence(code) {\n    if (code === marker) {\n      effects.consume(code)\n      return closingSequence\n    }\n    effects.exit(\"setextHeadingLineSequence\")\n    return factorySpace(effects, closingSequenceEnd, \"lineSuffix\")(code)\n  }\n  function closingSequenceEnd(code) {\n    if (code === null || markdownLineEnding(code)) {\n      effects.exit(\"setextHeadingLine\")\n      return ok(code)\n    }\n    return nok(code)\n  }\n}\n\n// node_modules/micromark/lib/initialize/flow.js\nvar flow = {\n  tokenize: initializeFlow,\n}\nfunction initializeFlow(effects) {\n  const self = this\n  const initial = effects.attempt(\n    blankLine,\n    atBlankEnding,\n    effects.attempt(\n      this.parser.constructs.flowInitial,\n      afterConstruct,\n      factorySpace(\n        effects,\n        effects.attempt(\n          this.parser.constructs.flow,\n          afterConstruct,\n          effects.attempt(content2, afterConstruct),\n        ),\n        \"linePrefix\",\n      ),\n    ),\n  )\n  return initial\n  function atBlankEnding(code) {\n    if (code === null) {\n      effects.consume(code)\n      return\n    }\n    effects.enter(\"lineEndingBlank\")\n    effects.consume(code)\n    effects.exit(\"lineEndingBlank\")\n    self.currentConstruct = void 0\n    return initial\n  }\n  function afterConstruct(code) {\n    if (code === null) {\n      effects.consume(code)\n      return\n    }\n    effects.enter(\"lineEnding\")\n    effects.consume(code)\n    effects.exit(\"lineEnding\")\n    self.currentConstruct = void 0\n    return initial\n  }\n}\n\n// node_modules/micromark/lib/initialize/text.js\nvar resolver = {\n  resolveAll: createResolver(),\n}\nvar string = initializeFactory(\"string\")\nvar text = initializeFactory(\"text\")\nfunction initializeFactory(field) {\n  return {\n    tokenize: initializeText,\n    resolveAll: createResolver(\n      field === \"text\" ? resolveAllLineSuffixes : void 0,\n    ),\n  }\n  function initializeText(effects) {\n    const self = this\n    const constructs2 = this.parser.constructs[field]\n    const text3 = effects.attempt(constructs2, start, notText)\n    return start\n    function start(code) {\n      return atBreak(code) ? text3(code) : notText(code)\n    }\n    function notText(code) {\n      if (code === null) {\n        effects.consume(code)\n        return\n      }\n      effects.enter(\"data\")\n      effects.consume(code)\n      return data\n    }\n    function data(code) {\n      if (atBreak(code)) {\n        effects.exit(\"data\")\n        return text3(code)\n      }\n      effects.consume(code)\n      return data\n    }\n    function atBreak(code) {\n      if (code === null) {\n        return true\n      }\n      const list2 = constructs2[code]\n      let index2 = -1\n      if (list2) {\n        while (++index2 < list2.length) {\n          const item = list2[index2]\n          if (!item.previous || item.previous.call(self, self.previous)) {\n            return true\n          }\n        }\n      }\n      return false\n    }\n  }\n}\nfunction createResolver(extraResolver) {\n  return resolveAllText\n  function resolveAllText(events, context) {\n    let index2 = -1\n    let enter\n    while (++index2 <= events.length) {\n      if (enter === void 0) {\n        if (events[index2] && events[index2][1].type === \"data\") {\n          enter = index2\n          index2++\n        }\n      } else if (!events[index2] || events[index2][1].type !== \"data\") {\n        if (index2 !== enter + 2) {\n          events[enter][1].end = events[index2 - 1][1].end\n          events.splice(enter + 2, index2 - enter - 2)\n          index2 = enter + 2\n        }\n        enter = void 0\n      }\n    }\n    return extraResolver ? extraResolver(events, context) : events\n  }\n}\nfunction resolveAllLineSuffixes(events, context) {\n  let eventIndex = -1\n  while (++eventIndex <= events.length) {\n    if (\n      (eventIndex === events.length ||\n        events[eventIndex][1].type === \"lineEnding\") &&\n      events[eventIndex - 1][1].type === \"data\"\n    ) {\n      const data = events[eventIndex - 1][1]\n      const chunks = context.sliceStream(data)\n      let index2 = chunks.length\n      let bufferIndex = -1\n      let size = 0\n      let tabs\n      while (index2--) {\n        const chunk = chunks[index2]\n        if (typeof chunk === \"string\") {\n          bufferIndex = chunk.length\n          while (chunk.charCodeAt(bufferIndex - 1) === 32) {\n            size++\n            bufferIndex--\n          }\n          if (bufferIndex) break\n          bufferIndex = -1\n        } else if (chunk === -2) {\n          tabs = true\n          size++\n        } else if (chunk === -1) {\n        } else {\n          index2++\n          break\n        }\n      }\n      if (size) {\n        const token = {\n          type:\n            eventIndex === events.length || tabs || size < 2\n              ? \"lineSuffix\"\n              : \"hardBreakTrailing\",\n          start: {\n            line: data.end.line,\n            column: data.end.column - size,\n            offset: data.end.offset - size,\n            _index: data.start._index + index2,\n            _bufferIndex: index2\n              ? bufferIndex\n              : data.start._bufferIndex + bufferIndex,\n          },\n          end: Object.assign({}, data.end),\n        }\n        data.end = Object.assign({}, token.start)\n        if (data.start.offset === data.end.offset) {\n          Object.assign(data, token)\n        } else {\n          events.splice(\n            eventIndex,\n            0,\n            [\"enter\", token, context],\n            [\"exit\", token, context],\n          )\n          eventIndex += 2\n        }\n      }\n      eventIndex++\n    }\n  }\n  return events\n}\n\n// node_modules/micromark/lib/create-tokenizer.js\nfunction createTokenizer(parser, initialize, from) {\n  let point2 = Object.assign(\n    from\n      ? Object.assign({}, from)\n      : {\n          line: 1,\n          column: 1,\n          offset: 0,\n        },\n    {\n      _index: 0,\n      _bufferIndex: -1,\n    },\n  )\n  const columnStart = {}\n  const resolveAllConstructs = []\n  let chunks = []\n  let stack = []\n  let consumed = true\n  const effects = {\n    consume,\n    enter,\n    exit: exit2,\n    attempt: constructFactory(onsuccessfulconstruct),\n    check: constructFactory(onsuccessfulcheck),\n    interrupt: constructFactory(onsuccessfulcheck, {\n      interrupt: true,\n    }),\n  }\n  const context = {\n    previous: null,\n    code: null,\n    containerState: {},\n    events: [],\n    parser,\n    sliceStream,\n    sliceSerialize,\n    now,\n    defineSkip,\n    write,\n  }\n  let state = initialize.tokenize.call(context, effects)\n  let expectedCode\n  if (initialize.resolveAll) {\n    resolveAllConstructs.push(initialize)\n  }\n  return context\n  function write(slice) {\n    chunks = push(chunks, slice)\n    main()\n    if (chunks[chunks.length - 1] !== null) {\n      return []\n    }\n    addResult(initialize, 0)\n    context.events = resolveAll(resolveAllConstructs, context.events, context)\n    return context.events\n  }\n  function sliceSerialize(token, expandTabs) {\n    return serializeChunks(sliceStream(token), expandTabs)\n  }\n  function sliceStream(token) {\n    return sliceChunks(chunks, token)\n  }\n  function now() {\n    return Object.assign({}, point2)\n  }\n  function defineSkip(value2) {\n    columnStart[value2.line] = value2.column\n    accountForPotentialSkip()\n  }\n  function main() {\n    let chunkIndex\n    while (point2._index < chunks.length) {\n      const chunk = chunks[point2._index]\n      if (typeof chunk === \"string\") {\n        chunkIndex = point2._index\n        if (point2._bufferIndex < 0) {\n          point2._bufferIndex = 0\n        }\n        while (\n          point2._index === chunkIndex &&\n          point2._bufferIndex < chunk.length\n        ) {\n          go(chunk.charCodeAt(point2._bufferIndex))\n        }\n      } else {\n        go(chunk)\n      }\n    }\n  }\n  function go(code) {\n    consumed = void 0\n    expectedCode = code\n    state = state(code)\n  }\n  function consume(code) {\n    if (markdownLineEnding(code)) {\n      point2.line++\n      point2.column = 1\n      point2.offset += code === -3 ? 2 : 1\n      accountForPotentialSkip()\n    } else if (code !== -1) {\n      point2.column++\n      point2.offset++\n    }\n    if (point2._bufferIndex < 0) {\n      point2._index++\n    } else {\n      point2._bufferIndex++\n      if (point2._bufferIndex === chunks[point2._index].length) {\n        point2._bufferIndex = -1\n        point2._index++\n      }\n    }\n    context.previous = code\n    consumed = true\n  }\n  function enter(type, fields) {\n    const token = fields || {}\n    token.type = type\n    token.start = now()\n    context.events.push([\"enter\", token, context])\n    stack.push(token)\n    return token\n  }\n  function exit2(type) {\n    const token = stack.pop()\n    token.end = now()\n    context.events.push([\"exit\", token, context])\n    return token\n  }\n  function onsuccessfulconstruct(construct, info) {\n    addResult(construct, info.from)\n  }\n  function onsuccessfulcheck(_, info) {\n    info.restore()\n  }\n  function constructFactory(onreturn, fields) {\n    return hook\n    function hook(constructs2, returnState, bogusState) {\n      let listOfConstructs\n      let constructIndex\n      let currentConstruct\n      let info\n      return Array.isArray(constructs2)\n        ? handleListOfConstructs(constructs2)\n        : \"tokenize\" in constructs2\n        ? handleListOfConstructs([constructs2])\n        : handleMapOfConstructs(constructs2)\n      function handleMapOfConstructs(map) {\n        return start\n        function start(code) {\n          const def = code !== null && map[code]\n          const all2 = code !== null && map.null\n          const list2 = [\n            ...(Array.isArray(def) ? def : def ? [def] : []),\n            ...(Array.isArray(all2) ? all2 : all2 ? [all2] : []),\n          ]\n          return handleListOfConstructs(list2)(code)\n        }\n      }\n      function handleListOfConstructs(list2) {\n        listOfConstructs = list2\n        constructIndex = 0\n        if (list2.length === 0) {\n          return bogusState\n        }\n        return handleConstruct(list2[constructIndex])\n      }\n      function handleConstruct(construct) {\n        return start\n        function start(code) {\n          info = store()\n          currentConstruct = construct\n          if (!construct.partial) {\n            context.currentConstruct = construct\n          }\n          if (\n            construct.name &&\n            context.parser.constructs.disable.null.includes(construct.name)\n          ) {\n            return nok(code)\n          }\n          return construct.tokenize.call(\n            fields ? Object.assign(Object.create(context), fields) : context,\n            effects,\n            ok,\n            nok,\n          )(code)\n        }\n      }\n      function ok(code) {\n        consumed = true\n        onreturn(currentConstruct, info)\n        return returnState\n      }\n      function nok(code) {\n        consumed = true\n        info.restore()\n        if (++constructIndex < listOfConstructs.length) {\n          return handleConstruct(listOfConstructs[constructIndex])\n        }\n        return bogusState\n      }\n    }\n  }\n  function addResult(construct, from2) {\n    if (construct.resolveAll && !resolveAllConstructs.includes(construct)) {\n      resolveAllConstructs.push(construct)\n    }\n    if (construct.resolve) {\n      splice(\n        context.events,\n        from2,\n        context.events.length - from2,\n        construct.resolve(context.events.slice(from2), context),\n      )\n    }\n    if (construct.resolveTo) {\n      context.events = construct.resolveTo(context.events, context)\n    }\n  }\n  function store() {\n    const startPoint = now()\n    const startPrevious = context.previous\n    const startCurrentConstruct = context.currentConstruct\n    const startEventsIndex = context.events.length\n    const startStack = Array.from(stack)\n    return {\n      restore,\n      from: startEventsIndex,\n    }\n    function restore() {\n      point2 = startPoint\n      context.previous = startPrevious\n      context.currentConstruct = startCurrentConstruct\n      context.events.length = startEventsIndex\n      stack = startStack\n      accountForPotentialSkip()\n    }\n  }\n  function accountForPotentialSkip() {\n    if (point2.line in columnStart && point2.column < 2) {\n      point2.column = columnStart[point2.line]\n      point2.offset += columnStart[point2.line] - 1\n    }\n  }\n}\nfunction sliceChunks(chunks, token) {\n  const startIndex = token.start._index\n  const startBufferIndex = token.start._bufferIndex\n  const endIndex = token.end._index\n  const endBufferIndex = token.end._bufferIndex\n  let view\n  if (startIndex === endIndex) {\n    view = [chunks[startIndex].slice(startBufferIndex, endBufferIndex)]\n  } else {\n    view = chunks.slice(startIndex, endIndex)\n    if (startBufferIndex > -1) {\n      view[0] = view[0].slice(startBufferIndex)\n    }\n    if (endBufferIndex > 0) {\n      view.push(chunks[endIndex].slice(0, endBufferIndex))\n    }\n  }\n  return view\n}\nfunction serializeChunks(chunks, expandTabs) {\n  let index2 = -1\n  const result = []\n  let atTab\n  while (++index2 < chunks.length) {\n    const chunk = chunks[index2]\n    let value2\n    if (typeof chunk === \"string\") {\n      value2 = chunk\n    } else\n      switch (chunk) {\n        case -5: {\n          value2 = \"\\r\"\n          break\n        }\n        case -4: {\n          value2 = \"\\n\"\n          break\n        }\n        case -3: {\n          value2 = \"\\r\\n\"\n          break\n        }\n        case -2: {\n          value2 = expandTabs ? \" \" : \"\t\"\n          break\n        }\n        case -1: {\n          if (!expandTabs && atTab) continue\n          value2 = \" \"\n          break\n        }\n        default: {\n          value2 = String.fromCharCode(chunk)\n        }\n      }\n    atTab = chunk === -2\n    result.push(value2)\n  }\n  return result.join(\"\")\n}\n\n// node_modules/micromark/lib/constructs.js\nvar constructs_exports = {}\n__export(constructs_exports, {\n  attentionMarkers: () => attentionMarkers,\n  contentInitial: () => contentInitial,\n  disable: () => disable,\n  document: () => document3,\n  flow: () => flow2,\n  flowInitial: () => flowInitial,\n  insideSpan: () => insideSpan,\n  string: () => string2,\n  text: () => text2,\n})\nvar document3 = {\n  [42]: list,\n  [43]: list,\n  [45]: list,\n  [48]: list,\n  [49]: list,\n  [50]: list,\n  [51]: list,\n  [52]: list,\n  [53]: list,\n  [54]: list,\n  [55]: list,\n  [56]: list,\n  [57]: list,\n  [62]: blockQuote,\n}\nvar contentInitial = {\n  [91]: definition,\n}\nvar flowInitial = {\n  [-2]: codeIndented,\n  [-1]: codeIndented,\n  [32]: codeIndented,\n}\nvar flow2 = {\n  [35]: headingAtx,\n  [42]: thematicBreak,\n  [45]: [setextUnderline, thematicBreak],\n  [60]: htmlFlow,\n  [61]: setextUnderline,\n  [95]: thematicBreak,\n  [96]: codeFenced,\n  [126]: codeFenced,\n}\nvar string2 = {\n  [38]: characterReference,\n  [92]: characterEscape,\n}\nvar text2 = {\n  [-5]: lineEnding,\n  [-4]: lineEnding,\n  [-3]: lineEnding,\n  [33]: labelStartImage,\n  [38]: characterReference,\n  [42]: attention,\n  [60]: [autolink, htmlText],\n  [91]: labelStartLink,\n  [92]: [hardBreakEscape, characterEscape],\n  [93]: labelEnd,\n  [95]: attention,\n  [96]: codeText,\n}\nvar insideSpan = {\n  null: [attention, resolver],\n}\nvar attentionMarkers = {\n  null: [42, 95],\n}\nvar disable = {\n  null: [],\n}\n\n// node_modules/micromark/lib/parse.js\nfunction parse2(options = {}) {\n  const constructs2 = combineExtensions(\n    [constructs_exports].concat(options.extensions || []),\n  )\n  const parser = {\n    defined: [],\n    lazy: {},\n    constructs: constructs2,\n    content: create2(content),\n    document: create2(document2),\n    flow: create2(flow),\n    string: create2(string),\n    text: create2(text),\n  }\n  return parser\n  function create2(initial) {\n    return creator\n    function creator(from) {\n      return createTokenizer(parser, initial, from)\n    }\n  }\n}\n\n// node_modules/micromark/lib/preprocess.js\nvar search = /[\\0\\t\\n\\r]/g\nfunction preprocess() {\n  let column = 1\n  let buffer2 = \"\"\n  let start = true\n  let atCarriageReturn\n  return preprocessor\n  function preprocessor(value2, encoding, end) {\n    const chunks = []\n    let match\n    let next\n    let startPosition\n    let endPosition\n    let code\n    value2 = buffer2 + value2.toString(encoding)\n    startPosition = 0\n    buffer2 = \"\"\n    if (start) {\n      if (value2.charCodeAt(0) === 65279) {\n        startPosition++\n      }\n      start = void 0\n    }\n    while (startPosition < value2.length) {\n      search.lastIndex = startPosition\n      match = search.exec(value2)\n      endPosition =\n        match && match.index !== void 0 ? match.index : value2.length\n      code = value2.charCodeAt(endPosition)\n      if (!match) {\n        buffer2 = value2.slice(startPosition)\n        break\n      }\n      if (code === 10 && startPosition === endPosition && atCarriageReturn) {\n        chunks.push(-3)\n        atCarriageReturn = void 0\n      } else {\n        if (atCarriageReturn) {\n          chunks.push(-5)\n          atCarriageReturn = void 0\n        }\n        if (startPosition < endPosition) {\n          chunks.push(value2.slice(startPosition, endPosition))\n          column += endPosition - startPosition\n        }\n        switch (code) {\n          case 0: {\n            chunks.push(65533)\n            column++\n            break\n          }\n          case 9: {\n            next = Math.ceil(column / 4) * 4\n            chunks.push(-2)\n            while (column++ < next) chunks.push(-1)\n            break\n          }\n          case 10: {\n            chunks.push(-4)\n            column = 1\n            break\n          }\n          default: {\n            atCarriageReturn = true\n            column = 1\n          }\n        }\n      }\n      startPosition = endPosition + 1\n    }\n    if (end) {\n      if (atCarriageReturn) chunks.push(-5)\n      if (buffer2) chunks.push(buffer2)\n      chunks.push(null)\n    }\n    return chunks\n  }\n}\n\n// node_modules/micromark/lib/postprocess.js\nfunction postprocess(events) {\n  while (!subtokenize(events)) {}\n  return events\n}\n\n// node_modules/micromark-util-decode-numeric-character-reference/index.js\nfunction decodeNumericCharacterReference(value2, base2) {\n  const code = Number.parseInt(value2, base2)\n  if (\n    code < 9 ||\n    code === 11 ||\n    (code > 13 && code < 32) ||\n    (code > 126 && code < 160) ||\n    (code > 55295 && code < 57344) ||\n    (code > 64975 && code < 65008) ||\n    (code & 65535) === 65535 ||\n    (code & 65535) === 65534 ||\n    code > 1114111\n  ) {\n    return \"\\uFFFD\"\n  }\n  return String.fromCharCode(code)\n}\n\n// node_modules/micromark-util-decode-string/index.js\nvar characterEscapeOrReference =\n  /\\\\([!-/:-@[-`{-~])|&(#(?:\\d{1,7}|x[\\da-f]{1,6})|[\\da-z]{1,31});/gi\nfunction decodeString(value2) {\n  return value2.replace(characterEscapeOrReference, decode)\n}\nfunction decode($0, $1, $2) {\n  if ($1) {\n    return $1\n  }\n  const head = $2.charCodeAt(0)\n  if (head === 35) {\n    const head2 = $2.charCodeAt(1)\n    const hex = head2 === 120 || head2 === 88\n    return decodeNumericCharacterReference($2.slice(hex ? 2 : 1), hex ? 16 : 10)\n  }\n  return decodeEntity($2) || $0\n}\n\n// node_modules/unist-util-stringify-position/index.js\nvar own2 = {}.hasOwnProperty\nfunction stringifyPosition(value2) {\n  if (!value2 || typeof value2 !== \"object\") {\n    return \"\"\n  }\n  if (own2.call(value2, \"position\") || own2.call(value2, \"type\")) {\n    return position(value2.position)\n  }\n  if (own2.call(value2, \"start\") || own2.call(value2, \"end\")) {\n    return position(value2)\n  }\n  if (own2.call(value2, \"line\") || own2.call(value2, \"column\")) {\n    return point(value2)\n  }\n  return \"\"\n}\nfunction point(point2) {\n  return index(point2 && point2.line) + \":\" + index(point2 && point2.column)\n}\nfunction position(pos) {\n  return point(pos && pos.start) + \"-\" + point(pos && pos.end)\n}\nfunction index(value2) {\n  return value2 && typeof value2 === \"number\" ? value2 : 1\n}\n\n// node_modules/mdast-util-from-markdown/lib/index.js\nvar own3 = {}.hasOwnProperty\nvar fromMarkdown = function (value2, encoding, options) {\n  if (typeof encoding !== \"string\") {\n    options = encoding\n    encoding = void 0\n  }\n  return compiler(options)(\n    postprocess(\n      parse2(options).document().write(preprocess()(value2, encoding, true)),\n    ),\n  )\n}\nfunction compiler(options = {}) {\n  const config = configure(\n    {\n      transforms: [],\n      canContainEols: [\n        \"emphasis\",\n        \"fragment\",\n        \"heading\",\n        \"paragraph\",\n        \"strong\",\n      ],\n      enter: {\n        autolink: opener2(link),\n        autolinkProtocol: onenterdata,\n        autolinkEmail: onenterdata,\n        atxHeading: opener2(heading),\n        blockQuote: opener2(blockQuote2),\n        characterEscape: onenterdata,\n        characterReference: onenterdata,\n        codeFenced: opener2(codeFlow),\n        codeFencedFenceInfo: buffer2,\n        codeFencedFenceMeta: buffer2,\n        codeIndented: opener2(codeFlow, buffer2),\n        codeText: opener2(codeText2, buffer2),\n        codeTextData: onenterdata,\n        data: onenterdata,\n        codeFlowValue: onenterdata,\n        definition: opener2(definition2),\n        definitionDestinationString: buffer2,\n        definitionLabelString: buffer2,\n        definitionTitleString: buffer2,\n        emphasis: opener2(emphasis),\n        hardBreakEscape: opener2(hardBreak),\n        hardBreakTrailing: opener2(hardBreak),\n        htmlFlow: opener2(html, buffer2),\n        htmlFlowData: onenterdata,\n        htmlText: opener2(html, buffer2),\n        htmlTextData: onenterdata,\n        image: opener2(image),\n        label: buffer2,\n        link: opener2(link),\n        listItem: opener2(listItem),\n        listItemValue: onenterlistitemvalue,\n        listOrdered: opener2(list2, onenterlistordered),\n        listUnordered: opener2(list2),\n        paragraph: opener2(paragraph),\n        reference: onenterreference,\n        referenceString: buffer2,\n        resourceDestinationString: buffer2,\n        resourceTitleString: buffer2,\n        setextHeading: opener2(heading),\n        strong: opener2(strong),\n        thematicBreak: opener2(thematicBreak2),\n      },\n      exit: {\n        atxHeading: closer(),\n        atxHeadingSequence: onexitatxheadingsequence,\n        autolink: closer(),\n        autolinkEmail: onexitautolinkemail,\n        autolinkProtocol: onexitautolinkprotocol,\n        blockQuote: closer(),\n        characterEscapeValue: onexitdata,\n        characterReferenceMarkerHexadecimal: onexitcharacterreferencemarker,\n        characterReferenceMarkerNumeric: onexitcharacterreferencemarker,\n        characterReferenceValue: onexitcharacterreferencevalue,\n        codeFenced: closer(onexitcodefenced),\n        codeFencedFence: onexitcodefencedfence,\n        codeFencedFenceInfo: onexitcodefencedfenceinfo,\n        codeFencedFenceMeta: onexitcodefencedfencemeta,\n        codeFlowValue: onexitdata,\n        codeIndented: closer(onexitcodeindented),\n        codeText: closer(onexitcodetext),\n        codeTextData: onexitdata,\n        data: onexitdata,\n        definition: closer(),\n        definitionDestinationString: onexitdefinitiondestinationstring,\n        definitionLabelString: onexitdefinitionlabelstring,\n        definitionTitleString: onexitdefinitiontitlestring,\n        emphasis: closer(),\n        hardBreakEscape: closer(onexithardbreak),\n        hardBreakTrailing: closer(onexithardbreak),\n        htmlFlow: closer(onexithtmlflow),\n        htmlFlowData: onexitdata,\n        htmlText: closer(onexithtmltext),\n        htmlTextData: onexitdata,\n        image: closer(onexitimage),\n        label: onexitlabel,\n        labelText: onexitlabeltext,\n        lineEnding: onexitlineending,\n        link: closer(onexitlink),\n        listItem: closer(),\n        listOrdered: closer(),\n        listUnordered: closer(),\n        paragraph: closer(),\n        referenceString: onexitreferencestring,\n        resourceDestinationString: onexitresourcedestinationstring,\n        resourceTitleString: onexitresourcetitlestring,\n        resource: onexitresource,\n        setextHeading: closer(onexitsetextheading),\n        setextHeadingLineSequence: onexitsetextheadinglinesequence,\n        setextHeadingText: onexitsetextheadingtext,\n        strong: closer(),\n        thematicBreak: closer(),\n      },\n    },\n    options.mdastExtensions || [],\n  )\n  const data = {}\n  return compile\n  function compile(events) {\n    let tree = {\n      type: \"root\",\n      children: [],\n    }\n    const stack = [tree]\n    const tokenStack = []\n    const listStack = []\n    const context = {\n      stack,\n      tokenStack,\n      config,\n      enter,\n      exit: exit2,\n      buffer: buffer2,\n      resume,\n      setData,\n      getData,\n    }\n    let index2 = -1\n    while (++index2 < events.length) {\n      if (\n        events[index2][1].type === \"listOrdered\" ||\n        events[index2][1].type === \"listUnordered\"\n      ) {\n        if (events[index2][0] === \"enter\") {\n          listStack.push(index2)\n        } else {\n          const tail = listStack.pop()\n          index2 = prepareList(events, tail, index2)\n        }\n      }\n    }\n    index2 = -1\n    while (++index2 < events.length) {\n      const handler2 = config[events[index2][0]]\n      if (own3.call(handler2, events[index2][1].type)) {\n        handler2[events[index2][1].type].call(\n          Object.assign(\n            {\n              sliceSerialize: events[index2][2].sliceSerialize,\n            },\n            context,\n          ),\n          events[index2][1],\n        )\n      }\n    }\n    if (tokenStack.length > 0) {\n      throw new Error(\n        \"Cannot close document, a token (`\" +\n          tokenStack[tokenStack.length - 1].type +\n          \"`, \" +\n          stringifyPosition({\n            start: tokenStack[tokenStack.length - 1].start,\n            end: tokenStack[tokenStack.length - 1].end,\n          }) +\n          \") is still open\",\n      )\n    }\n    tree.position = {\n      start: point2(\n        events.length > 0\n          ? events[0][1].start\n          : {\n              line: 1,\n              column: 1,\n              offset: 0,\n            },\n      ),\n      end: point2(\n        events.length > 0\n          ? events[events.length - 2][1].end\n          : {\n              line: 1,\n              column: 1,\n              offset: 0,\n            },\n      ),\n    }\n    index2 = -1\n    while (++index2 < config.transforms.length) {\n      tree = config.transforms[index2](tree) || tree\n    }\n    return tree\n  }\n  function prepareList(events, start, length) {\n    let index2 = start - 1\n    let containerBalance = -1\n    let listSpread = false\n    let listItem2\n    let lineIndex\n    let firstBlankLineIndex\n    let atMarker\n    while (++index2 <= length) {\n      const event = events[index2]\n      if (\n        event[1].type === \"listUnordered\" ||\n        event[1].type === \"listOrdered\" ||\n        event[1].type === \"blockQuote\"\n      ) {\n        if (event[0] === \"enter\") {\n          containerBalance++\n        } else {\n          containerBalance--\n        }\n        atMarker = void 0\n      } else if (event[1].type === \"lineEndingBlank\") {\n        if (event[0] === \"enter\") {\n          if (\n            listItem2 &&\n            !atMarker &&\n            !containerBalance &&\n            !firstBlankLineIndex\n          ) {\n            firstBlankLineIndex = index2\n          }\n          atMarker = void 0\n        }\n      } else if (\n        event[1].type === \"linePrefix\" ||\n        event[1].type === \"listItemValue\" ||\n        event[1].type === \"listItemMarker\" ||\n        event[1].type === \"listItemPrefix\" ||\n        event[1].type === \"listItemPrefixWhitespace\"\n      ) {\n      } else {\n        atMarker = void 0\n      }\n      if (\n        (!containerBalance &&\n          event[0] === \"enter\" &&\n          event[1].type === \"listItemPrefix\") ||\n        (containerBalance === -1 &&\n          event[0] === \"exit\" &&\n          (event[1].type === \"listUnordered\" ||\n            event[1].type === \"listOrdered\"))\n      ) {\n        if (listItem2) {\n          let tailIndex = index2\n          lineIndex = void 0\n          while (tailIndex--) {\n            const tailEvent = events[tailIndex]\n            if (\n              tailEvent[1].type === \"lineEnding\" ||\n              tailEvent[1].type === \"lineEndingBlank\"\n            ) {\n              if (tailEvent[0] === \"exit\") continue\n              if (lineIndex) {\n                events[lineIndex][1].type = \"lineEndingBlank\"\n                listSpread = true\n              }\n              tailEvent[1].type = \"lineEnding\"\n              lineIndex = tailIndex\n            } else if (\n              tailEvent[1].type === \"linePrefix\" ||\n              tailEvent[1].type === \"blockQuotePrefix\" ||\n              tailEvent[1].type === \"blockQuotePrefixWhitespace\" ||\n              tailEvent[1].type === \"blockQuoteMarker\" ||\n              tailEvent[1].type === \"listItemIndent\"\n            ) {\n            } else {\n              break\n            }\n          }\n          if (\n            firstBlankLineIndex &&\n            (!lineIndex || firstBlankLineIndex < lineIndex)\n          ) {\n            listItem2._spread = true\n          }\n          listItem2.end = Object.assign(\n            {},\n            lineIndex ? events[lineIndex][1].start : event[1].end,\n          )\n          events.splice(lineIndex || index2, 0, [\"exit\", listItem2, event[2]])\n          index2++\n          length++\n        }\n        if (event[1].type === \"listItemPrefix\") {\n          listItem2 = {\n            type: \"listItem\",\n            _spread: false,\n            start: Object.assign({}, event[1].start),\n          }\n          events.splice(index2, 0, [\"enter\", listItem2, event[2]])\n          index2++\n          length++\n          firstBlankLineIndex = void 0\n          atMarker = true\n        }\n      }\n    }\n    events[start][1]._spread = listSpread\n    return length\n  }\n  function setData(key, value2) {\n    data[key] = value2\n  }\n  function getData(key) {\n    return data[key]\n  }\n  function point2(d) {\n    return {\n      line: d.line,\n      column: d.column,\n      offset: d.offset,\n    }\n  }\n  function opener2(create2, and) {\n    return open\n    function open(token) {\n      enter.call(this, create2(token), token)\n      if (and) and.call(this, token)\n    }\n  }\n  function buffer2() {\n    this.stack.push({\n      type: \"fragment\",\n      children: [],\n    })\n  }\n  function enter(node, token) {\n    const parent = this.stack[this.stack.length - 1]\n    parent.children.push(node)\n    this.stack.push(node)\n    this.tokenStack.push(token)\n    node.position = {\n      start: point2(token.start),\n    }\n    return node\n  }\n  function closer(and) {\n    return close2\n    function close2(token) {\n      if (and) and.call(this, token)\n      exit2.call(this, token)\n    }\n  }\n  function exit2(token) {\n    const node = this.stack.pop()\n    const open = this.tokenStack.pop()\n    if (!open) {\n      throw new Error(\n        \"Cannot close `\" +\n          token.type +\n          \"` (\" +\n          stringifyPosition({\n            start: token.start,\n            end: token.end,\n          }) +\n          \"): it\\u2019s not open\",\n      )\n    } else if (open.type !== token.type) {\n      throw new Error(\n        \"Cannot close `\" +\n          token.type +\n          \"` (\" +\n          stringifyPosition({\n            start: token.start,\n            end: token.end,\n          }) +\n          \"): a different token (`\" +\n          open.type +\n          \"`, \" +\n          stringifyPosition({\n            start: open.start,\n            end: open.end,\n          }) +\n          \") is open\",\n      )\n    }\n    node.position.end = point2(token.end)\n    return node\n  }\n  function resume() {\n    return toString(this.stack.pop())\n  }\n  function onenterlistordered() {\n    setData(\"expectingFirstListItemValue\", true)\n  }\n  function onenterlistitemvalue(token) {\n    if (getData(\"expectingFirstListItemValue\")) {\n      const ancestor = this.stack[this.stack.length - 2]\n      ancestor.start = Number.parseInt(this.sliceSerialize(token), 10)\n      setData(\"expectingFirstListItemValue\")\n    }\n  }\n  function onexitcodefencedfenceinfo() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.lang = data2\n  }\n  function onexitcodefencedfencemeta() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.meta = data2\n  }\n  function onexitcodefencedfence() {\n    if (getData(\"flowCodeInside\")) return\n    this.buffer()\n    setData(\"flowCodeInside\", true)\n  }\n  function onexitcodefenced() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.value = data2.replace(/^(\\r?\\n|\\r)|(\\r?\\n|\\r)$/g, \"\")\n    setData(\"flowCodeInside\")\n  }\n  function onexitcodeindented() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.value = data2.replace(/(\\r?\\n|\\r)$/g, \"\")\n  }\n  function onexitdefinitionlabelstring(token) {\n    const label = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.label = label\n    node.identifier = normalizeIdentifier(\n      this.sliceSerialize(token),\n    ).toLowerCase()\n  }\n  function onexitdefinitiontitlestring() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.title = data2\n  }\n  function onexitdefinitiondestinationstring() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.url = data2\n  }\n  function onexitatxheadingsequence(token) {\n    const node = this.stack[this.stack.length - 1]\n    if (!node.depth) {\n      const depth = this.sliceSerialize(token).length\n      node.depth = depth\n    }\n  }\n  function onexitsetextheadingtext() {\n    setData(\"setextHeadingSlurpLineEnding\", true)\n  }\n  function onexitsetextheadinglinesequence(token) {\n    const node = this.stack[this.stack.length - 1]\n    node.depth = this.sliceSerialize(token).charCodeAt(0) === 61 ? 1 : 2\n  }\n  function onexitsetextheading() {\n    setData(\"setextHeadingSlurpLineEnding\")\n  }\n  function onenterdata(token) {\n    const parent = this.stack[this.stack.length - 1]\n    let tail = parent.children[parent.children.length - 1]\n    if (!tail || tail.type !== \"text\") {\n      tail = text3()\n      tail.position = {\n        start: point2(token.start),\n      }\n      parent.children.push(tail)\n    }\n    this.stack.push(tail)\n  }\n  function onexitdata(token) {\n    const tail = this.stack.pop()\n    tail.value += this.sliceSerialize(token)\n    tail.position.end = point2(token.end)\n  }\n  function onexitlineending(token) {\n    const context = this.stack[this.stack.length - 1]\n    if (getData(\"atHardBreak\")) {\n      const tail = context.children[context.children.length - 1]\n      tail.position.end = point2(token.end)\n      setData(\"atHardBreak\")\n      return\n    }\n    if (\n      !getData(\"setextHeadingSlurpLineEnding\") &&\n      config.canContainEols.includes(context.type)\n    ) {\n      onenterdata.call(this, token)\n      onexitdata.call(this, token)\n    }\n  }\n  function onexithardbreak() {\n    setData(\"atHardBreak\", true)\n  }\n  function onexithtmlflow() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.value = data2\n  }\n  function onexithtmltext() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.value = data2\n  }\n  function onexitcodetext() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.value = data2\n  }\n  function onexitlink() {\n    const context = this.stack[this.stack.length - 1]\n    if (getData(\"inReference\")) {\n      context.type += \"Reference\"\n      context.referenceType = getData(\"referenceType\") || \"shortcut\"\n      delete context.url\n      delete context.title\n    } else {\n      delete context.identifier\n      delete context.label\n    }\n    setData(\"referenceType\")\n  }\n  function onexitimage() {\n    const context = this.stack[this.stack.length - 1]\n    if (getData(\"inReference\")) {\n      context.type += \"Reference\"\n      context.referenceType = getData(\"referenceType\") || \"shortcut\"\n      delete context.url\n      delete context.title\n    } else {\n      delete context.identifier\n      delete context.label\n    }\n    setData(\"referenceType\")\n  }\n  function onexitlabeltext(token) {\n    const ancestor = this.stack[this.stack.length - 2]\n    const string3 = this.sliceSerialize(token)\n    ancestor.label = decodeString(string3)\n    ancestor.identifier = normalizeIdentifier(string3).toLowerCase()\n  }\n  function onexitlabel() {\n    const fragment = this.stack[this.stack.length - 1]\n    const value2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    setData(\"inReference\", true)\n    if (node.type === \"link\") {\n      node.children = fragment.children\n    } else {\n      node.alt = value2\n    }\n  }\n  function onexitresourcedestinationstring() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.url = data2\n  }\n  function onexitresourcetitlestring() {\n    const data2 = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.title = data2\n  }\n  function onexitresource() {\n    setData(\"inReference\")\n  }\n  function onenterreference() {\n    setData(\"referenceType\", \"collapsed\")\n  }\n  function onexitreferencestring(token) {\n    const label = this.resume()\n    const node = this.stack[this.stack.length - 1]\n    node.label = label\n    node.identifier = normalizeIdentifier(\n      this.sliceSerialize(token),\n    ).toLowerCase()\n    setData(\"referenceType\", \"full\")\n  }\n  function onexitcharacterreferencemarker(token) {\n    setData(\"characterReferenceType\", token.type)\n  }\n  function onexitcharacterreferencevalue(token) {\n    const data2 = this.sliceSerialize(token)\n    const type = getData(\"characterReferenceType\")\n    let value2\n    if (type) {\n      value2 = decodeNumericCharacterReference(\n        data2,\n        type === \"characterReferenceMarkerNumeric\" ? 10 : 16,\n      )\n      setData(\"characterReferenceType\")\n    } else {\n      value2 = decodeEntity(data2)\n    }\n    const tail = this.stack.pop()\n    tail.value += value2\n    tail.position.end = point2(token.end)\n  }\n  function onexitautolinkprotocol(token) {\n    onexitdata.call(this, token)\n    const node = this.stack[this.stack.length - 1]\n    node.url = this.sliceSerialize(token)\n  }\n  function onexitautolinkemail(token) {\n    onexitdata.call(this, token)\n    const node = this.stack[this.stack.length - 1]\n    node.url = \"mailto:\" + this.sliceSerialize(token)\n  }\n  function blockQuote2() {\n    return {\n      type: \"blockquote\",\n      children: [],\n    }\n  }\n  function codeFlow() {\n    return {\n      type: \"code\",\n      lang: null,\n      meta: null,\n      value: \"\",\n    }\n  }\n  function codeText2() {\n    return {\n      type: \"inlineCode\",\n      value: \"\",\n    }\n  }\n  function definition2() {\n    return {\n      type: \"definition\",\n      identifier: \"\",\n      label: null,\n      title: null,\n      url: \"\",\n    }\n  }\n  function emphasis() {\n    return {\n      type: \"emphasis\",\n      children: [],\n    }\n  }\n  function heading() {\n    return {\n      type: \"heading\",\n      depth: void 0,\n      children: [],\n    }\n  }\n  function hardBreak() {\n    return {\n      type: \"break\",\n    }\n  }\n  function html() {\n    return {\n      type: \"html\",\n      value: \"\",\n    }\n  }\n  function image() {\n    return {\n      type: \"image\",\n      title: null,\n      url: \"\",\n      alt: null,\n    }\n  }\n  function link() {\n    return {\n      type: \"link\",\n      title: null,\n      url: \"\",\n      children: [],\n    }\n  }\n  function list2(token) {\n    return {\n      type: \"list\",\n      ordered: token.type === \"listOrdered\",\n      start: null,\n      spread: token._spread,\n      children: [],\n    }\n  }\n  function listItem(token) {\n    return {\n      type: \"listItem\",\n      spread: token._spread,\n      checked: null,\n      children: [],\n    }\n  }\n  function paragraph() {\n    return {\n      type: \"paragraph\",\n      children: [],\n    }\n  }\n  function strong() {\n    return {\n      type: \"strong\",\n      children: [],\n    }\n  }\n  function text3() {\n    return {\n      type: \"text\",\n      value: \"\",\n    }\n  }\n  function thematicBreak2() {\n    return {\n      type: \"thematicBreak\",\n    }\n  }\n}\nfunction configure(combined, extensions) {\n  let index2 = -1\n  while (++index2 < extensions.length) {\n    const value2 = extensions[index2]\n    if (Array.isArray(value2)) {\n      configure(combined, value2)\n    } else {\n      extension(combined, value2)\n    }\n  }\n  return combined\n}\nfunction extension(combined, extension2) {\n  let key\n  for (key in extension2) {\n    if (own3.call(extension2, key)) {\n      const list2 = key === \"canContainEols\" || key === \"transforms\"\n      const maybe = own3.call(combined, key) ? combined[key] : void 0\n      const left = maybe || (combined[key] = list2 ? [] : {})\n      const right = extension2[key]\n      if (right) {\n        if (list2) {\n          combined[key] = [...left, ...right]\n        } else {\n          Object.assign(left, right)\n        }\n      }\n    }\n  }\n}\n\n// node_modules/remark-parse/lib/index.js\nfunction remarkParse(options) {\n  const parser = (doc) => {\n    const settings = this.data(\"settings\")\n    return fromMarkdown(\n      doc,\n      Object.assign({}, settings, options, {\n        extensions: this.data(\"micromarkExtensions\") || [],\n        mdastExtensions: this.data(\"fromMarkdownExtensions\") || [],\n      }),\n    )\n  }\n  Object.assign(this, { Parser: parser })\n}\n\n// node_modules/remark-parse/index.js\nvar remark_parse_default = remarkParse\n\n// node_modules/bail/index.js\nfunction bail(error) {\n  if (error) {\n    throw error\n  }\n}\n\n// node_modules/unified/lib/index.js\nvar import_is_buffer2 = __toModule(require_is_buffer())\nvar import_extend = __toModule(require_extend())\n\n// node_modules/is-plain-obj/index.js\nfunction isPlainObject(value2) {\n  if (Object.prototype.toString.call(value2) !== \"[object Object]\") {\n    return false\n  }\n  const prototype = Object.getPrototypeOf(value2)\n  return prototype === null || prototype === Object.prototype\n}\n\n// node_modules/trough/index.js\nfunction trough() {\n  const fns = []\n  const pipeline = { run, use }\n  return pipeline\n  function run(...values) {\n    let middlewareIndex = -1\n    const callback = values.pop()\n    if (typeof callback !== \"function\") {\n      throw new TypeError(\"Expected function as last argument, not \" + callback)\n    }\n    next(null, ...values)\n    function next(error, ...output) {\n      const fn = fns[++middlewareIndex]\n      let index2 = -1\n      if (error) {\n        callback(error)\n        return\n      }\n      while (++index2 < values.length) {\n        if (output[index2] === null || output[index2] === void 0) {\n          output[index2] = values[index2]\n        }\n      }\n      values = output\n      if (fn) {\n        wrap(fn, next)(...output)\n      } else {\n        callback(null, ...output)\n      }\n    }\n  }\n  function use(middelware) {\n    if (typeof middelware !== \"function\") {\n      throw new TypeError(\n        \"Expected `middelware` to be a function, not \" + middelware,\n      )\n    }\n    fns.push(middelware)\n    return pipeline\n  }\n}\nfunction wrap(middleware, callback) {\n  let called\n  return wrapped\n  function wrapped(...parameters) {\n    const fnExpectsCallback = middleware.length > parameters.length\n    let result\n    if (fnExpectsCallback) {\n      parameters.push(done)\n    }\n    try {\n      result = middleware(...parameters)\n    } catch (error) {\n      const exception = error\n      if (fnExpectsCallback && called) {\n        throw exception\n      }\n      return done(exception)\n    }\n    if (!fnExpectsCallback) {\n      if (result instanceof Promise) {\n        result.then(then, done)\n      } else if (result instanceof Error) {\n        done(result)\n      } else {\n        then(result)\n      }\n    }\n  }\n  function done(error, ...output) {\n    if (!called) {\n      called = true\n      callback(error, ...output)\n    }\n  }\n  function then(value2) {\n    done(null, value2)\n  }\n}\n\n// node_modules/vfile/lib/index.js\nvar import_is_buffer = __toModule(require_is_buffer())\n\n// node_modules/vfile-message/index.js\nvar VFileMessage = class extends Error {\n  constructor(reason, place, origin) {\n    var parts = [null, null]\n    var position2 = {\n      start: { line: null, column: null },\n      end: { line: null, column: null },\n    }\n    var index2\n    super()\n    if (typeof place === \"string\") {\n      origin = place\n      place = null\n    }\n    if (typeof origin === \"string\") {\n      index2 = origin.indexOf(\":\")\n      if (index2 === -1) {\n        parts[1] = origin\n      } else {\n        parts[0] = origin.slice(0, index2)\n        parts[1] = origin.slice(index2 + 1)\n      }\n    }\n    if (place) {\n      if (\"type\" in place || \"position\" in place) {\n        if (place.position) {\n          position2 = place.position\n        }\n      } else if (\"start\" in place || \"end\" in place) {\n        position2 = place\n      } else if (\"line\" in place || \"column\" in place) {\n        position2.start = place\n      }\n    }\n    this.name = stringifyPosition(place) || \"1:1\"\n    this.message = typeof reason === \"object\" ? reason.message : reason\n    this.stack = typeof reason === \"object\" ? reason.stack : \"\"\n    this.reason = this.message\n    this.line = position2.start.line\n    this.column = position2.start.column\n    this.source = parts[0]\n    this.ruleId = parts[1]\n    this.position = position2\n    this.file\n    this.fatal\n    this.url\n    this.note\n  }\n}\nVFileMessage.prototype.file = \"\"\nVFileMessage.prototype.name = \"\"\nVFileMessage.prototype.reason = \"\"\nVFileMessage.prototype.message = \"\"\nVFileMessage.prototype.stack = \"\"\nVFileMessage.prototype.fatal = null\nVFileMessage.prototype.column = null\nVFileMessage.prototype.line = null\nVFileMessage.prototype.source = null\nVFileMessage.prototype.ruleId = null\nVFileMessage.prototype.position = null\n\n// node_modules/vfile/lib/minpath.browser.js\nvar path = { basename, dirname, extname, join, sep: \"/\" }\nfunction basename(path2, ext) {\n  if (ext !== void 0 && typeof ext !== \"string\") {\n    throw new TypeError('\"ext\" argument must be a string')\n  }\n  assertPath(path2)\n  let start = 0\n  let end = -1\n  let index2 = path2.length\n  let seenNonSlash\n  if (ext === void 0 || ext.length === 0 || ext.length > path2.length) {\n    while (index2--) {\n      if (path2.charCodeAt(index2) === 47) {\n        if (seenNonSlash) {\n          start = index2 + 1\n          break\n        }\n      } else if (end < 0) {\n        seenNonSlash = true\n        end = index2 + 1\n      }\n    }\n    return end < 0 ? \"\" : path2.slice(start, end)\n  }\n  if (ext === path2) {\n    return \"\"\n  }\n  let firstNonSlashEnd = -1\n  let extIndex = ext.length - 1\n  while (index2--) {\n    if (path2.charCodeAt(index2) === 47) {\n      if (seenNonSlash) {\n        start = index2 + 1\n        break\n      }\n    } else {\n      if (firstNonSlashEnd < 0) {\n        seenNonSlash = true\n        firstNonSlashEnd = index2 + 1\n      }\n      if (extIndex > -1) {\n        if (path2.charCodeAt(index2) === ext.charCodeAt(extIndex--)) {\n          if (extIndex < 0) {\n            end = index2\n          }\n        } else {\n          extIndex = -1\n          end = firstNonSlashEnd\n        }\n      }\n    }\n  }\n  if (start === end) {\n    end = firstNonSlashEnd\n  } else if (end < 0) {\n    end = path2.length\n  }\n  return path2.slice(start, end)\n}\nfunction dirname(path2) {\n  assertPath(path2)\n  if (path2.length === 0) {\n    return \".\"\n  }\n  let end = -1\n  let index2 = path2.length\n  let unmatchedSlash\n  while (--index2) {\n    if (path2.charCodeAt(index2) === 47) {\n      if (unmatchedSlash) {\n        end = index2\n        break\n      }\n    } else if (!unmatchedSlash) {\n      unmatchedSlash = true\n    }\n  }\n  return end < 0\n    ? path2.charCodeAt(0) === 47\n      ? \"/\"\n      : \".\"\n    : end === 1 && path2.charCodeAt(0) === 47\n    ? \"//\"\n    : path2.slice(0, end)\n}\nfunction extname(path2) {\n  assertPath(path2)\n  let index2 = path2.length\n  let end = -1\n  let startPart = 0\n  let startDot = -1\n  let preDotState = 0\n  let unmatchedSlash\n  while (index2--) {\n    const code = path2.charCodeAt(index2)\n    if (code === 47) {\n      if (unmatchedSlash) {\n        startPart = index2 + 1\n        break\n      }\n      continue\n    }\n    if (end < 0) {\n      unmatchedSlash = true\n      end = index2 + 1\n    }\n    if (code === 46) {\n      if (startDot < 0) {\n        startDot = index2\n      } else if (preDotState !== 1) {\n        preDotState = 1\n      }\n    } else if (startDot > -1) {\n      preDotState = -1\n    }\n  }\n  if (\n    startDot < 0 ||\n    end < 0 ||\n    preDotState === 0 ||\n    (preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)\n  ) {\n    return \"\"\n  }\n  return path2.slice(startDot, end)\n}\nfunction join(...segments) {\n  let index2 = -1\n  let joined\n  while (++index2 < segments.length) {\n    assertPath(segments[index2])\n    if (segments[index2]) {\n      joined =\n        joined === void 0 ? segments[index2] : joined + \"/\" + segments[index2]\n    }\n  }\n  return joined === void 0 ? \".\" : normalize(joined)\n}\nfunction normalize(path2) {\n  assertPath(path2)\n  const absolute = path2.charCodeAt(0) === 47\n  let value2 = normalizeString(path2, !absolute)\n  if (value2.length === 0 && !absolute) {\n    value2 = \".\"\n  }\n  if (value2.length > 0 && path2.charCodeAt(path2.length - 1) === 47) {\n    value2 += \"/\"\n  }\n  return absolute ? \"/\" + value2 : value2\n}\nfunction normalizeString(path2, allowAboveRoot) {\n  let result = \"\"\n  let lastSegmentLength = 0\n  let lastSlash = -1\n  let dots = 0\n  let index2 = -1\n  let code\n  let lastSlashIndex\n  while (++index2 <= path2.length) {\n    if (index2 < path2.length) {\n      code = path2.charCodeAt(index2)\n    } else if (code === 47) {\n      break\n    } else {\n      code = 47\n    }\n    if (code === 47) {\n      if (lastSlash === index2 - 1 || dots === 1) {\n      } else if (lastSlash !== index2 - 1 && dots === 2) {\n        if (\n          result.length < 2 ||\n          lastSegmentLength !== 2 ||\n          result.charCodeAt(result.length - 1) !== 46 ||\n          result.charCodeAt(result.length - 2) !== 46\n        ) {\n          if (result.length > 2) {\n            lastSlashIndex = result.lastIndexOf(\"/\")\n            if (lastSlashIndex !== result.length - 1) {\n              if (lastSlashIndex < 0) {\n                result = \"\"\n                lastSegmentLength = 0\n              } else {\n                result = result.slice(0, lastSlashIndex)\n                lastSegmentLength = result.length - 1 - result.lastIndexOf(\"/\")\n              }\n              lastSlash = index2\n              dots = 0\n              continue\n            }\n          } else if (result.length > 0) {\n            result = \"\"\n            lastSegmentLength = 0\n            lastSlash = index2\n            dots = 0\n            continue\n          }\n        }\n        if (allowAboveRoot) {\n          result = result.length > 0 ? result + \"/..\" : \"..\"\n          lastSegmentLength = 2\n        }\n      } else {\n        if (result.length > 0) {\n          result += \"/\" + path2.slice(lastSlash + 1, index2)\n        } else {\n          result = path2.slice(lastSlash + 1, index2)\n        }\n        lastSegmentLength = index2 - lastSlash - 1\n      }\n      lastSlash = index2\n      dots = 0\n    } else if (code === 46 && dots > -1) {\n      dots++\n    } else {\n      dots = -1\n    }\n  }\n  return result\n}\nfunction assertPath(path2) {\n  if (typeof path2 !== \"string\") {\n    throw new TypeError(\n      \"Path must be a string. Received \" + JSON.stringify(path2),\n    )\n  }\n}\n\n// node_modules/vfile/lib/minproc.browser.js\nvar proc = { cwd }\nfunction cwd() {\n  return \"/\"\n}\n\n// node_modules/vfile/lib/minurl.shared.js\nfunction isUrl(fileURLOrPath) {\n  return (\n    fileURLOrPath !== null &&\n    typeof fileURLOrPath === \"object\" &&\n    fileURLOrPath.href &&\n    fileURLOrPath.origin\n  )\n}\n\n// node_modules/vfile/lib/minurl.browser.js\nfunction urlToPath(path2) {\n  if (typeof path2 === \"string\") {\n    path2 = new URL(path2)\n  } else if (!isUrl(path2)) {\n    const error = new TypeError(\n      'The \"path\" argument must be of type string or an instance of URL. Received `' +\n        path2 +\n        \"`\",\n    )\n    error.code = \"ERR_INVALID_ARG_TYPE\"\n    throw error\n  }\n  if (path2.protocol !== \"file:\") {\n    const error = new TypeError(\"The URL must be of scheme file\")\n    error.code = \"ERR_INVALID_URL_SCHEME\"\n    throw error\n  }\n  return getPathFromURLPosix(path2)\n}\nfunction getPathFromURLPosix(url) {\n  if (url.hostname !== \"\") {\n    const error = new TypeError(\n      'File URL host must be \"localhost\" or empty on darwin',\n    )\n    error.code = \"ERR_INVALID_FILE_URL_HOST\"\n    throw error\n  }\n  const pathname = url.pathname\n  let index2 = -1\n  while (++index2 < pathname.length) {\n    if (\n      pathname.charCodeAt(index2) === 37 &&\n      pathname.charCodeAt(index2 + 1) === 50\n    ) {\n      const third = pathname.charCodeAt(index2 + 2)\n      if (third === 70 || third === 102) {\n        const error = new TypeError(\n          \"File URL path must not include encoded / characters\",\n        )\n        error.code = \"ERR_INVALID_FILE_URL_PATH\"\n        throw error\n      }\n    }\n  }\n  return decodeURIComponent(pathname)\n}\n\n// node_modules/vfile/lib/index.js\nvar order = [\"history\", \"path\", \"basename\", \"stem\", \"extname\", \"dirname\"]\nvar VFile = class {\n  constructor(value2) {\n    let options\n    if (!value2) {\n      options = {}\n    } else if (\n      typeof value2 === \"string\" ||\n      (0, import_is_buffer.default)(value2)\n    ) {\n      options = { value: value2 }\n    } else if (isUrl(value2)) {\n      options = { path: value2 }\n    } else {\n      options = value2\n    }\n    this.data = {}\n    this.messages = []\n    this.history = []\n    this.cwd = proc.cwd()\n    this.value\n    this.stored\n    this.result\n    this.map\n    let index2 = -1\n    while (++index2 < order.length) {\n      const prop2 = order[index2]\n      if (prop2 in options && options[prop2] !== void 0) {\n        this[prop2] = prop2 === \"history\" ? [...options[prop2]] : options[prop2]\n      }\n    }\n    let prop\n    for (prop in options) {\n      if (!order.includes(prop)) this[prop] = options[prop]\n    }\n  }\n  get path() {\n    return this.history[this.history.length - 1]\n  }\n  set path(path2) {\n    if (isUrl(path2)) {\n      path2 = urlToPath(path2)\n    }\n    assertNonEmpty(path2, \"path\")\n    if (this.path !== path2) {\n      this.history.push(path2)\n    }\n  }\n  get dirname() {\n    return typeof this.path === \"string\" ? path.dirname(this.path) : void 0\n  }\n  set dirname(dirname2) {\n    assertPath2(this.basename, \"dirname\")\n    this.path = path.join(dirname2 || \"\", this.basename)\n  }\n  get basename() {\n    return typeof this.path === \"string\" ? path.basename(this.path) : void 0\n  }\n  set basename(basename2) {\n    assertNonEmpty(basename2, \"basename\")\n    assertPart(basename2, \"basename\")\n    this.path = path.join(this.dirname || \"\", basename2)\n  }\n  get extname() {\n    return typeof this.path === \"string\" ? path.extname(this.path) : void 0\n  }\n  set extname(extname2) {\n    assertPart(extname2, \"extname\")\n    assertPath2(this.dirname, \"extname\")\n    if (extname2) {\n      if (extname2.charCodeAt(0) !== 46) {\n        throw new Error(\"`extname` must start with `.`\")\n      }\n      if (extname2.includes(\".\", 1)) {\n        throw new Error(\"`extname` cannot contain multiple dots\")\n      }\n    }\n    this.path = path.join(this.dirname, this.stem + (extname2 || \"\"))\n  }\n  get stem() {\n    return typeof this.path === \"string\"\n      ? path.basename(this.path, this.extname)\n      : void 0\n  }\n  set stem(stem) {\n    assertNonEmpty(stem, \"stem\")\n    assertPart(stem, \"stem\")\n    this.path = path.join(this.dirname || \"\", stem + (this.extname || \"\"))\n  }\n  toString(encoding) {\n    return (this.value || \"\").toString(encoding)\n  }\n  message(reason, place, origin) {\n    const message = new VFileMessage(reason, place, origin)\n    if (this.path) {\n      message.name = this.path + \":\" + message.name\n      message.file = this.path\n    }\n    message.fatal = false\n    this.messages.push(message)\n    return message\n  }\n  info(reason, place, origin) {\n    const message = this.message(reason, place, origin)\n    message.fatal = null\n    return message\n  }\n  fail(reason, place, origin) {\n    const message = this.message(reason, place, origin)\n    message.fatal = true\n    throw message\n  }\n}\nfunction assertPart(part, name) {\n  if (part && part.includes(path.sep)) {\n    throw new Error(\n      \"`\" + name + \"` cannot be a path: did not expect `\" + path.sep + \"`\",\n    )\n  }\n}\nfunction assertNonEmpty(part, name) {\n  if (!part) {\n    throw new Error(\"`\" + name + \"` cannot be empty\")\n  }\n}\nfunction assertPath2(path2, name) {\n  if (!path2) {\n    throw new Error(\"Setting `\" + name + \"` requires `path` to be set too\")\n  }\n}\n\n// node_modules/unified/lib/index.js\nvar unified = base().freeze()\nvar own4 = {}.hasOwnProperty\nfunction base() {\n  const transformers = trough()\n  const attachers = []\n  let namespace = {}\n  let frozen\n  let freezeIndex = -1\n  processor.data = data\n  processor.Parser = void 0\n  processor.Compiler = void 0\n  processor.freeze = freeze\n  processor.attachers = attachers\n  processor.use = use\n  processor.parse = parse3\n  processor.stringify = stringify\n  processor.run = run\n  processor.runSync = runSync\n  processor.process = process\n  processor.processSync = processSync\n  return processor\n  function processor() {\n    const destination = base()\n    let index2 = -1\n    while (++index2 < attachers.length) {\n      destination.use(...attachers[index2])\n    }\n    destination.data((0, import_extend.default)(true, {}, namespace))\n    return destination\n  }\n  function data(key, value2) {\n    if (typeof key === \"string\") {\n      if (arguments.length === 2) {\n        assertUnfrozen(\"data\", frozen)\n        namespace[key] = value2\n        return processor\n      }\n      return (own4.call(namespace, key) && namespace[key]) || null\n    }\n    if (key) {\n      assertUnfrozen(\"data\", frozen)\n      namespace = key\n      return processor\n    }\n    return namespace\n  }\n  function freeze() {\n    if (frozen) {\n      return processor\n    }\n    while (++freezeIndex < attachers.length) {\n      const [attacher, ...options] = attachers[freezeIndex]\n      if (options[0] === false) {\n        continue\n      }\n      if (options[0] === true) {\n        options[1] = void 0\n      }\n      const transformer = attacher.call(processor, ...options)\n      if (typeof transformer === \"function\") {\n        transformers.use(transformer)\n      }\n    }\n    frozen = true\n    freezeIndex = Number.POSITIVE_INFINITY\n    return processor\n  }\n  function use(value2, ...options) {\n    let settings\n    assertUnfrozen(\"use\", frozen)\n    if (value2 === null || value2 === void 0) {\n    } else if (typeof value2 === \"function\") {\n      addPlugin(value2, ...options)\n    } else if (typeof value2 === \"object\") {\n      if (Array.isArray(value2)) {\n        addList(value2)\n      } else {\n        addPreset(value2)\n      }\n    } else {\n      throw new TypeError(\"Expected usable value, not `\" + value2 + \"`\")\n    }\n    if (settings) {\n      namespace.settings = Object.assign(namespace.settings || {}, settings)\n    }\n    return processor\n    function add(value3) {\n      if (typeof value3 === \"function\") {\n        addPlugin(value3)\n      } else if (typeof value3 === \"object\") {\n        if (Array.isArray(value3)) {\n          const [plugin, ...options2] = value3\n          addPlugin(plugin, ...options2)\n        } else {\n          addPreset(value3)\n        }\n      } else {\n        throw new TypeError(\"Expected usable value, not `\" + value3 + \"`\")\n      }\n    }\n    function addPreset(result) {\n      addList(result.plugins)\n      if (result.settings) {\n        settings = Object.assign(settings || {}, result.settings)\n      }\n    }\n    function addList(plugins) {\n      let index2 = -1\n      if (plugins === null || plugins === void 0) {\n      } else if (Array.isArray(plugins)) {\n        while (++index2 < plugins.length) {\n          const thing = plugins[index2]\n          add(thing)\n        }\n      } else {\n        throw new TypeError(\"Expected a list of plugins, not `\" + plugins + \"`\")\n      }\n    }\n    function addPlugin(plugin, value3) {\n      let index2 = -1\n      let entry\n      while (++index2 < attachers.length) {\n        if (attachers[index2][0] === plugin) {\n          entry = attachers[index2]\n          break\n        }\n      }\n      if (entry) {\n        if (isPlainObject(entry[1]) && isPlainObject(value3)) {\n          value3 = (0, import_extend.default)(true, entry[1], value3)\n        }\n        entry[1] = value3\n      } else {\n        attachers.push([...arguments])\n      }\n    }\n  }\n  function parse3(doc) {\n    processor.freeze()\n    const file = vfile(doc)\n    const Parser = processor.Parser\n    assertParser(\"parse\", Parser)\n    if (newable(Parser, \"parse\")) {\n      return new Parser(String(file), file).parse()\n    }\n    return Parser(String(file), file)\n  }\n  function stringify(node, doc) {\n    processor.freeze()\n    const file = vfile(doc)\n    const Compiler = processor.Compiler\n    assertCompiler(\"stringify\", Compiler)\n    assertNode(node)\n    if (newable(Compiler, \"compile\")) {\n      return new Compiler(node, file).compile()\n    }\n    return Compiler(node, file)\n  }\n  function run(node, doc, callback) {\n    assertNode(node)\n    processor.freeze()\n    if (!callback && typeof doc === \"function\") {\n      callback = doc\n      doc = void 0\n    }\n    if (!callback) {\n      return new Promise(executor)\n    }\n    executor(null, callback)\n    function executor(resolve, reject) {\n      transformers.run(node, vfile(doc), done)\n      function done(error, tree, file) {\n        tree = tree || node\n        if (error) {\n          reject(error)\n        } else if (resolve) {\n          resolve(tree)\n        } else {\n          callback(null, tree, file)\n        }\n      }\n    }\n  }\n  function runSync(node, file) {\n    let result\n    let complete\n    processor.run(node, file, done)\n    assertDone(\"runSync\", \"run\", complete)\n    return result\n    function done(error, tree) {\n      bail(error)\n      result = tree\n      complete = true\n    }\n  }\n  function process(doc, callback) {\n    processor.freeze()\n    assertParser(\"process\", processor.Parser)\n    assertCompiler(\"process\", processor.Compiler)\n    if (!callback) {\n      return new Promise(executor)\n    }\n    executor(null, callback)\n    function executor(resolve, reject) {\n      const file = vfile(doc)\n      processor.run(processor.parse(file), file, (error, tree, file2) => {\n        if (error || !tree || !file2) {\n          done(error)\n        } else {\n          const result = processor.stringify(tree, file2)\n          if (result === void 0 || result === null) {\n          } else if (looksLikeAVFileValue(result)) {\n            file2.value = result\n          } else {\n            file2.result = result\n          }\n          done(error, file2)\n        }\n      })\n      function done(error, file2) {\n        if (error || !file2) {\n          reject(error)\n        } else if (resolve) {\n          resolve(file2)\n        } else {\n          callback(null, file2)\n        }\n      }\n    }\n  }\n  function processSync(doc) {\n    let complete\n    processor.freeze()\n    assertParser(\"processSync\", processor.Parser)\n    assertCompiler(\"processSync\", processor.Compiler)\n    const file = vfile(doc)\n    processor.process(file, done)\n    assertDone(\"processSync\", \"process\", complete)\n    return file\n    function done(error) {\n      complete = true\n      bail(error)\n    }\n  }\n}\nfunction newable(value2, name) {\n  return (\n    typeof value2 === \"function\" &&\n    value2.prototype &&\n    (keys(value2.prototype) || name in value2.prototype)\n  )\n}\nfunction keys(value2) {\n  let key\n  for (key in value2) {\n    if (own4.call(value2, key)) {\n      return true\n    }\n  }\n  return false\n}\nfunction assertParser(name, value2) {\n  if (typeof value2 !== \"function\") {\n    throw new TypeError(\"Cannot `\" + name + \"` without `Parser`\")\n  }\n}\nfunction assertCompiler(name, value2) {\n  if (typeof value2 !== \"function\") {\n    throw new TypeError(\"Cannot `\" + name + \"` without `Compiler`\")\n  }\n}\nfunction assertUnfrozen(name, frozen) {\n  if (frozen) {\n    throw new Error(\n      \"Cannot call `\" +\n        name +\n        \"` on a frozen processor.\\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.\",\n    )\n  }\n}\nfunction assertNode(node) {\n  if (!isPlainObject(node) || typeof node.type !== \"string\") {\n    throw new TypeError(\"Expected node, got `\" + node + \"`\")\n  }\n}\nfunction assertDone(name, asyncName, complete) {\n  if (!complete) {\n    throw new Error(\n      \"`\" + name + \"` finished async. Use `\" + asyncName + \"` instead\",\n    )\n  }\n}\nfunction vfile(value2) {\n  return looksLikeAVFile(value2) ? value2 : new VFile(value2)\n}\nfunction looksLikeAVFile(value2) {\n  return Boolean(\n    value2 &&\n      typeof value2 === \"object\" &&\n      \"message\" in value2 &&\n      \"messages\" in value2,\n  )\n}\nfunction looksLikeAVFileValue(value2) {\n  return typeof value2 === \"string\" || (0, import_is_buffer2.default)(value2)\n}\n\n// node_modules/annotatedtext-remark/out/index.js\nvar defaults2 = {\n  children(node) {\n    return defaults.children(node)\n  },\n  annotatetextnode(node, text3) {\n    return defaults.annotatetextnode(node, text3)\n  },\n  interpretmarkup(text3 = \"\") {\n    return \"\\n\".repeat((text3.match(/\\n/g) || []).length)\n  },\n  remarkoptions: {},\n}\nfunction build2(text3, options = defaults2) {\n  const processor = unified()\n    .use(remark_parse_default, options.remarkoptions)\n    .use(remarkFrontmatter, [\"yaml\", \"toml\"])\n  return build(text3, processor.parse, options)\n}\n\n// lib/prepareMarkdown.mjs\nvar prepareMarkdown = (text3) => JSON.stringify(build2(text3))\nvar prepareMarkdown_default = prepareMarkdown\n/*!\n * Determine if an object is a Buffer\n *\n * @author   Feross Aboukhadijeh <https://feross.org>\n * @license  MIT\n */\n"
  },
  {
    "path": "src/utils/stripStyles.js",
    "content": "/**\n * Strips terminal styles from string\n * (colors, weight etc.)\n *\n * @param {string} text any string\n */\nconst stripStyles = (text) => {\n  // eslint-disable-next-line no-control-regex\n  const regex = /[\\u001b\\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g\n\n  return text.replace(regex, \"\")\n}\n\nmodule.exports = stripStyles\n"
  },
  {
    "path": "src/utils/stripStyles.test.js",
    "content": "const kleur = require(\"kleur\")\nconst stripStyles = require(\"./stripStyles\")\n\ndescribe(\"Strips styles from console string\", () => {\n  it(\"strips colors\", () => {\n    const input = kleur.red(\"foo\")\n    const expected = \"foo\"\n    const result = stripStyles(input)\n\n    expect(result).toEqual(expected)\n  })\n\n  it(\"strips background colors\", () => {\n    const input = kleur.bgRed(\"foo\")\n    const expected = \"foo\"\n    const result = stripStyles(input)\n\n    expect(result).toEqual(expected)\n  })\n\n  it(\"strips font style\", () => {\n    const input = kleur\n      .bold()\n      .italic()\n      .underline()\n      .strikethrough()\n      .dim(\"foo\")\n    const expected = \"foo\"\n    const result = stripStyles(input)\n\n    expect(result).toEqual(expected)\n  })\n})\n"
  },
  {
    "path": "src/utils/unzipFile.js",
    "content": "const decompress = require(\"decompress\")\nconst decompressUnzip = require(\"decompress-unzip\")\n\nconst unzipFile = (pathToFile, outputFolder) => {\n  return decompress(pathToFile, outputFolder, {\n    plugins: [decompressUnzip()],\n  })\n}\n\nmodule.exports = unzipFile\n"
  },
  {
    "path": "src/validators/languages.js",
    "content": "const languages = require(\"../../data/languages.json\")\n\nconst languageOptions = [\n  \"config\",\n  \"auto\",\n  ...languages.map((language) => language.longCode),\n]\n\nconst isLanguage = (value) => {\n  return languageOptions.includes(value)\n}\n\nmodule.exports = {\n  languageOptions,\n  isLanguage,\n}\n"
  },
  {
    "path": "src/validators/rules.js",
    "content": "const rules = require(\"../../data/rules.json\")\n\nconst ruleOptions = rules.map((rule) => rule.id.toLowerCase())\n\nconst isRule = (value) => {\n  return ruleOptions.includes(value)\n}\n\nmodule.exports = {\n  ruleOptions,\n  isRule,\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"include\": [\"src/index.js\"],\n  \"compilerOptions\": {\n    \"allowJs\": true,\n    \"declaration\": true,\n    \"emitDeclarationOnly\": true,\n    \"outDir\": \"src/types\"\n  }\n}\n"
  }
]