[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_size = 2\nindent_style = space\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".github/workflows/bb.yml",
    "content": "jobs:\n  main:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: unifiedjs/beep-boop-beta@main\n        with:\n          repo-token: ${{secrets.GITHUB_TOKEN}}\nname: bb\non:\n  issues:\n    types: [closed, edited, labeled, opened, reopened, unlabeled]\n  pull_request_target:\n    types: [closed, edited, labeled, opened, reopened, unlabeled]\n"
  },
  {
    "path": ".github/workflows/main.yml",
    "content": "jobs:\n  small:\n    env:\n      PUPPETEER_SKIP_DOWNLOAD: 1\n    name: test / ${{matrix.os}} / ${{matrix.node}}\n    runs-on: ${{matrix.os}}\n    steps:\n      - uses: actions/checkout@v5\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-node@v4\n        with:\n          cache: npm\n          node-version: ${{matrix.node}}\n      - run: npm ci\n      - run: npm run test-api\n    strategy:\n      matrix:\n        include:\n          - node: lts/iron\n            os: ubuntu-latest\n        node:\n          - lts/*\n        os:\n          - macos-latest\n          - windows-latest\n  full:\n    env:\n      PUPPETEER_SKIP_DOWNLOAD: 1\n    name: full build\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v5\n        with:\n          fetch-depth: 0\n      - uses: actions/setup-node@v4\n        with:\n          cache: npm\n          node-version: lts/*\n      - run: npm ci\n      - run: npm test\n      - uses: codecov/codecov-action@v5\nname: main\non:\n  - pull_request\n  - push\n"
  },
  {
    "path": ".github/workflows/website.yml",
    "content": "jobs:\n  deploy:\n    environment:\n      name: Website\n      url: ${{steps.deployment.outputs.page_url}}\n    permissions:\n      contents: read\n      id-token: write\n      pages: write\n    # To do: replace w/ `ubuntu-latest` when upstream is solved:\n    # <https://github.com/puppeteer/puppeteer/issues/12818>.\n    runs-on: ubuntu-22.04\n    steps:\n      - uses: actions/checkout@v5\n      - uses: actions/setup-node@v4\n        with:\n          node-version: lts/*\n      - run: npm ci\n      - run: npm run docs\n      - uses: actions/upload-pages-artifact@v4\n        with:\n          path: public\n      - uses: actions/deploy-pages@v4\n        id: deployment\nname: website\non:\n  push:\n    branches:\n      - main\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\ncoverage/\nnode_modules/\n*.d.cts\n*.d.ts\n*.map\n*.tsbuildinfo\n/public/\n!/packages/mdx/lib/types.d.ts\n!/website/types.d.ts\n"
  },
  {
    "path": ".prettierignore",
    "content": "node_modules/\ncoverage/\npublic/\n*.md\n*.mdx\n"
  },
  {
    "path": ".vercelignore",
    "content": "node_modules/\n"
  },
  {
    "path": "changelog.md",
    "content": "# Changelog\n\nSee [GitHub Releases][releases] for the changelog.\n\n[releases]: https://github.com/mdx-js/mdx/releases\n"
  },
  {
    "path": "docs/.remarkrc.js",
    "content": "/**\n * @import {CheckFlag} from 'remark-lint-fenced-code-flag'\n * @import {Preset} from 'unified'\n */\n\nimport remarkPresetWooorm from 'remark-preset-wooorm'\nimport remarkLintFencedCodeFlag, {\n  checkGithubLinguistFlag\n} from 'remark-lint-fenced-code-flag'\nimport remarkLintNoHtml from 'remark-lint-no-html'\nimport remarkValidateLinks from 'remark-validate-links'\n\n/** @type {Preset} */\nconst remarkPresetMdx = {\n  plugins: [\n    remarkPresetWooorm,\n    [remarkLintFencedCodeFlag, check],\n    [remarkLintNoHtml, false],\n    [remarkValidateLinks, false]\n  ]\n}\n\nexport default remarkPresetMdx\n\n/**\n * Check according to GitHub Linguist.\n *\n * @param {string} value\n *   Language flag to check.\n * @returns {string | undefined}\n *   Whether the flag is valid (`undefined`),\n *   or a message to warn about (`string`).\n * @satisfies {CheckFlag}\n */\nfunction check(value) {\n  // To do: investigate if we can change ` ```jsx ` -> ` ```js `?\n  if (value === 'jsx' || value === 'mdx-invalid') return undefined\n  return checkGithubLinguistFlag(value)\n}\n"
  },
  {
    "path": "docs/404.mdx",
    "content": "import {Note} from './_component/note.jsx'\n\nexport {Home as default} from './_component/home.jsx'\nexport const navExclude = true\n\n# 404: Not found\n\nAww, snap.\nUnfortunately this page doesn’t exist.\nPerhaps you can find what you’re looking for [on GitHub][search]?\n\n<Note type=\"info\">\n  **Note**: Did you come here from a website linking to it?\n  Pretty sure this page used to exist?\n  Please [open an issue](https://github.com/mdx-js/mdx/issues/new) to let us\n  know so we can fix it!\n</Note>\n\n[search]: https://github.com/mdx-js/mdx/search\n"
  },
  {
    "path": "docs/_asset/editor.jsx",
    "content": "/* @jsxRuntime automatic */\n/* @jsxImportSource react */\n\n/* eslint-disable unicorn/prefer-global-this */\n\n/**\n * @import {Grammar} from '@wooorm/starry-night'\n * @import {Node as EstreeNode, Program} from 'estree'\n * @import {Nodes as HastNodes, Root as HastRoot} from 'hast'\n * @import {Nodes as MdastNodes, Root as MdastRoot} from 'mdast'\n * @import {\n    MdxJsxAttribute,\n    MdxJsxAttributeValueExpression,\n    MdxJsxExpressionAttribute\n * } from 'mdast-util-mdx-jsx'\n * @import {MDXModule} from 'mdx/types.js'\n * @import {ReactNode} from 'react'\n * @import {FallbackProps} from 'react-error-boundary'\n * @import {PluggableList} from 'unified'\n * @import {Node as UnistNode} from 'unist'\n */\n\n/**\n * @typedef DisplayProperties\n *   Properties.\n * @property {Error} error\n *   Error.\n *\n * @typedef EvalNok\n *   Not OK.\n * @property {false} ok\n *   Whether OK.\n * @property {Error} value\n *   Error.\n *\n * @typedef EvalOk\n *   OK.\n * @property {true} ok\n *   Whether OK.\n * @property {ReactNode} value\n *   Result.\n *\n * @typedef {EvalNok | EvalOk} EvalResult\n *   Result.\n */\n\nimport {compile, nodeTypes, run} from '@mdx-js/mdx'\nimport {createStarryNight} from '@wooorm/starry-night'\nimport sourceCss from '@wooorm/starry-night/source.css'\nimport sourceJs from '@wooorm/starry-night/source.js'\nimport sourceJson from '@wooorm/starry-night/source.json'\nimport sourceMdx from '@wooorm/starry-night/source.mdx'\nimport sourceTs from '@wooorm/starry-night/source.ts'\nimport sourceTsx from '@wooorm/starry-night/source.tsx'\nimport textHtmlBasic from '@wooorm/starry-night/text.html.basic'\nimport textMd from '@wooorm/starry-night/text.md'\nimport {visit as visitEstree} from 'estree-util-visit'\nimport {toJsxRuntime} from 'hast-util-to-jsx-runtime'\nimport {useEffect, useState} from 'react'\nimport {Fragment, jsx, jsxs} from 'react/jsx-runtime'\nimport ReactDom from 'react-dom/client'\nimport {ErrorBoundary} from 'react-error-boundary'\nimport rehypeRaw from 'rehype-raw'\nimport remarkDirective from 'remark-directive'\nimport remarkFrontmatter from 'remark-frontmatter'\nimport remarkGfm from 'remark-gfm'\nimport remarkMath from 'remark-math'\nimport {removePosition} from 'unist-util-remove-position'\nimport {visit} from 'unist-util-visit'\nimport {VFile} from 'vfile'\n\nconst sample = `# Hello, world!\n\nBelow is an example of markdown in JSX.\n\n<div style={{backgroundColor: 'violet', padding: '1rem'}}>\n  Try and change the background color to \\`tomato\\`.\n</div>`\n\n/** @type {ReadonlyArray<Grammar>} */\nconst grammars = [\n  sourceCss,\n  sourceJs,\n  sourceJson,\n  sourceMdx,\n  sourceTs,\n  sourceTsx,\n  textHtmlBasic,\n  textMd\n]\n\n/** @type {Awaited<ReturnType<typeof createStarryNight>>} */\nlet starryNight\n\nconst editor = document.querySelector('#js-editor')\n\nif (window.location.pathname === '/playground/' && editor) {\n  const root = document.createElement('div')\n  root.classList.add('playground')\n  editor.after(root)\n  init(root)\n}\n\n/**\n * @param {Element} main\n *   DOM element.\n * @returns {undefined}\n *   Nothing.\n */\nfunction init(main) {\n  const root = ReactDom.createRoot(main)\n\n  createStarryNight(grammars).then(\n    /**\n     * @returns {undefined}\n     *   Nothing.\n     */\n    function (x) {\n      starryNight = x\n\n      const missing = starryNight.missingScopes()\n      if (missing.length > 0) {\n        throw new Error('Unexpected missing required scopes: `' + missing + '`')\n      }\n\n      root.render(<Playground />)\n    }\n  )\n}\n\nfunction Playground() {\n  const [directive, setDirective] = useState(false)\n  const [evalResult, setEvalResult] = useState(\n    // Cast to more easily use actual value.\n    /** @type {unknown} */ (undefined)\n  )\n  const [development, setDevelopment] = useState(false)\n  const [frontmatter, setFrontmatter] = useState(false)\n  const [gfm, setGfm] = useState(false)\n  const [formatMarkdown, setFormatMarkdown] = useState(false)\n  const [generateJsx, setGenerateJsx] = useState(false)\n  const [math, setMath] = useState(false)\n  const [outputFormatFunctionBody, setOutputFormatFunctionBody] =\n    useState(false)\n  const [positions, setPositions] = useState(false)\n  const [raw, setRaw] = useState(false)\n  const [show, setShow] = useState('result')\n  const [value, setValue] = useState(sample)\n\n  useEffect(\n    function () {\n      go().then(\n        function (ok) {\n          setEvalResult({ok: true, value: ok})\n        },\n        /**\n         * @param {Error} error\n         *   Error.\n         * @returns {undefined}\n         *   Nothing.\n         */\n        function (error) {\n          setEvalResult({ok: false, value: error})\n        }\n      )\n\n      async function go() {\n        /** @type {PluggableList} */\n        const recmaPlugins = []\n        /** @type {PluggableList} */\n        const rehypePlugins = []\n        /** @type {PluggableList} */\n        const remarkPlugins = []\n\n        if (directive) remarkPlugins.unshift(remarkDirective)\n        if (frontmatter) remarkPlugins.unshift(remarkFrontmatter)\n        if (gfm) remarkPlugins.unshift(remarkGfm)\n        if (math) remarkPlugins.unshift(remarkMath)\n        if (raw) rehypePlugins.unshift([rehypeRaw, {passThrough: nodeTypes}])\n\n        const file = new VFile({\n          basename: formatMarkdown ? 'example.md' : 'example.mdx',\n          value\n        })\n\n        if (show === 'esast') recmaPlugins.push([captureEsast])\n        if (show === 'hast') rehypePlugins.push([captureHast])\n        if (show === 'mdast') remarkPlugins.push([captureMdast])\n        /** @type {UnistNode | undefined} */\n        let ast\n\n        await compile(file, {\n          development: show === 'result' ? false : development,\n          jsx: show === 'code' || show === 'esast' ? generateJsx : false,\n          outputFormat:\n            show === 'result' || outputFormatFunctionBody\n              ? 'function-body'\n              : 'program',\n          recmaPlugins,\n          rehypePlugins,\n          remarkPlugins\n        })\n\n        if (show === 'result') {\n          /** @type {MDXModule} */\n          const result = await run(String(file), {\n            Fragment,\n            jsx,\n            jsxs,\n            baseUrl: window.location.href\n          })\n\n          return (\n            <ErrorBoundary\n              FallbackComponent={ErrorFallback}\n              resetKeys={[value]}\n            >\n              <div className=\"playground-result\">{result.default({})}</div>\n            </ErrorBoundary>\n          )\n        }\n\n        if (ast) {\n          return (\n            <pre>\n              <code>\n                {toJsxRuntime(\n                  starryNight.highlight(\n                    JSON.stringify(ast, undefined, 2),\n                    'source.json'\n                  ),\n                  {Fragment, jsx, jsxs}\n                )}\n              </code>\n            </pre>\n          )\n        }\n\n        // `show === 'code'`\n        return (\n          <pre>\n            <code>\n              {toJsxRuntime(starryNight.highlight(String(file), 'source.js'), {\n                Fragment,\n                jsx,\n                jsxs\n              })}\n            </code>\n          </pre>\n        )\n\n        function captureMdast() {\n          /**\n           * @param {MdastRoot} tree\n           *   Tree.\n           * @returns {undefined}\n           *   Nothing.\n           */\n          return function (tree) {\n            const clone = structuredClone(tree)\n            if (!positions) cleanUnistTree(clone)\n            ast = clone\n          }\n        }\n\n        function captureHast() {\n          /**\n           * @param {HastRoot} tree\n           *   Tree.\n           * @returns {undefined}\n           *   Nothing.\n           */\n          return function (tree) {\n            const clone = structuredClone(tree)\n            if (!positions) cleanUnistTree(clone)\n            ast = clone\n          }\n        }\n\n        function captureEsast() {\n          /**\n           * @param {Program} tree\n           *   Tree.\n           * @returns {undefined}\n           *   Nothing.\n           */\n          return function (tree) {\n            const clone = structuredClone(tree)\n            if (!positions) visitEstree(clone, removeFromEstree)\n            ast = clone\n          }\n        }\n      }\n    },\n    [\n      development,\n      directive,\n      frontmatter,\n      gfm,\n      generateJsx,\n      formatMarkdown,\n      math,\n      outputFormatFunctionBody,\n      positions,\n      raw,\n      show,\n      value\n    ]\n  )\n\n  const scope = formatMarkdown ? 'text.md' : 'source.mdx'\n  // Cast to actual value.\n  const compiledResult = /** @type {EvalResult | undefined} */ (evalResult)\n  /** @type {ReactNode | undefined} */\n  let display\n\n  if (compiledResult) {\n    if (compiledResult.ok) {\n      display = compiledResult.value\n    } else {\n      display = (\n        <div>\n          <p>Could not compile code:</p>\n          <DisplayError error={compiledResult.value} />\n        </div>\n      )\n    }\n  }\n\n  return (\n    <>\n      <form>\n        <div className=\"playground-area\">\n          <div className=\"playground-inner\">\n            <div className=\"playground-draw\">\n              {toJsxRuntime(starryNight.highlight(value, scope), {\n                Fragment,\n                jsx,\n                jsxs\n              })}\n              {/* Trailing whitespace in a `textarea` is shown, but not in a `div`\n          with `white-space: pre-wrap`.\n          Add a `br` to make the last newline explicit. */}\n              {/\\n[ \\t]*$/.test(value) ? <br /> : undefined}\n            </div>\n            <textarea\n              spellCheck=\"false\"\n              className=\"playground-write\"\n              value={value}\n              rows={value.split('\\n').length + 1}\n              onChange={function (event) {\n                setValue(event.target.value)\n              }}\n            />\n          </div>\n        </div>\n        <div className=\"playground-controls\">\n          <fieldset>\n            <legend>Show</legend>\n            <label>\n              <select\n                name=\"show\"\n                onChange={function (event) {\n                  setShow(event.target.value)\n                }}\n              >\n                <option value=\"result\">evaluated result</option>\n                <option value=\"code\">compiled code</option>\n                <option value=\"mdast\">mdast (markdown)</option>\n                <option value=\"hast\">hast (html)</option>\n                <option value=\"esast\">esast (javascript)</option>\n              </select>{' '}\n            </label>\n          </fieldset>\n          <fieldset>\n            <legend>Plugin</legend>\n            <label>\n              <input\n                type=\"checkbox\"\n                name=\"directive\"\n                checked={directive}\n                onChange={function () {\n                  setDirective(!directive)\n                }}\n              />{' '}\n              use{' '}\n              <a href=\"https://github.com/remarkjs/remark-directive\">\n                <code>remark-directive</code>\n              </a>\n            </label>\n            <label>\n              <input\n                type=\"checkbox\"\n                name=\"frontmatter\"\n                checked={frontmatter}\n                onChange={function () {\n                  setFrontmatter(!frontmatter)\n                }}\n              />{' '}\n              use{' '}\n              <a href=\"https://github.com/remarkjs/remark-frontmatter\">\n                <code>remark-frontmatter</code>\n              </a>\n            </label>\n            <label>\n              <input\n                type=\"checkbox\"\n                name=\"gfm\"\n                checked={gfm}\n                onChange={function () {\n                  setGfm(!gfm)\n                }}\n              />{' '}\n              use{' '}\n              <a href=\"https://github.com/remarkjs/remark-gfm\">\n                <code>remark-gfm</code>\n              </a>\n            </label>\n            <label>\n              <input\n                type=\"checkbox\"\n                name=\"math\"\n                checked={math}\n                onChange={function () {\n                  setMath(!math)\n                }}\n              />{' '}\n              use{' '}\n              <a href=\"https://github.com/remarkjs/remark-math\">\n                <code>remark-math</code>\n              </a>\n            </label>\n            <label>\n              <input\n                type=\"checkbox\"\n                name=\"raw\"\n                checked={raw}\n                onChange={function () {\n                  setRaw(!raw)\n                }}\n              />{' '}\n              use{' '}\n              <a href=\"https://github.com/rehypejs/rehype-raw\">\n                <code>rehype-raw</code>\n              </a>\n            </label>\n          </fieldset>\n          <fieldset>\n            <legend>Input format</legend>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"language\"\n                checked={!formatMarkdown}\n                onChange={function () {\n                  setFormatMarkdown(false)\n                }}\n              />{' '}\n              MDX (<code>format: &apos;mdx&apos;</code>)\n            </label>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"language\"\n                checked={formatMarkdown}\n                onChange={function () {\n                  setFormatMarkdown(true)\n                }}\n              />{' '}\n              markdown (<code>format: &apos;markdown&apos;</code>)\n            </label>\n          </fieldset>\n\n          <fieldset disabled={show === 'result'}>\n            <legend>Output format</legend>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"output-format\"\n                checked={outputFormatFunctionBody}\n                onChange={function () {\n                  setOutputFormatFunctionBody(true)\n                }}\n              />{' '}\n              function body (\n              <code>outputFormat: &apos;function-body&apos;</code>)\n            </label>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"output-format\"\n                checked={!outputFormatFunctionBody}\n                onChange={function () {\n                  setOutputFormatFunctionBody(false)\n                }}\n              />{' '}\n              program (<code>outputFormat: &apos;program&apos;</code>)\n            </label>\n          </fieldset>\n\n          <fieldset disabled={show === 'result'}>\n            <legend>Development</legend>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"development\"\n                checked={development}\n                onChange={function () {\n                  setDevelopment(true)\n                }}\n              />{' '}\n              generate for development (<code>development: true</code>)\n            </label>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"development\"\n                checked={!development}\n                onChange={function () {\n                  setDevelopment(false)\n                }}\n              />{' '}\n              generate for production (<code>development: false</code>)\n            </label>\n          </fieldset>\n\n          <fieldset disabled={show === 'result'}>\n            <legend>JSX</legend>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"jsx\"\n                checked={generateJsx}\n                onChange={function () {\n                  setGenerateJsx(true)\n                }}\n              />{' '}\n              keep JSX (<code>jsx: true</code>)\n            </label>\n            <label>\n              <input\n                type=\"radio\"\n                name=\"jsx\"\n                checked={!generateJsx}\n                onChange={function () {\n                  setGenerateJsx(false)\n                }}\n              />{' '}\n              compile JSX away (<code>jsx: false</code>)\n            </label>\n          </fieldset>\n\n          <fieldset disabled={show === 'result' || show === 'code'}>\n            <legend>Tree</legend>\n            <label>\n              <input\n                type=\"checkbox\"\n                name=\"positions\"\n                checked={positions}\n                onChange={function () {\n                  setPositions(!positions)\n                }}\n              />{' '}\n              show <code>position</code> in tree\n            </label>\n          </fieldset>\n        </div>\n      </form>\n      {display}\n    </>\n  )\n}\n\n/**\n *\n * @param {Readonly<FallbackProps>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nfunction ErrorFallback(properties) {\n  // type-coverage:ignore-next-line\n  const error = /** @type {Error} */ (properties.error)\n  return (\n    <div role=\"alert\">\n      <p>Something went wrong:</p>\n      <DisplayError error={error} />\n      <button type=\"button\" onClick={properties.resetErrorBoundary}>\n        Try again\n      </button>\n    </div>\n  )\n}\n\n/**\n * @param {DisplayProperties} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nfunction DisplayError(properties) {\n  return (\n    <pre>\n      <code>\n        {String(\n          properties.error.stack\n            ? properties.error.message + '\\n' + properties.error.stack\n            : properties.error\n        )}\n      </code>\n    </pre>\n  )\n}\n\n/**\n * @param {HastRoot | MdastRoot} node\n *   mdast or hast root.\n * @returns {undefined}\n *   Nothing.\n */\nfunction cleanUnistTree(node) {\n  removePosition(node, {force: true})\n  visit(node, cleanUnistNode)\n}\n\n/**\n * @param {HastNodes | MdastNodes | MdxJsxAttribute | MdxJsxAttributeValueExpression | MdxJsxExpressionAttribute} node\n *   Node.\n * @returns {undefined}\n *   Nothing.\n */\nfunction cleanUnistNode(node) {\n  if (\n    node.type === 'mdxJsxAttribute' &&\n    'value' in node &&\n    node.value &&\n    typeof node.value === 'object'\n  ) {\n    cleanUnistNode(node.value)\n  }\n\n  if (\n    'attributes' in node &&\n    node.attributes &&\n    Array.isArray(node.attributes)\n  ) {\n    for (const attribute of node.attributes) {\n      removePosition(attribute, {force: true})\n      cleanUnistNode(attribute)\n    }\n  }\n\n  if (node.data && 'estree' in node.data && node.data.estree) {\n    visitEstree(node.data.estree, removeFromEstree)\n  }\n}\n\n/**\n * @param {EstreeNode} node\n *   estree node.\n * @returns {undefined}\n *   Nothing.\n */\nfunction removeFromEstree(node) {\n  delete node.loc\n  delete node.start\n  delete node.end\n  delete node.range\n}\n"
  },
  {
    "path": "docs/_asset/index.css",
    "content": ":root {\n  --sans:\n    system-ui, -apple-system, blinkmacsystemfont, 'Segoe UI', helvetica, arial,\n    sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';\n  --mono:\n    'San Francisco Mono', 'Monaco', 'Consolas', 'Lucida Console',\n    'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;\n  --white: #fff;\n  --black: #1b1f24;\n  --gray-0: #f6f8fa;\n  --gray-1: #eaeef2;\n  --gray-2: #d0d7de;\n  --gray-3: #afb8c1;\n  --gray-4: #8c959f;\n  --gray-5: #6e7781;\n  --gray-6: #57606a;\n  --gray-7: #424a53;\n  --gray-8: #32383f;\n  --gray-9: #24292f;\n  --blue-0: #ddf4ff;\n  --blue-5: #0969da;\n  --blue-9: #002155;\n  --green-0: #dafbe1;\n  --green-5: #1a7f37;\n  --green-9: #002d11;\n  --yellow-0: #fff8c5;\n  --yellow-5: #9a6700;\n  --yellow-9: #3b2300;\n  --orange-0: #fff1e5;\n  --orange-5: #bc4c00;\n  --orange-9: #471700;\n  --red-0: #ffebe9;\n  --red-5: #cf222e;\n  --red-9: #4c0014;\n  --purple-0: #fbefff;\n  --purple-5: #8250df;\n  --purple-9: #2e1461;\n  --pink-0: #ffeff7;\n  --pink-5: #bf3989;\n  --pink-9: #4d0336;\n  --coral-0: #fff0eb;\n  --coral-5: #c4432b;\n  --coral-9: #510901;\n  --mdx-yellow: hsl(39deg 97% 58%);\n  --hl: var(--blue-5);\n  --fg: var(--black);\n  --bg: var(--white);\n\n  /* We manually add a blur on `::before` of the container, so no background needed. */\n  --docsearch-container-background: transparent !important;\n  --docsearch-footer-background: var(--white) !important;\n  --docsearch-footer-shadow: 0 -1px 0 0 var(--gray-2) !important;\n  --docsearch-highlight-color: var(--hl) !important;\n  --docsearch-hit-color: var(--gray-7) !important;\n  --docsearch-hit-shadow: inset 0 0 0 1px var(--gray-2) !important;\n  /* This is actually used in a `background` field so does not have to be a gradient. */\n  --docsearch-key-gradient: var(--gray-0) !important;\n  --docsearch-key-pressed-shadow: none !important;\n  --docsearch-key-shadow: inset 0 -1px 0 var(--gray-4) !important;\n  --docsearch-modal-background: var(--white) !important;\n  /* Card shadow: <https://github.com/unifiedjs/unifiedjs.github.io/blob/4de0391/asset/index.css#L399> */\n  --docsearch-modal-shadow:\n    0 0 0 0.2em rgb(3 102 214 / 0%), 0 13px 27px -5px rgb(50 50 93 / 25%),\n    0 8px 16px -8px rgb(0 0 0 / 30%), 0 -6px 16px -6px rgb(0 0 0 / 2.5%) !important;\n  /* Use the regular color: */\n  --docsearch-muted-color: var(--black) !important;\n  --docsearch-primary-color: var(--hl) !important;\n  --docsearch-searchbox-background: var(--white) !important;\n  --docsearch-searchbox-focus-background: var(--gray-0) !important;\n  --docsearch-searchbox-shadow: inset 0 0 0 2px var(--hl) !important;\n  --docsearch-text-color: var(--black) !important;\n}\n\n* {\n  box-sizing: border-box;\n}\n\nhtml {\n  color-scheme: light dark;\n  accent-color: var(--hl);\n  -ms-text-size-adjust: 100%;\n  -webkit-text-size-adjust: 100%;\n  word-wrap: break-word;\n  font-kerning: normal;\n  font-family: var(--sans);\n  font-feature-settings: 'kern', 'liga', 'clig', 'calt';\n  line-height: calc(1em + 1ex);\n}\n\nbutton,\ninput {\n  font-family: inherit;\n  font-size: inherit;\n}\n\nkbd,\npre,\ncode,\n.playground-write,\n.playground-draw {\n  font-family: var(--mono);\n  font-feature-settings: normal;\n  font-size: smaller;\n  line-height: calc(1em + (1 / 0.8 * 1ex));\n}\n\nbody {\n  margin: 0;\n  background-color: var(--bg);\n  color: var(--fg);\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nstrong,\nth {\n  font-weight: 700;\n  letter-spacing: 0.0125em;\n}\n\nsup {\n  vertical-align: top;\n}\n\nmain {\n  margin-block-start: calc(5.5 * (1em + 1ex));\n}\n\ndd,\n.content {\n  padding-inline: calc(1em + 1ex);\n}\n\nlabel {\n  display: block;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nlabel,\np,\npre,\nol,\nul,\nhr,\ntable,\nblockquote,\n.block,\n.frame {\n  margin-block: calc(1em + 1ex);\n}\n\nsummary {\n  cursor: pointer;\n}\n\n.anchor {\n  display: inline-block;\n  width: calc(1em + 1ex);\n  margin-inline-start: calc(-0.75 * (1em + 1ex));\n  margin-inline-end: calc(-0.25 * (1em + 1ex));\n  font-size: 1rem;\n}\n\na[name],\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n  display: block;\n  scroll-margin-block-start: 6rem;\n}\n\nh1,\nh2 {\n  font-size: 2.5em;\n  line-height: calc(1em + (1 / 2.5 * 1ex));\n  margin-block: calc(1 / 2.5 * (1em + 1ex));\n}\n\n.head-article,\n.foot-article,\n.foot-site {\n  position: relative;\n}\n\n.foot-site {\n  background-color: var(--gray-0);\n}\n\n.foot-article,\n.foot-site {\n  margin-block-start: calc(1 * (1em + 1ex));\n  border-block-start: 1px solid var(--gray-2);\n}\n\n.head-article {\n  margin-block-end: calc(1 * (1em + 1ex));\n}\n\n.navigation,\n.head-article {\n  border-block-end: 1px solid var(--gray-2);\n}\n\n.article-row {\n  display: flex;\n  justify-content: space-between;\n}\n\n.article-row-start,\n.article-row-end {\n  font-size: smaller;\n  line-height: calc(1em + (1 / 0.8 * 1ex));\n  flex-basis: 0;\n  flex-grow: 1;\n}\n\n.article-row-end {\n  margin-inline-start: auto;\n  text-align: end;\n}\n\n.foot-site {\n  padding-block: 1px;\n}\n\nh3 {\n  font-size: 2em;\n  line-height: calc(1em + (1 / 1.5 * 1ex));\n  margin-block: calc(1 / 1.5 * (1em + 1ex));\n}\n\nh4 {\n  font-size: 1.25em;\n  line-height: calc(1em + (1 / 1.25 * 1ex));\n  margin-block: calc(1 / 1.25 * (1em + 1ex));\n}\n\nh5,\nh6 {\n  font-size: 1em;\n  line-height: calc(1em + 1ex);\n  margin-block: calc(1em + 1ex);\n}\n\nh6 {\n  color: var(--gray-6);\n}\n\nimg,\nsvg {\n  max-width: 100%;\n  background-color: transparent;\n}\n\nimg[align='right'] {\n  padding-inline-start: calc(1em + 1ex);\n}\n\nimg[align='left'] {\n  padding-inline-end: calc(1em + 1ex);\n}\n\nkbd {\n  background-color: var(--gray-0);\n  border: 1px solid var(--gray-3);\n  border-radius: 3px;\n  box-shadow: inset 0 -1px 0 var(--gray-4);\n  color: var(--gray-9);\n  padding: 0.2em 0.4em;\n}\n\npre {\n  word-wrap: normal;\n  overflow: auto;\n  font-size: inherit;\n}\n\nblockquote pre,\nli pre {\n  margin-inline: 0;\n}\n\ncode {\n  background-color: var(--gray-0);\n}\n\ncode {\n  border-radius: 3px;\n  padding-block: calc(0.33 * (1 / 0.8 * 1ex));\n  padding-inline: calc(0.66 * (1 / 0.8 * 1ex));\n}\n\npre code {\n  display: block;\n  padding: calc(1em + 1ex) !important;\n  white-space: pre;\n  word-break: normal;\n  overflow-x: auto;\n  /* overflow: visible; */\n  word-wrap: normal;\n\n  mask-image: paint(squircle);\n  --squircle-radius: 10px;\n  border-radius: 10px;\n}\n\n.frame-tab-item {\n  background-color: var(--gray-1);\n  transition: 200ms;\n  transition-property: color, background-color;\n}\n\npre code,\n.frame-body,\n.frame-tab-item-selected {\n  background-color: #fafafa !important; /* Color from one-light */\n}\n\n.frame-body-box {\n  padding: calc(1em + 1ex);\n}\n\n.frame-tab-item-dark.frame-tab-item-selected {\n  background-color: #282c34 !important;\n  color: var(--white);\n}\n\n.frame-body > pre:only-child {\n  margin-block: 0;\n}\n\n.frame-tab-item-inactive {\n  background-color: transparent;\n  color: var(--gray-6);\n}\n\nhr {\n  background-color: var(--gray-1);\n  border: 0;\n  border-radius: 3px;\n  height: calc(0.25 * (1em + 1ex));\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n  overflow: auto;\n  width: 100%;\n  font-variant-numeric: lining-nums;\n}\n\ntr {\n  border-block-start: 1px solid var(--gray-3);\n}\n\ntr:nth-child(even) {\n  background-color: hsl(210deg 17% 82% / 20%); /* gray-1 */\n}\n\ntd,\nth {\n  border: 1px solid var(--gray-3);\n  padding-block: calc(0.33 * (1 / 0.8 * 1ex));\n  padding-inline: calc(0.66 * (1 / 0.8 * 1ex));\n}\n\nblockquote {\n  color: var(--gray-6);\n  margin-inline-start: 0;\n  padding-inline-start: calc(1em + 1ex);\n  position: relative;\n}\n\nblockquote::before {\n  content: '';\n  display: block;\n  width: calc(0.25 * (1em + 1ex));\n  height: 100%;\n  background-color: var(--gray-1);\n  border-radius: 3px;\n  position: absolute;\n  inset-inline-start: 0;\n}\n\nol,\nul {\n  padding-inline-start: 0;\n}\n\nul {\n  list-style-type: circle;\n}\n\nol {\n  list-style-type: decimal;\n}\n\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-block: 0;\n}\n\nul ul {\n  list-style-type: disc;\n}\n\nul ul ul {\n  list-style-type: square;\n}\n\nol ol {\n  list-style-type: lower-roman;\n}\n\nol ol ol {\n  list-style-type: lower-alpha;\n}\n\nli {\n  word-wrap: break-all;\n  margin-block: calc(0.25 * (1em + 1ex));\n  margin-inline-start: calc(1em + 1ex);\n}\n\n.task-list-item {\n  list-style-type: none;\n  margin-inline-start: 0;\n}\n\n.task-list-item input {\n  margin: 0;\n  margin-inline-end: calc(0.25 * (1em + 1ex));\n}\n\ndt {\n  font-style: italic;\n  margin-block-end: 0;\n}\n\ndt + dt {\n  margin-block-start: 0;\n}\n\ndd {\n  margin-block-start: 0;\n}\n\na {\n  color: var(--hl);\n  transition: 200ms;\n  transition-property: color;\n}\n\na.alt {\n  color: var(--purple-5);\n}\n\n.navigation a {\n  display: block;\n  color: inherit;\n  text-decoration: none;\n}\n\na[aria-current],\na:hover,\na:focus {\n  color: inherit;\n  text-decoration: none;\n}\n\nnav a[aria-current],\nnav a:hover,\nnav a:focus {\n  color: var(--hl);\n  text-decoration: underline;\n}\n\nbutton,\na.cta {\n  outline: 0;\n  padding: calc(0.25 * (1em + 1ex)) calc(0.5 * (1em + 1ex));\n  border-radius: 3px;\n  border: 1px solid currentColor;\n  color: var(--black);\n  transition: 200ms;\n  transition-property: color, background-color, border-color, box-shadow;\n  font-weight: 400;\n  background-color: transparent;\n}\n\na.cta:hover,\na.cta:focus,\na.cta:active,\nbutton:hover,\nbutton:focus,\nbutton:active {\n  color: var(--hl);\n}\n\na.cta:active,\nbutton:active,\na.cta.active,\nbutton.active {\n  background-color: var(--hl);\n  border-color: var(--hl);\n  color: var(--white);\n}\n\na.cta:active,\na.cta.active,\na.cta:focus,\nbutton.active,\nbutton:active,\nbutton:focus {\n  box-shadow: 0 0 0 0.2em rgb(191 135 0 / 30%); /* --hl */\n}\n\na.cta.success,\nbutton.success {\n  background-color: var(--green-5);\n  border-color: var(--green-5);\n  box-shadow: 0 0 0 0.2em rgb(26 127 55 / 30%); /* --green-5 */\n  color: var(--white);\n}\n\n.content {\n  width: 100%;\n  max-width: calc(36 * (1em + 1ex));\n  margin: calc(1 * (1em + 1ex)) auto;\n}\n\n.navigation {\n  position: fixed;\n  inset-inline: 0;\n  inset-block-start: 0;\n  display: flex;\n  padding: calc(0.5 * (1em + 1ex));\n  padding-top: calc(2 * (1em + 1ex));\n}\n\n.navigation::before,\n.DocSearch-Container::before {\n  content: '';\n  inset: 0;\n  position: absolute;\n  z-index: 2;\n  background-image: radial-gradient(\n    ellipse at 50% 0%,\n    hsl(39deg 97% 88% / 90%) 0%,\n    hsl(39deg 97% 96% / 90%) 100%\n  );\n}\n\n.DocSearch li {\n  margin: 0;\n}\n\n#banner {\n  padding: calc(0.25 * (1em + 1ex));\n  background-color: var(--mdx-yellow);\n  color: var(--white);\n  position: absolute;\n  left: 0;\n  top: 0;\n  right: 0;\n  text-align: center;\n  z-index: 10;\n  font-weight: bolder;\n  letter-spacing: 1px;\n}\n\n.full-bleed {\n  width: 100vw;\n  position: relative;\n  left: 50%;\n  right: 50%;\n  margin-left: -50vw;\n  margin-right: -50vw;\n  padding-inline: calc(1em + 1ex);\n}\n\n/* Note that the `backdrop-filter` itself is applied in light mode. */\n@supports (backdrop-filter: blur(1ex)) {\n  .navigation::before,\n  .DocSearch-Container::before {\n    backdrop-filter: saturate(200%) blur(1ex);\n    background-image: radial-gradient(\n      ellipse at 50% 0%,\n      hsl(39deg 97% 88% / 60%) 0%,\n      hsl(39deg 97% 98% / 60%) 80%\n    );\n  }\n}\n\n.DocSearch-Modal,\n.navigation-primary,\n.navigation-secondary,\n.navigation-search,\n.navigation-tertiary {\n  z-index: 3;\n}\n\n.navigation .icon {\n  display: block;\n  width: auto;\n  height: calc(1em + 1ex);\n}\n\n.navigation-primary,\n.navigation-secondary,\n.navigation-tertiary,\n.navigation-primary h1,\n.navigation-secondary li,\n.navigation-tertiary li {\n  margin: 0;\n}\n\n.navigation-primary,\n.navigation-secondary,\n.navigation-search,\n.navigation-tertiary {\n  margin: 0;\n  padding: calc(0.5 * (1em + 1ex));\n  display: flex;\n  list-style-type: none;\n}\n\n.navigation-search {\n  padding: calc(0.25em + 0.25ex);\n}\n\n.DocSearch-Button {\n  margin: 0 !important;\n}\n\n.navigation-primary h1,\n.navigation-secondary li,\n.navigation-tertiary li {\n  padding: 0;\n}\n\n.navigation-primary h1 {\n  font-size: 1em;\n  border-bottom-width: 0;\n}\n\n.navigation-tertiary {\n  justify-content: flex-end;\n}\n\n.navigation-secondary {\n  z-index: 3;\n  overflow-x: auto;\n  overflow-y: hidden;\n  flex: 1;\n  flex-direction: row;\n  align-items: stretch;\n  flex-grow: 1;\n  mask-image: linear-gradient(\n    to right,\n    transparent,\n    black 2ex,\n    black calc(100% - 2ex),\n    transparent\n  );\n}\n\n.navigation-secondary li {\n  white-space: nowrap;\n}\n\n.navigation-secondary li + li {\n  padding-inline-start: calc(0.5 * (1em + 1ex));\n}\n\n/* Some extra spacing because otherwise the blur is shown over it. */\n.navigation-secondary li:last-child {\n  padding-inline-end: calc(0.5 * (1em + 1ex));\n}\n\n.navigation-secondary ol,\n.navigation-show-big {\n  display: none;\n}\n\n.navigation-tertiary li + li {\n  padding-inline-start: calc(0.5 * (1em + 1ex));\n}\n\n.skip-to-navigation {\n  inset-block-start: 0;\n  inset-inline-start: 0;\n}\n\n.skip-to-content,\n.skip-to-navigation {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: 0;\n  overflow: hidden;\n  clip: rect(1px, 1px, 1px, 1px);\n}\n\n.skip-to-content:focus,\n.skip-to-navigation:focus {\n  z-index: 4;\n  width: auto;\n  height: auto;\n  clip: auto;\n  background-color: var(--hl);\n  color: var(--white);\n  padding: calc(1em + 1ex);\n}\n\n.note {\n  color: var(--gray-9);\n  font-size: smaller;\n  line-height: calc(1em + (1 / 0.8 * 1ex));\n  padding-inline: calc(1 / 0.8 * (1em + 1ex));\n  margin-block: calc(1 / 0.8 * (1em + 1ex));\n  position: relative;\n  z-index: 0;\n  inset: 0;\n  mask-image: paint(squircle);\n  --squircle-radius: 10px;\n  border-radius: 10px;\n  border: 1px solid transparent;\n\n  /* Actually the border color: */\n  background-color: var(--purple-5);\n}\n\n.note::after {\n  content: '';\n  position: absolute;\n  mask-image: paint(squircle);\n  z-index: -1;\n  background-color: hsl(9deg 64% 8%);\n  inset: 0;\n  --squircle-radius: 9px;\n  border-radius: 9px;\n\n  background-color: var(--purple-0);\n}\n\n.legacy {\n  background-color: var(--gray-5);\n}\n\n.legacy::after {\n  background-color: var(--gray-0);\n}\n\n.important {\n  background-color: var(--red-5);\n}\n\n.important::after {\n  background-color: var(--red-0);\n}\n\n.card {\n  display: block;\n  padding: calc(1 * (1em + 1ex));\n  margin-block: calc(2 * (1em + 1ex));\n  overflow: hidden;\n  /* yellow */\n  background-image:\n    radial-gradient(\n      ellipse at 0% 0%,\n      rgb(252 180 45 / 5%) 20%,\n      rgb(252 180 45 / 0%) 80%\n    ),\n    /* purple */\n      radial-gradient(\n        ellipse at 0% 100%,\n        rgb(130 80 223 / 5%) 20%,\n        rgb(130 80 223 / 0%) 80%\n      );\n\n  mask-image: paint(squircle);\n  --squircle-radius: 20px;\n  border-radius: 20px;\n}\n\n.emoji-list > ul {\n  list-style-type: none;\n}\n\n.emoji-list > ul > li {\n  margin-inline-start: 0;\n}\n\n.big {\n  font-size: larger;\n  line-height: calc(1em + (1 / 1.2 * 1ex));\n  padding: calc(1 / 1.2 * (1em + 1ex));\n  margin-block: calc(1 / 1.2 * (1em + 1ex));\n}\n\n.frame {\n  /* gray-1 is used for unselected tabs, but gray-2 is really too much\n   * This is a perfect mix between the two: */\n  background-color: hsl(210, 20.5%, 88.8%);\n  position: relative;\n\n  mask-image: paint(squircle);\n  --squircle-radius: 10px;\n  border-radius: 10px;\n}\n\n.frame-resizeable {\n  display: flex;\n  flex-direction: column;\n  overflow: auto;\n\n  min-height: 10rem;\n  height: 24rem;\n  resize: vertical;\n}\n\n.frame-tab-bar {\n  flex-shrink: 0;\n  display: flex;\n  flex-direction: row;\n  align-items: stretch;\n  margin-block-start: calc(1em + 1ex);\n  list-style-type: none;\n  margin: 0;\n  padding: calc(0.25em + 0.25ex);\n  padding-block-end: 0;\n}\n\n.frame-tab-bar-scroll {\n  overflow-x: auto;\n  overflow-y: hidden;\n  mask-image: linear-gradient(\n    to right,\n    hsl(0deg 0% 100% / 30%),\n    black calc(0.5 * (1em + 1ex)),\n    black calc(100% - 0.5 * (1em + 1ex)),\n    hsl(0deg 0% 100% / 30%)\n  );\n}\n\n.frame-body {\n  border-bottom-left-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n.frame-body > pre {\n  flex-grow: 1;\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n}\n\n.frame-body > pre > code {\n  overflow-x: auto;\n  overflow-y: auto;\n}\n\n.frame-tab-bar + pre,\n.frame-tab-bar + .highlight > pre {\n  margin-block-start: 0;\n}\n\n.frame-tab-bar + pre code,\n.frame-tab-bar + .highlight > pre code {\n  --squircle-radius: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n\n.frame-tab-item {\n  font-family: var(--mono);\n  font-size: smaller;\n  line-height: calc(1em + (1 / 0.8 * 1ex));\n  padding-block: calc(1 / 0.8 * 0.25 * (1em + 1ex));\n  padding-inline: calc(1 / 0.8 * 0.5 * (1em + 1ex));\n  margin: calc(1 / 0.8 * 0.25 * (1em + 1ex));\n  margin-block-end: 0;\n  border-top-left-radius: 2px;\n  border-top-right-radius: 2px;\n  white-space: nowrap;\n}\n\n.frame-tab-item-language {\n  margin-left: auto;\n  padding-inline: 0;\n}\n\n.code-frame .copy-button {\n  position: absolute;\n  inset-block-end: 0;\n  inset-inline-end: 0;\n  /* Lines it out nicely if there’s just one line of code. */\n  margin: calc(0.618 * (1em + 1ex));\n  backdrop-filter: saturate(200%) blur(1ex);\n}\n\n#markdown-for-thecomponent-era {\n  font-weight: 600;\n}\n\n#markdown-for-thecomponent-era strong {\n  color: var(--mdx-yellow);\n}\n\n.home hr {\n  height: 0;\n  background-color: transparent;\n}\n\n.home-preview {\n  position: relative;\n  border: 1px solid transparent;\n  padding: calc(1em + 1ex);\n  background-color: var(--gray-2);\n  mask-image: paint(squircle);\n  z-index: 0;\n  --squircle-radius: 10px;\n  border-radius: 10px;\n}\n\n.home-preview::after {\n  content: '';\n  position: absolute;\n  inset: 0;\n  z-index: -1;\n  background-color: var(--bg);\n  mask-image: paint(squircle);\n  --squircle-radius: 9px;\n  border-radius: 9px;\n}\n\n:is(.home-preview, .card, .frame-body, .nav-description, .big-columns > *)\n  > :is(h1, h2, h3, h4, p, .block):first-child {\n  margin-block-start: 0;\n}\n\n:is(.home-preview, .card, .frame-body, .nav-description, .big-columns > *)\n  > :is(h1, h2, h3, h4, p, .block):last-child {\n  margin-block-end: 0;\n}\n\n.home .anchor {\n  display: none;\n}\n\n.snowfall {\n  display: flex;\n  align-items: flex-end;\n  justify-content: center;\n}\n\n.snowfall-bar {\n  flex-basis: 0;\n  flex-grow: 1;\n  margin: calc(0.125 * (1em + 1ex));\n  background-color: var(--fg);\n}\n\ndetails {\n  border: 1px solid var(--gray-2);\n  padding: 1ex;\n  border-radius: 3px;\n}\n\ndetails[open] {\n  padding: calc(1em + 1ex);\n}\n\n.rehype-twoslash-completion-deprecated {\n  opacity: 0.5;\n}\n\n.rehype-twoslash-popover-target {\n  cursor: default;\n}\n\n.highlight:is(:hover, :focus-within) .rehype-twoslash-popover-target {\n  background-color: var(--gray-2);\n}\n\n/* Wavy underline for errors. */\n.rehype-twoslash-error-target {\n  background-repeat: repeat-x;\n  background-position: bottom left;\n  background-image: url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 6 3\" enable-background=\"new 0 0 6 3\" height=\"3\" width=\"6\"><g fill=\"%23c94824\"><polygon points=\"5.5,0 2.5,3 1.1,3 4.1,0\"/><polygon points=\"4,0 6,2 6,0.6 5.4,0\"/><polygon points=\"0,2 1,3 2.4,3 0,0.6\"/></g></svg>');\n}\n\n/* The content that will be shown in the tooltip. */\n.rehype-twoslash-popover {\n  position: absolute;\n  max-width: calc(45 * (1em + 1ex));\n  padding: calc(0.5 * (1em + 1ex));\n  margin: 0;\n  background-color: var(--bg);\n  border: 1px solid var(--gray-2);\n  border-radius: 3px;\n}\n\n/* No padding if we have a padded code block (and perhaps more blocks) */\n.rehype-twoslash-popover:has(.rehype-twoslash-popover-code) {\n  padding: 0;\n}\n\n.rehype-twoslash-popover-code {\n  margin: 0;\n}\n\n.rehype-twoslash-popover-code > code {\n  mask-image: none;\n  border-radius: 0;\n}\n\n.rehype-twoslash-popover-description {\n  background-color: var(--bg);\n  padding: 0 1em;\n}\n\n@media (prefers-color-scheme: dark) {\n  :root {\n    --white: #f0f6fc;\n    --black: #010409;\n    --gray-0: var(--white);\n    --gray-1: #c9d1d9;\n    --gray-2: #b1bac4;\n    --gray-3: #8b949e;\n    --gray-4: #6e7681;\n    --gray-5: #484f58;\n    --gray-6: #30363d;\n    --gray-7: #21262d;\n    --gray-8: #161b22;\n    --gray-9: #0d1117;\n    --hl: var(--mdx-yellow);\n    --fg: var(--white);\n    --bg: var(--black);\n\n    --docsearch-key-gradient: #eaeef2 !important;\n  }\n\n  .navigation-secondary a {\n    display: initial;\n  }\n\n  .note {\n    color: var(--gray-0);\n  }\n\n  .note::after {\n    background-color: var(--purple-9);\n  }\n\n  .legacy::after {\n    background-color: var(--gray-9);\n  }\n\n  .important::after {\n    background-color: var(--red-9);\n  }\n\n  .navigation::before {\n    background-image: radial-gradient(\n      ellipse at 50% 0%,\n      hsl(39deg 97% 12% / 90%) 0%,\n      hsl(39deg 97% 4% / 90%) 100%\n    );\n  }\n\n  /* Note that the `backdrop-filter` itself is applied in light mode. */\n  @supports (backdrop-filter: blur(1ex)) {\n    .navigation::before {\n      background-image: radial-gradient(\n        ellipse at 50% 0%,\n        hsl(39deg 97% 12% / 60%) 0%,\n        hsl(39deg 97% 4% / 60%) 90%\n      );\n    }\n  }\n\n  .card {\n    /* yellow */\n    background-image:\n      radial-gradient(\n        ellipse at 0% 0%,\n        rgb(252 180 45 / 10%) 20%,\n        rgb(252 180 45 / 0%) 80%\n      ),\n      /* purple */\n        radial-gradient(\n          ellipse at 0% 100%,\n          rgb(130 80 223 / 10%) 20%,\n          rgb(130 80 223 / 0%) 80%\n        );\n  }\n\n  .foot-article,\n  .foot-site {\n    border-top-color: var(--gray-6);\n  }\n\n  .navigation,\n  .head-article {\n    border-bottom-color: var(--gray-6);\n  }\n\n  .home-preview {\n    background-color: var(--gray-6);\n  }\n\n  .foot-site {\n    background-color: var(--gray-8);\n  }\n\n  .highlight:is(:hover, :focus-within) .rehype-twoslash-popover-target {\n    background-color: var(--gray-5);\n  }\n\n  .rehype-twoslash-popover {\n    border-color: var(--gray-6);\n  }\n\n  h6 {\n    color: var(--gray-3);\n  }\n\n  kbd {\n    background-color: var(--black);\n    border-color: var(--gray-6);\n    box-shadow: inset 0 -1px 0 var(--gray-6);\n    color: var(--gray-0);\n  }\n\n  code {\n    background-color: var(--gray-6);\n  }\n\n  .frame {\n    background-color: var(--gray-9);\n  }\n\n  .frame-tab-item {\n    background-color: var(--gray-8);\n  }\n\n  pre code,\n  .frame-body,\n  .frame-tab-item-selected,\n  .frame-tab-item-dark.frame-tab-item-selected {\n    background-color: var(--gray-7) !important;\n  }\n\n  .frame-tab-item-inactive {\n    background-color: transparent;\n    color: var(--gray-3);\n  }\n\n  hr {\n    background-color: var(--gray-6);\n  }\n\n  tr {\n    background-color: var(--gray-9);\n    border-top-color: var(--gray-6);\n  }\n\n  tr:nth-child(2n) {\n    background-color: var(--gray-8);\n    color: var(--white);\n  }\n\n  td,\n  th {\n    border-color: var(--gray-4);\n  }\n\n  blockquote {\n    color: var(--gray-2);\n  }\n\n  blockquote::before {\n    background-color: var(--gray-4);\n  }\n\n  a.cta,\n  button {\n    color: var(--gray-0);\n    border-color: currentColor;\n    background-color: transparent;\n  }\n\n  a.cta:hover,\n  a.cta:focus,\n  a.cta:active,\n  button:hover,\n  button:focus,\n  button:active {\n    border-color: var(--hl);\n  }\n\n  a.cta:active,\n  button:active {\n    background-color: var(--hl);\n    color: var(--gray-0);\n  }\n\n  a.cta.success,\n  button.success {\n    background-color: var(--green-5);\n    border-color: var(--green-5);\n    color: var(--white);\n  }\n\n  details {\n    border-color: var(--gray-6);\n  }\n}\n\n@media (min-width: 22em) {\n  #markdown-for-thecomponent-era {\n    font-size: 2rem;\n    line-height: calc(1em + (1 / 2 * 1ex));\n    margin-block: calc(1 / 2 * (1em + 1ex));\n  }\n}\n\n@media (min-width: 40em) {\n  html {\n    font-size: 1.125em;\n  }\n\n  .navigation-search {\n    padding: calc(0.3em + 0.3ex);\n  }\n\n  #markdown-for-thecomponent-era {\n    font-size: 3rem;\n    line-height: calc(1em + (1 / 3 * 1ex));\n    margin-block: calc(1 / 3 * (1em + 1ex));\n    padding-block: calc(1 / 3 * (1em + 1ex));\n  }\n\n  .foot-article,\n  .foot-site {\n    margin-block-start: calc(2 * (1em + 1ex));\n  }\n\n  .head-article {\n    margin-block-end: calc(2 * (1em + 1ex));\n  }\n\n  .foot-site {\n    padding-block: calc(1 * (1em + 1ex));\n  }\n\n  .big {\n    padding: calc(2 * (1em + 1ex));\n  }\n\n  .big.card {\n    margin-block: calc(2 * (1em + 1ex));\n  }\n}\n\n@media (min-width: 56em) {\n  #markdown-for-thecomponent-era {\n    font-size: 5rem;\n    line-height: calc(1em + (1 / 5 * 1ex));\n    margin-block: calc(1 / 5 * (1em + 1ex));\n    padding-block: calc(2 * 1 / 5 * (1em + 1ex));\n  }\n\n  .playground {\n    display: grid;\n    grid-template-columns: 49% 49%;\n  }\n}\n\n@media (min-width: 64em) {\n  .navigation-show-big {\n    display: block;\n  }\n\n  .big {\n    padding: calc(1.66 * (1em + 1ex));\n  }\n\n  .big.card {\n    margin-block: calc(1.66 * (1em + 1ex));\n  }\n\n  /* Assume they don’t scroll anymore. */\n  .frame-tab-bar-scroll,\n  .navigation-secondary {\n    mask-image: initial;\n  }\n}\n\n@media (min-width: 76em) {\n  #markdown-for-thecomponent-era {\n    font-size: 5.9rem;\n    line-height: calc(1em + (1 / 6 * 1ex));\n    margin-block: calc(1 / 6 * (1em + 1ex));\n  }\n\n  .big-columns {\n    display: flex;\n    justify-content: space-between;\n    margin: 0 calc(-1 * (1em + 1ex));\n  }\n\n  .big-columns > * {\n    width: calc(15 * (1em + 1ex));\n    flex: 1;\n    margin: 0 calc(1em + 1ex);\n  }\n}\n\n.playground {\n  min-height: 40rem;\n  gap: calc(1em + 1ex);\n}\n\n.playground-area,\n.playground-controls,\n.playground-result {\n  overflow: auto;\n  border-radius: 1ex;\n  padding: 1em;\n  margin-block: calc(1em + 1ex);\n}\n\n.playground-area {\n  background-color: rgba(255, 255, 255, 0.1);\n}\n\n.playground-controls,\n.playground-result {\n  border: 1px solid rgba(255, 255, 255, 0.1);\n}\n\n.playground-inner {\n  position: relative;\n  max-width: 100%;\n  overflow: hidden;\n  min-height: calc(10 * (1em + 1ex));\n}\n\n.playground-write,\n.playground-draw {\n  font-size: 14px;\n  tab-size: 4;\n  letter-spacing: normal;\n  line-height: calc(1 * (1em + 1ex));\n  white-space: pre-wrap;\n  word-wrap: break-word;\n  background: transparent;\n  box-sizing: border-box;\n  border: none;\n  outline: none;\n  margin: 0;\n  padding: 0;\n  width: 100%;\n  height: 100%;\n  overflow: hidden;\n  resize: none;\n}\n\n.playground-write::selection {\n  color: var(--fg);\n  background-color: hsl(42.22deg 74.31% 57.25% / 66%);\n}\n\n.playground-write {\n  position: absolute;\n  top: 0;\n  -webkit-print-color-adjust: exact;\n  print-color-adjust: exact;\n  color: transparent;\n  caret-color: var(--hl);\n}\n\n.playground-controls fieldset {\n  border: 0;\n  padding: 0;\n  margin-inline: 0;\n}\n\n.playground-controls fieldset[disabled] {\n  opacity: 0.6;\n}\n\n.playground-controls label {\n  font-size: smaller;\n  display: block;\n  margin-block: calc(0.5 * (1em + 1ex));\n}\n\n.playground-controls select {\n  padding: 0.5ex;\n}\n\n/* Can’t have bold things; they mess with the textarea */\n.playground .pl-mh,\n.playground .pl-mh .pl-en,\n.playground .pl-ms {\n  font-weight: normal !important;\n}\n"
  },
  {
    "path": "docs/_asset/index.js",
    "content": "/* eslint-disable unicorn/prefer-query-selector */\n/// <reference lib=\"dom\" />\n\nimport docsearch_ from '@docsearch/js'\nimport {computePosition, shift} from '@floating-ui/dom'\nimport copyToClipboard from 'copy-to-clipboard'\nimport {ok as assert} from 'devlop'\n\n// Squircles.\nif ('paintWorklet' in CSS) {\n  // @ts-expect-error: TS doesn’t understand Houdini.\n  CSS.paintWorklet.addModule(\n    'https://www.unpkg.com/css-houdini-squircle@0.2.1/squircle.min.js'\n  )\n}\n\n// Copy buttons.\nconst copies = Array.from(document.querySelectorAll('button.copy-button'))\nconst copyTemplate = document.createElement('template')\nconst copiedTemplate = document.createElement('template')\ncopyTemplate.innerHTML = `<svg\n  role=\"img\"\n  aria-label=\"Copy\"\n  class=\"icon icon-copy\"\n  viewBox=\"0 0 16 16\"\n  width=16\n  height=16\n>\n  <title>Copy</title>\n  <path\n    fill=\"currentcolor\"\n    fill-rule=\"evenodd\"\n    d=\"M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z\"\n  />\n  <path\n    fill=\"currentcolor\"\n    fill-rule=\"evenodd\"\n    d=\"M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z\"\n  />\n</svg>`\ncopiedTemplate.innerHTML = `<svg\n  role=\"img\"\n  aria-label=\"Copied!\"\n  class=\"icon icon-copy\"\n  viewBox=\"0 0 16 16\"\n  width=16\n  height=16\n>\n  <title>Copied!</title>\n  <path\n    fill=\"currentcolor\"\n    fill-rule=\"evenodd\"\n    d=\"M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z\"\n  />\n</svg>`\nconst copyIcon = copyTemplate.content.querySelector('svg')\nconst copiedIcon = copiedTemplate.content.querySelector('svg')\nassert(copyIcon)\nassert(copiedIcon)\n\nfor (const copy of copies) {\n  assert(copy instanceof HTMLButtonElement)\n  copy.type = 'button'\n  copy.replaceChildren(copyIcon.cloneNode(true))\n  copy.addEventListener('click', oncopyonclick)\n}\n\nconst popoverTargets = /** @type {Array<HTMLElement>} */ (\n  Array.from(document.querySelectorAll('.rehype-twoslash-popover-target'))\n)\n\nfor (const popoverTarget of popoverTargets) {\n  /** @type {NodeJS.Timeout | number} */\n  let timeout = 0\n\n  popoverTarget.addEventListener('click', function () {\n    popoverShow(popoverTarget)\n  })\n\n  popoverTarget.addEventListener('mouseenter', function () {\n    clearTimeout(timeout)\n    timeout = setTimeout(function () {\n      popoverShow(popoverTarget)\n    }, 300)\n  })\n\n  popoverTarget.addEventListener('mouseleave', function () {\n    clearTimeout(timeout)\n  })\n\n  if (popoverTarget.classList.contains('rehype-twoslash-autoshow')) {\n    popoverShow(popoverTarget)\n  }\n}\n\n/**\n * @this {HTMLButtonElement}\n *   Button element.\n * @returns {undefined}\n *   Nothing.\n */\nfunction oncopyonclick() {\n  assert(copyIcon)\n  assert(copiedIcon)\n  assert(this instanceof HTMLButtonElement)\n\n  const value = this.dataset.value\n  assert(value !== undefined)\n\n  this.classList.add('success')\n  this.replaceChildren(copiedIcon.cloneNode(true))\n\n  copyToClipboard(value)\n\n  setTimeout(() => {\n    this.classList.remove('success')\n    this.replaceChildren(copyIcon.cloneNode(true))\n  }, 2000)\n}\n\n/**\n * @param {HTMLElement} popoverTarget\n *   Popover target.\n * @returns {undefined}\n *   Nothing.\n */\nfunction popoverShow(popoverTarget) {\n  const id = popoverTarget.dataset.popoverTarget\n  if (!id) return\n  const popover = document.getElementById(id)\n  if (!popover) return\n\n  popover.showPopover()\n\n  computePosition(popoverTarget, popover, {\n    placement: 'bottom',\n    middleware: [shift({padding: 5})]\n  }).then(\n    /**\n     * @param {{x: number, y: number}} value\n     */\n    function (value) {\n      popover.style.left = value.x + 'px'\n      popover.style.top = value.y + 'px'\n    }\n  )\n}\n\n// Docsearch.\n// Note: types are wrong.\nconst docsearch = /** @type {import('@docsearch/js')['default']} */ (\n  /** @type {unknown} */ (docsearch_)\n)\n\ndocsearch({\n  appId: 'B0O9AAZ9L2',\n  apiKey: '71f38eae605e3e6d500368617e32c19f',\n  container: '#docsearch',\n  indexName: 'mdxjs'\n})\n"
  },
  {
    "path": "docs/_component/blog.jsx",
    "content": "/**\n * @import {ReactNode} from 'react'\n * @import {Item} from './sort.js'\n */\n\n/**\n * @typedef EntryProperties\n *   Properties for `BlogEntry`.\n * @property {Readonly<Item>} item\n *   Item.\n *\n * @typedef GroupProperties\n *   Properties for `BlogGroup`.\n * @property {string | undefined} [className]\n *   Class name.\n * @property {ReadonlyArray<Item>} items\n *   Items.\n * @property {string | undefined} [sort]\n *   Fields to sort on.\n */\n\nimport {apStyleTitleCase} from 'ap-style-title-case'\nimport {toJsxRuntime} from 'hast-util-to-jsx-runtime'\nimport React from 'react'\nimport {Fragment, jsx, jsxs} from 'react/jsx-runtime'\nimport {sortItems} from './sort.js'\n\nconst dateTimeFormat = new Intl.DateTimeFormat('en', {dateStyle: 'long'})\n\n/**\n * @param {Readonly<EntryProperties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function BlogEntry(properties) {\n  const {item} = properties\n  const {data, name} = item\n  const {matter = {}, meta = {}} = data\n  const title = matter.title || meta.title\n  const defaultTitle = apStyleTitleCase(\n    name.replace(/\\/$/, '').split('/').pop()\n  )\n  const description = matter.description || meta.description\n  const time = (\n    meta.readingTime\n      ? Array.isArray(meta.readingTime)\n        ? meta.readingTime\n        : [meta.readingTime, meta.readingTime]\n      : []\n  ).map(function (d) {\n    return Math.ceil(d)\n  })\n  /** @type {string | undefined} */\n  let timeLabel\n\n  if (time.length > 1 && time[0] !== time[1]) {\n    timeLabel = time[0] + '-' + time[1] + ' minutes'\n  } else if (time[0]) {\n    timeLabel = time[0] + ' minute' + (time[0] > 1 ? 's' : '')\n  }\n\n  return (\n    <div className=\"card\">\n      <h3>\n        <a href={name}>{title || defaultTitle}</a>\n      </h3>\n      <div>\n        {meta.descriptionHast ? (\n          toJsxRuntime(meta.descriptionHast, {Fragment, jsx, jsxs})\n        ) : description ? (\n          <p>{description}</p>\n        ) : undefined}\n        <span>\n          <a href={name}>Continue reading »</a>\n        </span>\n      </div>\n      <div\n        style={{display: 'flex', justifyContent: 'space-between'}}\n        className=\"block\"\n      >\n        <div>\n          {meta.author ? (\n            <>\n              <small>By {meta.author}</small>\n              <br />\n            </>\n          ) : undefined}\n          <small>Reading time: {timeLabel}</small>\n        </div>\n        {meta.published && typeof meta.published === 'object' ? (\n          <div style={{marginLeft: 'auto', textAlign: 'right'}}>\n            <small>\n              Published on{' '}\n              <time dateTime={meta.published.toISOString()}>\n                {dateTimeFormat.format(meta.published)}\n              </time>\n            </small>\n          </div>\n        ) : undefined}\n      </div>\n    </div>\n  )\n}\n\n/**\n * @param {Readonly<GroupProperties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function BlogGroup(properties) {\n  const {\n    className,\n    items,\n    sort = 'navSortSelf,meta.title',\n    ...rest\n  } = properties\n  const sorted = sortItems(items, sort)\n\n  return (\n    <>\n      {sorted.map(function (d) {\n        return <BlogEntry key={d.name} {...rest} item={d} />\n      })}\n    </>\n  )\n}\n"
  },
  {
    "path": "docs/_component/foot-site.jsx",
    "content": "import React from 'react'\nimport {config} from '../_config.js'\n\nexport function FootSite() {\n  return (\n    <footer className=\"foot-site\">\n      <div className=\"content\">\n        <div\n          className=\"block\"\n          style={{display: 'flex', justifyContent: 'space-between'}}\n        >\n          <div>\n            <small>\n              MDX is made with ❤️ in Amsterdam, Boise, and around the 🌏\n            </small>\n            <br />\n            <small>This site does not track you.</small>\n            <br />\n            <small>MIT © 2017-{new Date().getFullYear()}</small>\n          </div>\n          <div style={{marginLeft: 'auto', textAlign: 'right'}}>\n            <small>\n              Project on <a href={config.gh.href}>GitHub</a>\n            </small>\n            <br />\n            <small>\n              Site on <a href={new URL('docs/', config.ghTree).href}>GitHub</a>\n            </small>\n            <br />\n            <small>\n              Updates as <a href=\"/rss.xml\">RSS feed</a>\n            </small>\n            <br />\n            <small>\n              Sponsor on <a href={config.oc.href}>OpenCollective</a>\n            </small>\n          </div>\n        </div>\n      </div>\n    </footer>\n  )\n}\n"
  },
  {
    "path": "docs/_component/home.jsx",
    "content": "/**\n * @import {ReactNode} from 'react'\n * @import {Data} from 'vfile'\n * @import {Item} from './sort.js'\n */\n\n/**\n * @typedef {Exclude<Data['meta'], undefined>} Meta\n *\n * @typedef Properties\n *   Properties.\n * @property {string} name\n *   Name.\n * @property {ReactNode} children\n *   Children.\n * @property {Item} navigationTree\n *   Navigation tree.\n * @property {Meta} meta\n *   Meta.\n */\n\nimport React from 'react'\nimport {FootSite} from './foot-site.jsx'\nimport {NavigationSite, NavigationSiteSkip} from './nav-site.jsx'\n\n/**\n * @param {Readonly<Properties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function Home(properties) {\n  const {children, meta, name, navigationTree} = properties\n\n  return (\n    <div className=\"page home\">\n      <NavigationSiteSkip />\n      <main>\n        {meta.schemaOrg ? (\n          <script type=\"application/ld+json\">\n            {JSON.stringify(meta.schemaOrg)}\n          </script>\n        ) : undefined}\n        <article>\n          <div className=\"content body\">{children}</div>\n        </article>\n        <FootSite />\n      </main>\n      <NavigationSite name={name} navigationTree={navigationTree} />\n    </div>\n  )\n}\n"
  },
  {
    "path": "docs/_component/icon/github.jsx",
    "content": "import React from 'react'\n\nexport function GitHub() {\n  return (\n    <svg\n      role=\"img\"\n      aria-label=\"GitHub\"\n      className=\"icon icon-github\"\n      viewBox=\"0 0 16 16\"\n      width={18}\n      height={18}\n    >\n      <title>GitHub</title>\n      <path\n        fill=\"currentcolor\"\n        clipRule=\"evenodd\"\n        fillRule=\"evenodd\"\n        d=\"M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z\"\n      />\n    </svg>\n  )\n}\n"
  },
  {
    "path": "docs/_component/icon/mdx.jsx",
    "content": "import React from 'react'\n\nexport function Mdx() {\n  return (\n    <svg\n      role=\"img\"\n      aria-label=\"MDX\"\n      className=\"icon icon-mdx\"\n      viewBox=\"0 0 138 57\"\n      width={69}\n      height={28.5}\n    >\n      <title>MDX</title>\n      <g>\n        <rect\n          width=\"136.5\"\n          height=\"55.5\"\n          x=\".75\"\n          y=\".75\"\n          rx=\"4.5\"\n          fill=\"currentColor\"\n        />\n        <g fill=\"none\" stroke=\"var(--bg)\" strokeWidth=\"6\">\n          <path d=\"M16.5 44V19L30.25 32.75l14-14v25\" />\n          <path d=\"M70.5 40V10.75\" />\n          <path d=\"M57 27.25L70.5 40.75l13.5-13.5\" />\n          <path d=\"M122.5 41.24L93.25 12M93.5 41.25L122.75 12\" />\n        </g>\n      </g>\n    </svg>\n  )\n}\n"
  },
  {
    "path": "docs/_component/icon/open-collective.jsx",
    "content": "import React from 'react'\n\nexport function OpenCollective() {\n  return (\n    <svg\n      role=\"img\"\n      aria-label=\"OpenCollective\"\n      className=\"icon icon-opencollective\"\n      viewBox=\"0 0 40 40\"\n      width={18}\n      height={18}\n    >\n      <title>OpenCollective</title>\n      <path\n        fill=\"currentcolor\"\n        d=\"M32.779 19.921a13.09 13.09 0 01-1.989 6.938l5.13 5.151c2.512-3.364 4.082-7.569 4.082-12.089 0-4.52-1.57-8.725-4.083-12.09l-5.129 5.152c1.256 1.997 1.989 4.31 1.989 6.938z\"\n      />\n      <path\n        fill=\"currentcolor\"\n        d=\"M20.014 32.746c-7.014 0-12.771-5.782-12.771-12.825 0-7.043 5.757-12.825 12.77-12.825 2.618 0 4.92.736 6.91 2.102l5.129-5.15c-3.35-2.524-7.537-4.1-12.038-4.1C9.022-.053.02 8.882.02 20.025.02 31.17 9.022 40 20.014 40c4.605 0 8.793-1.577 12.142-4.1l-5.129-5.151c-1.989 1.261-4.396 1.997-7.013 1.997z\"\n      />\n    </svg>\n  )\n}\n"
  },
  {
    "path": "docs/_component/layout.jsx",
    "content": "/**\n * @import {ReactNode} from 'react'\n * @import {Data} from 'vfile'\n * @import {Item} from './sort.js'\n */\n\n/**\n * @typedef Properties\n *   Properties.\n * @property {string} name\n *   Name.\n * @property {Readonly<URL>} ghUrl\n *   GitHub URL.\n * @property {Readonly<Data['meta']> | undefined} [meta]\n *   Meta.\n * @property {Readonly<Item>} navigationTree\n *   Navigation tree.\n * @property {ReactNode} children\n *   Children.\n */\n\nimport React from 'react'\nimport {FootSite} from './foot-site.jsx'\nimport {NavigationSite, NavigationSiteSkip} from './nav-site.jsx'\nimport {sortItems} from './sort.js'\n\nconst dateTimeFormat = new Intl.DateTimeFormat('en', {dateStyle: 'long'})\n\n/**\n * @param {Readonly<Properties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function Layout(properties) {\n  const {ghUrl, name, navigationTree} = properties\n  const [self, parent] = findSelfAndParent(navigationTree) || []\n  const navigationSortItems = parent\n    ? parent.data.navigationSortItems\n    : undefined\n  const siblings = parent\n    ? sortItems(\n        parent.children,\n        typeof navigationSortItems === 'string'\n          ? navigationSortItems\n          : undefined\n      )\n    : []\n  const meta = (self ? self.data.meta : properties.meta) || {}\n  const index = self ? siblings.indexOf(self) : -1\n  const previous = index === -1 ? undefined : siblings[index - 1]\n  const next = index === -1 ? undefined : siblings[index + 1]\n  const metaAuthors = meta.authors || []\n  const metaTime = (\n    self\n      ? accumulateReadingTime(self)\n      : meta.readingTime\n        ? Array.isArray(meta.readingTime)\n          ? meta.readingTime\n          : [meta.readingTime, meta.readingTime]\n        : []\n  ).map(function (d) {\n    return d > 15 ? Math.round(d / 5) * 5 : Math.ceil(d)\n  })\n  /** @type {string | undefined} */\n  let timeLabel\n\n  if (metaTime.length > 1 && metaTime[0] !== metaTime[1]) {\n    timeLabel = metaTime[0] + '-' + metaTime[1] + ' minutes'\n  } else if (metaTime[0]) {\n    timeLabel = metaTime[0] + ' minute' + (metaTime[0] > 1 ? 's' : '')\n  }\n\n  const up =\n    parent && self && parent !== navigationTree ? (\n      <div>\n        <a href={parent.name}>{entryToTitle(parent)}</a>\n        {' / '}\n        <a href={name} aria-current=\"page\">\n          {entryToTitle(self)}\n        </a>\n      </div>\n    ) : undefined\n\n  const back = previous ? (\n    <div>\n      Previous:\n      <br />\n      <a rel=\"prev\" href={previous.name}>\n        {entryToTitle(previous)}\n      </a>\n    </div>\n  ) : undefined\n\n  const forward = next ? (\n    <div>\n      Next:\n      <br />\n      <a rel=\"next\" href={next.name}>\n        {entryToTitle(next)}\n      </a>\n    </div>\n  ) : undefined\n\n  const edit = (\n    <div>\n      Found a typo? Other suggestions?\n      <br />\n      <a href={ghUrl.href}>Edit this page on GitHub</a>\n    </div>\n  )\n\n  const published =\n    meta.published && typeof meta.published === 'object' ? (\n      <>\n        Published on{' '}\n        <time dateTime={meta.published.toISOString()}>\n          {dateTimeFormat.format(meta.published)}\n        </time>\n      </>\n    ) : undefined\n\n  const modified =\n    meta.modified && typeof meta.modified === 'object' ? (\n      <>\n        Modified on{' '}\n        <time dateTime={meta.modified.toISOString()}>\n          {dateTimeFormat.format(meta.modified)}\n        </time>\n      </>\n    ) : undefined\n\n  const date =\n    published || modified ? (\n      <div>\n        {published}\n        {published && modified ? <br /> : undefined}\n        {modified}\n      </div>\n    ) : undefined\n\n  const readingTime = timeLabel ? <>{timeLabel} read</> : undefined\n\n  const creditsList = metaAuthors.map(function (d, i) {\n    const href = d.github\n      ? 'https://github.com/' + d.github\n      : d.url || undefined\n    return (\n      <span key={d.name}>\n        {i ? ', ' : ''}\n        {href ? <a href={href}>{d.name}</a> : d.name}\n      </span>\n    )\n  })\n\n  const credits = creditsList.length > 0 ? <>By {creditsList}</> : undefined\n\n  const info =\n    readingTime || credits ? (\n      <>\n        {readingTime}\n        {readingTime && credits ? <br /> : undefined}\n        {credits}\n      </>\n    ) : undefined\n\n  const header =\n    up || info ? (\n      <div className=\"block article-row\">\n        {up ? <div className=\"article-row-start\">{up}</div> : undefined}\n        {info ? <div className=\"article-row-end\">{info}</div> : undefined}\n      </div>\n    ) : undefined\n\n  const tail =\n    edit || date ? (\n      <div className=\"block article-row\">\n        {edit ? <div className=\"article-row-start\">{edit}</div> : undefined}\n        {date ? <div className=\"article-row-end\">{date}</div> : undefined}\n      </div>\n    ) : undefined\n\n  const footer =\n    back || forward ? (\n      <div className=\"block article-row\">\n        {back ? <div className=\"article-row-start\">{back}</div> : undefined}\n        {forward ? <div className=\"article-row-end\">{forward}</div> : undefined}\n      </div>\n    ) : undefined\n\n  return (\n    <div className=\"page doc\">\n      <NavigationSiteSkip />\n      <main>\n        <article>\n          {header ? (\n            <header className=\"content\">\n              <div className=\"block head-article\">{header}</div>\n            </header>\n          ) : undefined}\n          <div className=\"content body\">{properties.children}</div>\n          {footer || tail ? (\n            <footer className=\"content\">\n              <div className=\"block foot-article\">\n                {footer}\n                {tail}\n              </div>\n            </footer>\n          ) : undefined}\n        </article>\n        <FootSite />\n      </main>\n      <NavigationSite name={name} navigationTree={navigationTree} />\n    </div>\n  )\n\n  /**\n   * @param {Item} item\n   *   Item.\n   * @param {Item | undefined} [parent]\n   *   Parent.\n   * @returns {[self: Item, parent: Item | undefined] | undefined}\n   *   Self and parent.\n   */\n  function findSelfAndParent(item, parent) {\n    if (item.name === name) return [item, parent]\n\n    let index = -1\n\n    while (++index < item.children.length) {\n      const result = findSelfAndParent(item.children[index], item)\n\n      if (result) return result\n    }\n  }\n}\n\n/**\n * @param {Item} d\n *   Item.\n * @returns {string | undefined}\n *   Title.\n */\nfunction entryToTitle(d) {\n  return d.data.matter?.title || d.data.meta?.title || undefined\n}\n\n/**\n * @param {Item} d\n *   Item.\n * @returns {[number, number] | [number] | []}\n *   Reading time.\n */\nfunction accumulateReadingTime(d) {\n  const time = (d.data.meta || {}).readingTime\n  /** @type {[number, number] | [number] | []} */\n  const total = time ? (Array.isArray(time) ? time : [time, time]) : []\n\n  let index = -1\n  while (++index < d.children.length) {\n    const childTime = accumulateReadingTime(d.children[index])\n    if (childTime[0]) total[0] = (total[0] || 0) + childTime[0]\n    if (childTime[1]) total[1] = (total[1] || 0) + childTime[1]\n  }\n\n  return total\n}\n"
  },
  {
    "path": "docs/_component/nav-site.jsx",
    "content": "/**\n * @import {ReactNode} from 'react'\n * @import {Item} from './sort.js'\n */\n\n/**\n * @typedef Properties\n *   Properties.\n * @property {string} name\n *   Name.\n * @property {Readonly<Item>} navigationTree\n *   Navigation tree.\n */\n\nimport React from 'react'\nimport {config} from '../_config.js'\nimport {GitHub} from './icon/github.jsx'\nimport {Mdx} from './icon/mdx.jsx'\nimport {OpenCollective} from './icon/open-collective.jsx'\nimport {NavigationGroup} from './nav.jsx'\n\nexport function NavigationSiteSkip() {\n  return (\n    <a\n      href=\"#start-of-navigation\"\n      id=\"start-of-content\"\n      className=\"skip-to-navigation\"\n    >\n      Skip to navigation\n    </a>\n  )\n}\n\n/**\n * @param {Readonly<Properties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function NavigationSite(properties) {\n  const {name, navigationTree} = properties\n\n  return (\n    <nav className=\"navigation\" aria-label=\"Site navigation\">\n      <div id=\"banner\">Ceasefire now! 🕊️</div>\n      <a\n        href=\"#start-of-content\"\n        id=\"start-of-navigation\"\n        className=\"skip-to-content\"\n      >\n        Skip to content\n      </a>\n      <div className=\"navigation-primary\">\n        <a href=\"/\" aria-current={name === '/' ? 'page' : undefined}>\n          <h1>\n            <Mdx />\n          </h1>\n        </a>\n      </div>\n      <div className=\"navigation-search\">\n        <div id=\"docsearch\" />\n      </div>\n      <NavigationGroup\n        className=\"navigation-secondary\"\n        items={navigationTree.children}\n        name={name}\n      />\n      <ol className=\"navigation-tertiary\">\n        <li>\n          <a href={config.gh.href}>\n            <GitHub />\n          </a>\n        </li>\n        <li className=\"navigation-show-big\">\n          <a href={config.oc.href}>\n            <OpenCollective />\n          </a>\n        </li>\n      </ol>\n    </nav>\n  )\n}\n"
  },
  {
    "path": "docs/_component/nav.jsx",
    "content": "// Augment vfile data:\n/// <reference types=\"rehype-infer-description-meta\" />\n\n/**\n * @import {ElementContent} from 'hast'\n * @import {ReactNode} from 'react'\n * @import {Item} from './sort.js'\n */\n\n/**\n * @typedef ItemProperties\n *   Properties for `NavigationItem`.\n * @property {boolean | undefined} [includeDescription=false]\n *   Whether to include the description (default: `false`).\n * @property {boolean | undefined} [includePublished=false]\n *   Whether to include the published date (default: `false`).\n * @property {Readonly<Item>} item\n *   Item.\n * @property {string | undefined} [name]\n *   Name.\n *\n * @typedef GroupOnlyProperties\n *   Properties for `NavigationGroup`;\n *   Other fields are passed to `NavigationItem`.\n * @property {string | undefined} [className]\n *   Class name.\n * @property {ReadonlyArray<Item>} items\n *   Items.\n * @property {string | undefined} [sort]\n *   Fields to sort on.\n * @property {string | undefined} [name]\n *   Name.\n *\n * @typedef {Omit<ItemProperties, 'item'> & GroupOnlyProperties} GroupProperties\n *   Properties for `NavigationGroup`.\n */\n\nimport {apStyleTitleCase} from 'ap-style-title-case'\nimport {toJsxRuntime} from 'hast-util-to-jsx-runtime'\nimport React from 'react'\nimport {Fragment, jsx, jsxs} from 'react/jsx-runtime'\nimport {sortItems} from './sort.js'\n\nconst dateTimeFormat = new Intl.DateTimeFormat('en', {dateStyle: 'long'})\n\n/**\n * @param {Readonly<GroupProperties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function NavigationGroup(properties) {\n  const {\n    className,\n    items,\n    sort = 'navSortSelf,meta.title',\n    ...rest\n  } = properties\n\n  return (\n    <ol {...{className}}>\n      {sortItems(items, sort).map(function (d) {\n        return <NavigationItem key={d.name} {...rest} item={d} />\n      })}\n    </ol>\n  )\n}\n\n/**\n * @param {Readonly<ItemProperties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function NavigationItem(properties) {\n  const {\n    includeDescription,\n    includePublished,\n    item,\n    name: activeName\n  } = properties\n  const {children, data = {}, name} = item\n  const {matter = {}, meta = {}, navExcludeGroup, navigationSortItems} = data\n  const title = matter.title || meta.title\n  const defaultTitle = apStyleTitleCase(\n    name.replace(/\\/$/, '').split('/').pop()\n  )\n  /** @type {ReactNode} */\n  let description\n  /** @type {string | undefined} */\n  let published\n\n  if (includeDescription) {\n    if (meta.descriptionHast) {\n      // Cast because we don’t expect doctypes.\n      const children = /** @type {Array<ElementContent>} */ (\n        meta.descriptionHast.children\n      )\n\n      description = toJsxRuntime(\n        {\n          type: 'element',\n          tagName: 'div',\n          properties: {className: ['nav-description']},\n          children\n        },\n        {Fragment, jsx, jsxs}\n      )\n    } else {\n      description = matter.description || meta.description || undefined\n\n      description &&= (\n        <div className=\"nav-description\">\n          <p>{description}</p>\n        </div>\n      )\n    }\n  }\n\n  const pub = matter.published || meta.published\n\n  if (includePublished && pub) {\n    published = dateTimeFormat.format(\n      typeof pub === 'string' ? new Date(pub) : pub || undefined\n    )\n  }\n\n  return (\n    <li>\n      {title ? (\n        <a href={name} aria-current={name === activeName ? 'page' : undefined}>\n          {title}\n        </a>\n      ) : (\n        defaultTitle\n      )}\n      {published ? ' — ' + published : undefined}\n      {description || undefined}\n      {!navExcludeGroup && children.length > 0 ? (\n        <NavigationGroup\n          items={children}\n          sort={\n            typeof navigationSortItems === 'string'\n              ? navigationSortItems\n              : undefined\n          }\n          name={activeName}\n        />\n      ) : undefined}\n    </li>\n  )\n}\n"
  },
  {
    "path": "docs/_component/note.jsx",
    "content": "/**\n * @import {ReactNode} from 'react'\n */\n\n/**\n * @typedef {'important' | 'info' | 'legacy'} NoteType\n *   Type.\n *\n * @typedef Properties\n *   Properties for `Note`.\n * @property {NoteType} type\n *   Kind.\n * @property {Readonly<ReactNode>} children\n *   Children.\n */\n\nimport React from 'react'\n\n/** @type {Set<NoteType>} */\nconst known = new Set(['info', 'legacy', 'important'])\n\n/**\n * @param {Readonly<Properties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function Note(properties) {\n  const {children, type} = properties\n  const className = ['note']\n\n  if (known.has(type)) className.push(type)\n  else {\n    throw new Error('Unknown note type `' + type + '`')\n  }\n\n  return <div className={className.join(' ')}>{children}</div>\n}\n"
  },
  {
    "path": "docs/_component/snowfall.jsx",
    "content": "/**\n * @import {ReactNode} from 'react'\n */\n\n/**\n * @typedef Properties\n *   Properties.\n * @property {string} color\n *   Color.\n * @property {number} year\n *   Year.\n */\n\nimport React from 'react'\n\nconst data = [6, 5, 2, 4.5, 1.5, 2.5, 2, 2.5, 1.5, 2.5, 3.5, 7]\n\n/**\n * @param {Readonly<Properties>} properties\n *   Properties.\n * @returns {ReactNode}\n *   Element.\n */\nexport function Chart(properties) {\n  return (\n    <div className=\"snowfall\">\n      {data.map(function (d) {\n        return (\n          <div\n            key={d}\n            className=\"snowfall-bar\"\n            style={{\n              backgroundColor: properties.color,\n              height: 'calc(' + d + ' * 0.5 * (1em + 1ex))'\n            }}\n          />\n        )\n      })}\n    </div>\n  )\n}\n"
  },
  {
    "path": "docs/_component/sort.js",
    "content": "/**\n * @import {Data} from 'vfile'\n */\n\n/**\n * @typedef Item\n *   Item.\n * @property {string} name\n *   Name.\n * @property {Readonly<Data>} data\n *   Data.\n * @property {Array<Item>} children\n *   Children.\n */\n\nimport dlv from 'dlv'\n\nconst collator = new Intl.Collator('en').compare\n\n/**\n * @param {ReadonlyArray<Item>} items\n *   Items.\n * @param {string | undefined} [sortString]\n *   Fields to sort on (default: `'navSortSelf,meta.title'`).\n * @returns {ReadonlyArray<Item>}\n *   Items.\n */\nexport function sortItems(items, sortString = 'navSortSelf,meta.title') {\n  /** @type {ReadonlyArray<[string, 'asc' | 'desc']>} */\n  const fields = sortString.split(',').map(function (d) {\n    const [field, order = 'asc'] = d.split(':')\n\n    if (order !== 'asc' && order !== 'desc') {\n      throw new Error('Cannot order as `' + order + '`')\n    }\n\n    return [field, order]\n  })\n\n  return [...items].sort(function (left, right) {\n    let index = -1\n\n    while (++index < fields.length) {\n      const [field, order] = fields[index]\n      /** @type {unknown} */\n      let a = dlv(left.data, field)\n      /** @type {unknown} */\n      let b = dlv(right.data, field)\n\n      // Dates.\n      if (a && typeof a === 'object' && 'valueOf' in a) a = a.valueOf()\n      if (b && typeof b === 'object' && 'valueOf' in b) b = b.valueOf()\n\n      const score =\n        typeof a === 'string' && typeof b === 'string'\n          ? collator(a, b)\n          : typeof a === 'number' && typeof b === 'number'\n            ? a - b\n            : (a === null || a === undefined) && (b === null || b === undefined)\n              ? 0\n              : a === null || a === undefined\n                ? 1\n                : b === null || b === undefined\n                  ? -1\n                  : 0\n\n      if (score) return order === 'asc' ? score : -score\n    }\n\n    return 0\n  })\n}\n"
  },
  {
    "path": "docs/_config.js",
    "content": "const site = new URL('https://mdxjs.com')\nconst git = new URL('../', import.meta.url)\nconst gh = new URL('https://github.com/mdx-js/mdx/')\n\nexport const config = {\n  author: 'MDX contributors',\n  color: '#010409',\n  gh,\n  ghBlob: new URL('blob/main/', gh),\n  ghTree: new URL('tree/main/', gh),\n  git,\n  input: new URL('docs/', git),\n  oc: new URL('https://opencollective.com/unified'),\n  output: new URL('public/', git),\n  site,\n  tags: ['mdx', 'markdown', 'jsx', 'oss', 'react'],\n  title: 'MDX'\n}\n\n/** @type {Record<string, string>} */\nexport const redirect = {\n  '/about/index.html': '/community/about/',\n  '/advanced/index.html': '/guides/',\n  '/advanced/api/index.html': '/packages/mdx/#api',\n  '/advanced/ast/index.html': '/packages/remark-mdx/#syntax-tree',\n  '/advanced/components/index.html': '/docs/using-mdx/',\n  '/advanced/contributing/index.html': '/community/contribute/',\n  '/advanced/custom-loader/index.html': '/guides/frontmatter/',\n  '/advanced/retext-plugins/index.html': '/docs/extending-mdx/#using-plugins',\n  '/advanced/plugins/index.html': '/docs/extending-mdx/',\n  '/advanced/runtime/index.html': '/packages/mdx/#evaluatefile-options',\n  '/advanced/specification/index.html': '/packages/remark-mdx/#syntax-tree',\n  '/advanced/sync-api/index.html': '/packages/mdx/#api',\n  '/advanced/transform-content/index.html': '/packages/remark-mdx/',\n  '/advanced/typescript/index.html': '/docs/getting-started/#types',\n  '/advanced/writing-a-plugin/index.html': '/guides/frontmatter/',\n  '/contributing/index.html': '/community/contribute/',\n  '/editor-plugins/index.html': '/docs/getting-started/#editor',\n  '/editors/index.html': '/docs/getting-started/#editor',\n  '/getting-started/create-react-app/index.html': '/docs/getting-started/#vite',\n  '/getting-started/gatsby/index.html': '/docs/getting-started/#gatsby',\n  '/getting-started/next/index.html': '/docs/getting-started/#nextjs',\n  '/getting-started/parcel/index.html': '/docs/getting-started/#parcel',\n  '/getting-started/react-static/index.html': '/docs/getting-started/#vite',\n  '/getting-started/table-of-components/index.html': '/table-of-components/',\n  '/getting-started/typescript/index.html': '/docs/getting-started/#types',\n  '/getting-started/webpack/index.html': '/docs/getting-started/#webpack',\n  '/getting-started/index.html': '/docs/getting-started/',\n  '/guides/custom-loader/index.html': '/guides/frontmatter/',\n  '/guides/live-code/index.html':\n    '/guides/syntax-highlighting/#syntax-highlighting-with-the-meta-field',\n  '/guides/markdown-in-components/index.html': '/docs/what-is-mdx/',\n  '/guides/math-blocks/index.html': '/guides/math/',\n  '/guides/mdx-embed/index.html': '/guides/embed/#embeds-at-run-time',\n  '/guides/table-of-contents/index.html': '/docs/extending-mdx/',\n  '/guides/terminal/index.html': '/docs/getting-started/#ink',\n  '/guides/vue/index.html': '/docs/getting-started/#vue',\n  '/guides/wrapper-customization/index.html': '/docs/using-mdx/#layout',\n  '/guides/writing-a-plugin/index.html':\n    '/docs/extending-mdx/#creating-plugins',\n  '/mdx/index.html': '/docs/what-is-mdx/',\n  '/plugins/index.html': '/docs/extending-mdx/#using-plugins',\n  '/projects/index.html': '/community/projects/',\n  '/support/index.html': '/community/support/',\n  '/syntax/index.html': '/docs/getting-started/#syntax',\n  '/vue/index.html': '/docs/getting-started/#vue'\n}\n"
  },
  {
    "path": "docs/blog/conf.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2020-07-31')\n}\n\n<Note type=\"legacy\">\n  **Note**: This is an old blog post.\n  The below is kept as is for historical purposes.\n</Note>\n\n# MDXConf\n\nMDXConf is a free and online conference for the MDX community.\nWhether you’re just learning about MDX or an expert, there’ll be something for\nyou! {/* more */}\n\nAugust 24th, 2020 at 8am PDT/3pm UST <br /> Online • Free\n\n## Watch\n\nThe conference is now over, but you can still watch the recordings!\n\n[Watch the talks →](https://egghead.io/playlists/mdx-conf-3fc2)\n\n## About\n\nJoin us for the first MDX conference!\nWe’ll stream it directly to you, for free.\n\nMDX has grown rapidly since the [first commit][] two and a half years ago.\nWe’d like to celebrate our accomplishments so far, and talk about what lies\nahead.\nWe’ve got lots of plans.\n\nLearn how MDX increases developer productivity, improves educational\ncontent authoring, and even peek behind the curtains to see how MDX works.\n\n## Speakers\n\n### Chris Biscardi\n\n![](https://github.com/ChristopherBiscardi.png?size=200)]\n\nKeynote: The past, present, and future of MDX\n\n### Monica Powell\n\n![](https://github.com/M0nica.png?size=200)\n\nMigrating to MDX\n\n### Laurie Barth\n\n![](https://github.com/laurieontech.png?size=200)\n\nMDX v2 syntax\n\n### Cole Bemis\n\n![](https://github.com/colebemis.png?size=200)\n\nDemystifying MDX\n\n### Prince Wilson\n\n![](https://github.com/maxcell.png?size=200)\n\nPersonal site playgrounds\n\n### Kathleen McMahon\n\n![](https://github.com/resource11.png?size=200)\n\nDigital gardening with MDX magic\n\n### Rodrigo Pombo\n\n![](https://github.com/pomber.png?size=200)\n\nThe X in MDX\n\n### Jonathan Bakebwa\n\n![](https://github.com/codebender828.png?size=200)\n\nMDX and Vue/Nuxt\n\n## Sign up\n\n<Note type=\"legacy\">\n  **Note**: Sign up is closed.\n</Note>\n\n## FAQ\n\n### What if I can’t make it on August 24th?\n\nWe’ll miss you, but you won’t miss out!\nAll talks will be recorded and released the day of the conference.\nYou can catch up with the talks, or rewatch them, whenever convenient.\n\n### Will the talks be transcribed?\n\nYes.\n\n### Is there a code of conduct?\n\nAbsolutely.\nWe’re dedicated to providing a harassment-free experience for everyone.\nWe will not tolerate harassment of participants in any form.\nWe’ve adopted the [Party Corgi Network’s Code of Conduct][coc].\nWe will have moderators to ensure that the code of conduct is followed.\n\n### Do you have a different question?\n\nReach out to us.\n\n[coc]: https://github.com/partycorgi/partycorgi/blob/corgi/CODE_OF_CONDUCT.md\n\n[first commit]: https://github.com/mdx-js/mdx/commit/dee47dc20b08d534132e3b966cdccf3b88c7bca5\n"
  },
  {
    "path": "docs/blog/custom-pragma.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'christopherbiscardi', name: 'Chris Biscardi'}\n  ],\n  modified: new Date('2021-11-01'),\n  published: new Date('2019-03-11')\n}\n\n<Note type=\"legacy\">\n  **Note**: This is an old blog post.\n  The steps described in it are no longer performed by MDX.\n  It now uses an JavaScript AST first rather than generating a string of JSX.\n  It is also no longer required for extra glue code, that combines MDX with a\n  specific framework, to be used on the client.\n  See [§ How MDX works](/docs/using-mdx/#how-mdx-works)\n  and [¶ Architecture](/packages/mdx/#architecture) for more info.\n  The below is kept as is for historical purposes.\n</Note>\n\n# Custom pragma\n\n`MDXTag`, for those that aren’t aware, is a critical piece in the way\nMDX replaces HTML primitives like `<pre>` and `<h1>` with custom React\nComponents.\n[I’ve previously\nwritten](https://www.christopherbiscardi.com/post/codeblocks-mdx-and-mdx-utils)\nabout the way `MDXTag` works when trying to replace the `<pre>` tag\nwith a custom code component.\n[mdx-utils](https://github.com/ChristopherBiscardi/gatsby-mdx/blob/00769a1b72455f40843cd2f09ee34fd63b009fb2/packages/mdx-utils/index.js)\ncontains the methodology for pulling the props around appropriately\nthrough the `MDXTag` elements that are inbetween `pre` and `code`.\n\n{/* more */}\n\n```tsx\nexports.preToCodeBlock = preProps => {\n  if (\n    // children is MDXTag\n    preProps.children &&\n    // MDXTag props\n    preProps.children.props &&\n    // if MDXTag is going to render a <code>\n    preProps.children.props.name === 'code'\n  ) {\n    // we have a <pre><code> situation\n    const {\n      children: codeString,\n      props: {className, ...props}\n    } = preProps.children.props\n\n    return {\n      codeString: codeString.trim(),\n      language: className && className.split('-')[1],\n      ...props\n    }\n  }\n  return undefined\n}\n```\n\nSo `MDXTag` is a real Component in the middle of all of the other MDX\nrendered elements.\nAll of the code is included here for reference.\n\n```tsx\nimport React, {Component} from 'react'\n\nimport {withMDXComponents} from './mdx-provider'\n\nconst defaults = {\n  inlineCode: 'code',\n  wrapper: 'div'\n}\n\nclass MDXTag extends Component {\n  render() {\n    const {\n      name,\n      parentName,\n      props: childProps = {},\n      children,\n      components = {},\n      Layout,\n      layoutProps\n    } = this.props\n\n    const Component =\n      components[`${parentName}.${name}`] ||\n      components[name] ||\n      defaults[name] ||\n      name\n\n    if (Layout) {\n      return (\n        <Layout components={components} {...layoutProps}>\n          <Component {...childProps}>{children}</Component>\n        </Layout>\n      )\n    }\n\n    return <Component {...childProps}>{children}</Component>\n  }\n}\n\nexport default withMDXComponents(MDXTag)\n```\n\n`MDXTag` is used in the hast to estree conversion,\nwhich is the final step in the MDX AST pipeline.\nEvery renderable element is wrapped in an `MDXTag`, and `MDXTag` handles\nrendering the element later.\n\n```tsx\nreturn `<MDXTag name=\"${node.tagName}\" components={components}${\n  parentNode.tagName ? ` parentName=\"${parentNode.tagName}\"` : ''\n}${props ? ` props={${props}}` : ''}>${children}</MDXTag>`\n```\n\n## A concrete example\n\nThe following MDX\n\n```mdx\n# a title\n\n    and such\n\ntesting\n```\n\nturns into the following React code\n\n```tsx\nexport default ({components, ...props}) => (\n  <MDXTag name=\"wrapper\" components={components}>\n    <MDXTag name=\"h1\" components={components}>{`a title`}</MDXTag>{' '}\n    <MDXTag name=\"pre\" components={components}>\n      <MDXTag\n        name=\"code\"\n        components={components}\n        parentName=\"pre\"\n        props={{metaString: null}}\n      >{`and such `}</MDXTag>\n    </MDXTag>{' '}\n    <MDXTag name=\"p\" components={components}>{`testing`}</MDXTag>\n  </MDXTag>\n)\n```\n\nresulting in the following HTML\n\n```html\n<div>\n  <h1>a title</h1>\n  <pre>\n    <code>and such</code>\n  </pre>\n  <p>testing</p>\n</div>\n```\n\n## createElement\n\nWith the new approach, the above MDX transforms into this new React code\n\n```tsx\nconst layoutProps = {}\nexport default function MDXContent({components, ...props}) {\n  return (\n    <MDXLayout\n      {...layoutProps}\n      {...props}\n      components={components}\n      mdxType=\"MDXLayout\"\n    >\n      <h1>{`a title`}</h1>\n      <pre>\n        <code parentName=\"pre\" {...{}}>{`and such\n`}</code>\n      </pre>\n      <p>{`testing`}</p>\n    </MDXLayout>\n  )\n}\n\nMDXContent.isMDXComponent = true\n```\n\nNotice how now the React elements are plainly readable without\nwrapping `MDXTag`.\n\nNow that we’ve cleaned up the intermediary representation, we need to\nmake sure that we have the same functionality as the old `MDXTag`.\nThis is done through a custom `createElement` implementation.\nTypically when using React, we use `React.createElement` to render the elements\non screen.\nThis is even true if you’re using JSX because JSX tags such as `<div>` compile\nto `createElement` calls.\nSo this time instead of using `React.createElement` we’ll be using our own.\n\nReproduced here is our `createElement` function and the logic for how\nwe decide whether or not MDX should take over the rendering of the\n`createElement` call.\n\n```tsx\nexport default function (type, props) {\n  const args = arguments\n  const mdxType = props && props.mdxType\n\n  if (typeof type === 'string' || mdxType) {\n    const argsLength = args.length\n\n    const createElementArgArray = new Array(argsLength)\n    createElementArgArray[0] = MDXCreateElement\n\n    const newProps = {}\n    for (let key in props) {\n      if (hasOwnProperty.call(props, key)) {\n        newProps[key] = props[key]\n      }\n    }\n    newProps.originalType = type\n    newProps[TYPE_PROP_NAME] = typeof type === 'string' ? type : mdxType\n\n    createElementArgArray[1] = newProps\n\n    for (let i = 2; i < argsLength; i++) {\n      createElementArgArray[i] = args[i]\n    }\n\n    return React.createElement.apply(null, createElementArgArray)\n  }\n\n  return React.createElement.apply(null, args)\n}\n```\n\n## Vue\n\nOne really cool application of the new output format using a custom\n`createElement` is that we can now write versions of it for Vue and other\nframeworks.\nSince the pragma insertion is the responsibility of the webpack (or other\nbundlers) loader, swapping the pragma can be an option in mdx-loader as long as\nwe have a Vue `createElement` to point to.\n"
  },
  {
    "path": "docs/blog/index.mdx",
    "content": "{\n  /**\n   * @import {Item} from '../_component/sort.js'\n   */\n\n  /**\n   * @typedef Props\n   * @property {Item} navigationTree\n   */\n}\n\nimport assert from 'node:assert/strict'\nimport {BlogGroup} from '../_component/blog.jsx'\n\nexport const info = {\n  author: [{name: 'MDX Contributors'}],\n  modified: new Date('2024-07-04'),\n  published: new Date('2021-11-01')\n}\nexport const navExcludeGroup = true\nexport const navigationSortItems = 'navSortSelf,meta.published:desc'\nexport const navSortSelf = 7\n\n# Blog\n\nThe latest news about MDX.\n\n{\n  (function () {\n    const navigationTree = props.navigationTree\n    const category = navigationTree.children.find(function (item) {\n      return item.name === '/blog/'\n    })\n    assert(category)\n\n    return (\n      <nav>\n        <BlogGroup items={category.children} sort={navigationSortItems} />\n      </nav>\n    )\n  })()\n}\n"
  },
  {
    "path": "docs/blog/shortcodes.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'}\n  ],\n  modified: new Date('2021-11-01'),\n  published: new Date('2019-05-14')\n}\n\n<Note type=\"legacy\">\n  **Note**: This is an old blog post.\n  The features described in it are currently documented at\n  [§ MDX provider](/docs/using-mdx/#mdx-provider).\n  The below is kept as is for historical purposes.\n</Note>\n\n# Shortcodes\n\nAn exciting new feature in MDX v1 is global shortcodes.\nThis allows you to expose components to all of your documents in your app or\nwebsite.\nThis is a useful feature for common components like YouTube embeds, Twitter\ncards, or anything else frequently used in your documents.\n\n{/* more */}\n\nIf you have an application wrapper for your MDX documents\nyou can add in components with the `MDXProvider`:\n\n```tsx path=\"src/App.js\"\nimport React from 'react'\nimport {MDXProvider} from '@mdx-js/react'\nimport {TomatoBox, Twitter, YouTube} from './ui'\n\nconst shortcodes = {TomatoBox, Twitter, YouTube}\n\nexport default ({children}) => (\n  <MDXProvider components={shortcodes}>{children}</MDXProvider>\n)\n```\n\nThen, any MDX document that’s wrapped in `App` has access to `YouTube`,\n`Twitter`, and `TomatoBox`.\nShortcodes are nothing more than components, so you can reference them anywhere\nin an MDX document with JSX.\n\n```mdx path=\"example.mdx\"\n# Hello world!\n\nHere’s a YouTube shortcode:\n\n<YouTube tweetId=\"1234\" />\n\nHere’s a YouTube shortcode wrapped in TomatoBox:\n\n<TomatoBox>\n  <YouTube videoId=\"1234\" />\n</TomatoBox>\n```\n\nThat’s it.\n🎉 🚀\n\nHuge thanks to [Chris Biscardi](https://christopherbiscardi.com)\nfor building out most of this functionality.\n"
  },
  {
    "path": "docs/blog/v1.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2019-04-11')\n}\n\n<Note type=\"legacy\">\n  **Note**: This is an old blog post.\n  [ZEIT is now Vercel](https://rauchg.com/2020/vercel).\n  An “`@mdx` pragma” is no longer needed.\n  The below is kept as is for historical purposes.\n</Note>\n\n# MDX goes stable\n\nIt’s been a year and a half since the first MDX commit and a year since MDX was\nfirst announced at ZEIT Day.\nMDX is a radical paradigm shift in how to write immersive content using\ncomponents.\nIt’s an open, [authorable format](https://johno.com/authorable-format) that\nmakes it *fun* to write again.\n\n{/* more */}\n\nSince announcing MDX we’ve been working on numerous bug fixes, new features,\nbetter parsing, and integration tests.\nNow, we think it’s ready.\n**We’re happy to finally release v1!**\n\n## 🎉 What’s new?\n\nHere’s a rough breakdown on what we’ve been working on:\n\n### Parsing\n\nMDX document parsing is significantly improved.\nWe won’t get into the nitty gritty here, but we’ve seen how MDX is used in\nreal-world projects, integrated the edge cases we came across into our test\nsuite, and now handle JSX, imports, and exports much more intuitively.\nPlease open an issue if you find a case we haven’t covered!😸\n\n### remark-mdx\n\n`remark-mdx` is the syntactic extension for MDX in remark.\nIt provides the parsing functionality for MDX as a\n*[remark](https://github.com/remarkjs/remark) plugin*.\nThat sounds a bit meta.\nWhat it means is that before we had the syntax parsing bits *in* the library\n(unusable from the outside), and now it’s externalized (usable from the\noutside).\nThis is useful if you want to inspect or transform MDX documents.\nFor example, it allows tools like prettier to use the exact same parser used by\nMDX core.\nOr you could use `remark-mdx` in combination with\n[remark-lint](https://github.com/remarkjs/remark-lint) to check your MDX.\n\n### Custom pragma\n\nWith v1 we’ve moved away from using `MDXTag` and are using a custom pragma which\nwraps `React.createElement`.\nWe decided to update this approach so the JSX output is more legible,\nlighterweight, and more customizable.\n**This means MDX can be used with any React, Vue, Preact, or any other library\nwith JSX support**.\n\nSpecial thanks to [@christopherbiscardi][christopherbiscardi]\nfor implementing this feature.\n\n[Read the blog post](/blog/custom-pragma/)\n\n### 📚 Documentation\n\n**Good libraries need great docs**, so we’ve been working on adding content and\nimproving the overall documentation website experience.\n\n* Search (thanks Algolia)\n* [Guides](/guides/)\n* [Automatic deployment via ZEIT][zeit]\n* [Custom Gatsby theme][gatsbyjs]\n* Reorganization of docs for intuitiveness\n* Full page rewrites to improve clarity\n\nSpecial thanks to [@jxnblk](https://github.com/jxnblks) and\n[@wooorm][wooorm] for their help improving the docs and\nupdating the build tooling.\n\n## Breaking changes\n\nIn order to make some improvements we were forced to introduce a few breaking\nchanges.\n**These were the result of real-world production testing and feedback**.\nThe community has evolved and we’ve come up with newer, better ideas over the\nlast year.\nWe have made sure the impact is small and have written a full migration guide.\n\n* 🚨`@mdx-js/tag` is replaced by `@mdx-js/react` and an `@mdx` pragma\n  — [migration guide](/migrating/v1#pragma)\n* MDXProvider now merges component contexts when nested\n  — [migration guide](/migrating/v1#mdxprovider)\n* React support now requires `>= 16.8` in `@mdx-js/react`\n  — [migration guide](/migrating/v1#react)\n\n[Read the full v1 migration guide](/migrating/v1)\n\n### Deprecations\n\nWe only needed to introduce one deprecation.\nThe `mdPlugins` and `hastPlugins` options have been renamed `remarkPlugins` and\n`rehypePlugins` respectively.\nFor the time being we will issue a warning when the old options are used.\nIn v2, the old options will be removed.\n\n## 📈 Growth\n\nA major release is always a good time to take a step back and reflect on what’s\nbeen happening in terms of growth and the greater community.\nThe ecosystem surrounding MDX has already grown larger than we ever dreamed.\nWe’ve also seen projects/products/application we never even imagined.\n\n### Numbers\n\n* **Downloads**: 125,000/week, 2.4M total\n* **Stars**: 6,200\n* **Contributors**: 50\n* **Pull requests**: 281\n* **Commits**: 670\n\nThe contributor growth is one of the most important aspects here as we have\nnumerous community members that are familiar with MDX internals.\nThis allows us to continually improve the project and spread the workload\nagainst an ever growing team of contributors.\n\n[See the contributor graph](https://github.com/mdx-js/mdx/graphs/contributors?from=2017-12-17\\&to=2019-04-11\\&type=c)\n\n### Ecosystem\n\n* [Prettier](https://prettier.io)\n* [Docz](https://docz.site)\n* [MDX Deck](https://github.com/jxnblk/mdx-deck)\n* [Next.js](https://nextjs.org)\n* [Gatsby][gatsbyjs]\n* [AST Explorer](https://astexplorer.net)\n* [Vue support (alpha)](/docs/getting-started/#vue)\n* [Demoboard](https://frontarm.com/demoboard/)\n* [Editors](/docs/getting-started/#editor)\n\n## 🛣 Roadmap\n\nWith v1 released we have a roadmap in place that we’ll continue working towards\nover the next 6 months or so in addition to bug fixes and parsing issues we\nmight encounter.\n\n* MDXs: [#454](https://github.com/mdx-js/mdx/issues/454)\n* Interleaving: [#195](https://github.com/mdx-js/mdx/issues/195)\n* Global shortcodes: [#508](https://github.com/mdx-js/mdx/pull/508)\n* Stable Vue support: [#238](https://github.com/mdx-js/mdx/issues/238)\n* Blocks: MDX WYSIWYG: [blocks/blocks][blocks]\n* MDX playground inspired by AST Explorer: [#220](https://github.com/mdx-js/mdx/issues/220)\n* New splash page: [#444](https://github.com/mdx-js/mdx/issues/444)\n* Showcase page: [#414](https://github.com/mdx-js/mdx/issues/414)\n\n### Vue support\n\nSupporting Vue is an important goal for MDX and is one of the primary reasons\nwe’ve rearchitected MDX to use custom pragma.\nWe’re delighted that **we now have an alpha version for Vue working**.\nWe’d love it if anyone from the Vue community wants to give it a try and provide\nfeedback.\n\n[See the Vue example](https://github.com/mdx-js/mdx/tree/36cb41b/examples/vue)\n\n### Blocks project\n\nOne of the key missing aspects of authoring MDX documents is the editing\nexperience.\nCurrently, there isn’t an approachable way to write MDX unless you enjoy working\nin a text editor and writing raw Markdown/code.\nWe’d like to solve that and have begun work on an MDX “blocks editor” that’s a\n**content-focused WYSIWYG**.\nNot to mention, we’ll be doing all that we can to make sure the editor is as\naccessible as it can be from the beginning.\n\nWhen we have a beta ready we will be open sourcing it and announcing, so stay\ntuned.\n\n[Check out the Blocks project][blocks]\n\n## unified collective\n\nMDX is part of the unified collective, which is an open source ecosystem for\ndealing with many sources of content.\nunified projects are used all over the web, and it would never be possible\nwithout financial support from our fine sponsors.\n\n* [ZEIT][] 🥇\n* [Gatsby][gatsbyjs] 🥇\n* [Holloway](https://www.holloway.com) 🥉\n* [Backers](https://opencollective.com/unified#budget) 🏆\n* [You?](https://opencollective.com/unified)👤\n\n## 🙏 Thanks\n\nWe’d like to say thanks to all our contributors and our happy users.\nSpecial thanks to\n[@wooorm][wooorm],\n[@silvenon](https://github.com/silvenon),\n[@timneutkens](https://github.com/timneutkens),\n[@ChristopherBiscardi][christopherbiscardi],\n[@jxnblk](https://github.com/jxnblk),\n[@alexandernanberg](https://github.com/alexandernanberg),\n[@jescalan](https://github.com/jescalan),\n[@Jarred-Sumner](https://github.com/Jarred-Sumner),\n[@leimonio](https://github.com/leimonio),\n[@ticky](https://github.com/ticky),\n[@jamesknelson](https://github.com/jamesknelson),\n[@pshrmn](https://github.com/pshrmn),\n[@rauchg](https://github.com/rauchg),\n[@joelhooks](https://github.com/joelhooks),\n[@jlengstorf](https://github.com/jlengstorf),\n[@johnlindquist](https://github.com/johnlindquist),\n[@kyleamathews](https://github.com/kyleamathews),\n[@kentcdodds](https://github.com/kentcdodds),\n[@wesbos](https://github.com/wesbos),\n[@rosew](https://github.com/rosew),\n[@pedronauck](https://github.com/pedronauck),\n[@tayiorbeii](https://github.com/tayiorbeii),\n[@nickbender](https://github.com/nickbender),\n[@ntaylor89](https://github.com/ntaylor89),\n[@mxstbr](https://github.com/mxstbr),\n[@manovotny](https://github.com/manovotny),\n[@xyc](https://github.com/xyc),\n[@filoxo](https://github.com/filoxo),\n[@millette](https://github.com/millette),\n[@hugmanrique](https://github.com/hugmanrique),\n[@johnsherrard](https://github.com/johnsherrard),\n[@sw-yx](https://github.com/sw-yx),\nand anyone we may have forgotten.\n\n[blocks]: https://github.com/blocks/blocks\n\n[christopherbiscardi]: https://github.com/christopherbiscardi\n\n[gatsbyjs]: https://gatsbyjs.org\n\n[wooorm]: https://github.com/wooorm\n\n[zeit]: https://zeit.co\n"
  },
  {
    "path": "docs/blog/v2.mdx",
    "content": "import {Note} from '../_component/note.jsx'\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2022-02-01')\n}\n\n<Note type=\"legacy\">\n  **Note**: This is an old blog post.\n  The below is kept as is for historical purposes.\n</Note>\n\n<Note type=\"info\">\n  **Note**: Info on how to migrate is available in our\n  [Version 2 migration guide][migrating].\n</Note>\n\n# MDX 2\n\nVersion 2 of MDX was released after years of hard work, and has many\nimprovements.\nHere are the highlights:\n\n{/* more */}\n\n<div className=\"emoji-list\">\n  * 📝 **Improved syntax** makes it easier to use markdown in JSX\n  * 🧑‍💻 **JavaScript expressions** turn `{2 * Math.PI}` into {2 * Math.PI}\n  * 🔌 New **esbuild**, **Rollup**, and **Node.js** integrations\n  * ⚛️ **Any JSX runtime**: React, Preact, Vue, Emotion, you name it, they’re\n    all supported\n  * 🌳 **Improved AST** exposes more info in greater detail\n  * 🏃‍♀️ Compiles at least **25% faster**\n  * 🚴 Generated code runs twice as fast (**100% faster**)\n  * 🚄 Bundle size of `@mdx-js/mdx` is more than three times as small\n    (**250% smaller**)\n  * 🧵 …and much, so much more\n</div>\n\nIt’s been 4 years since this project was announced.\n2½ since we released our stable version 1.\n**We’re proud to finally release v2!**\nLet’s dive in!\n\n## Contents\n\n* [Improvements to the MDX format](#improvements-to-the-mdx-format)\n* [Rollup, esbuild, and other integrations](#rollup-esbuild-and-other-integrations)\n* [Architectural improvements](#architectural-improvements)\n* [TypeScript](#typescript)\n* [Docs & site](#docs--site)\n* [Breaking changes](#breaking-changes)\n* [Thanks](#thanks)\n\n## Improvements to the MDX format\n\nWe’ve spent a lot of time thinking and trying out different ways to improve the\nformat.\nOriginally, the format was very close to how markdown, and HTML in markdown,\nworks.\nWe found that the old behavior often yielded unexpected results.\nIn version 2, we shift the format a little bit closer to how JS(X) works.\n\nTake for example this MDX file:\n\n```mdx chrome=no\n<div>*hi*?</div>\n\n<div>\n  # hi?\n</div>\n\n<main>\n  <div>\n\n    # hi?\n\n  </div>\n</main>\n```\n\n<div className=\"big-columns\">\n  <div>\n    In version 1, that was equivalent to the following JSX:\n\n    ```tsx chrome=no\n    <>\n      <div>*hi*?</div>\n      <div>\n        # hi?\n      </div>\n      <main>\n        <div>\n          <pre><code># hi?</code></pre>\n        </div>\n      </main>\n    </>\n    ```\n  </div>\n\n  <div>\n    In version 2, it’s equivalent to the following JSX:\n\n    ```tsx chrome=no\n    <>\n      <div><em>hi</em>?</div>\n      <div>\n        <h1>hi?</h1>\n      </div>\n      <main>\n        <div>\n          <h1>hi?</h1>\n        </div>\n      </main>\n    </>\n    ```\n  </div>\n</div>\n\nWe believe it’s more intuitive that markdown “inlines” such as emphasis can form\nbetween tags on the same line (first `<div>`), “blocks” such as headings can\nform if they’re on their own line (second `<div>`), and indentation is allowed\nrather than forming code (third `<div>`).\n\nWe also added support for JavaScript expressions, take for example:\n\n<div className=\"big-columns\">\n  <div>\n    ```mdx path=\"expressions.mdx\"\n    export const authors = [\n      {name: 'Jane', email: 'hi@jane.com'},\n      {name: 'John', github: '@johno'}\n    ]\n    export const published = new Date('2022-02-01')\n\n    Written by: {new Intl.ListFormat('en').format(authors.map(d => d.name))}.\n\n    Published on: {new Intl.DateTimeFormat('en', {dateStyle: 'long'}).format(published)}.\n    ```\n  </div>\n\n  <div>\n    ```tsx path=\"equivalent.jsx\"\n    <>\n      <p>Written by: Jane and John.</p>\n      <p>Published on: February 1, 2022.</p>\n    </>\n    ```\n  </div>\n</div>\n\nAs the format moves a little further from markdown towards JSX, we’ve added\nsupport for loading “normal” markdown without our syntax extensions.\nIf you’re using our bundler integration `@mdx-js/loader` (or `@mdx-js/rollup`,\n`@mdx-js/esbuild`, or `@mdx-js/node-loader`, see next section), then that’ll\njust work: import `readme.mdx` and it’s seen as the MDX format, import\n`readme.md` and it’s seen as markdown, based on their extensions.\n\nThe MDX format is described in [§ What is MDX?][what]\n\n## Rollup, esbuild, and other integrations\n\nWhen we started out, Babel, webpack, and React were ubiquitous in the JavaScript\necosystem and we built MDX on them.\nFor version 2, we worked hard to make them optional.\nThey’re no longer required and MDX can more easily be used with other tools.\n\nOn the bundler side, we’ve added new integrations: `@mdx-js/esbuild` for\nesbuild (an extremely fast bundler) and `@mdx-js/rollup` for Rollup (a bundler\nthat’s also used in Vite and WMR).\nYou can even import MDX files directly in Node.js with our new\n`@mdx-js/node-loader`.\n\nOn the runtime side, we can now compile JSX away to normal JavaScript and\nno longer need framework-specific code to glue them together with MDX.\nNow any JSX runtime, whether [classic or automatic][jsx-runtime], is supported.\nThis means MDX can be used with React, Preact, Vue, Emotion, Theme UI, Ink, you\nname it, plus anything that’s yet to be invented!\n\nSee [§ Getting started][getting-started] for a quick start but also in-depth\ninfo on how to integrate MDX with many different tools.\n\n## Architectural improvements\n\nTo make the syntax of the MDX format better and to allow new integrations and\narbitrary JSX runtimes, we’ve rewritten almost everything.\nPart of that effort was [micromark][], which is another story, but it means\nwe’re fully CommonMark (and optionally GFM) compliant, while also understanding\nmore about MDX files.\n\nNow we can throw an early error when there’s a typo and point to exactly where\nit happened, instead of a later bundler like webpack complaining about an error\nin an intermediate, unrecognizable, and broken string of JavaScript.\nIt also means that we have a new AST which describes the MDX syntax in more\ndetail — we even expose the embedded JavaScript.\nThis detailed AST allows plugins to enhance MDX in powerful new ways.\nIt also helped solve edge cases where MDX would previously crash.\nAnd it let us drop Babel.\n\nThis new architecture results in **25% faster** compilation, generated code\nthat runs twice as fast (**100% faster**), and that the bundle size of\n`@mdx-js/mdx` is more than three times as small (**250% smaller**).\n\nSee [¶ Architecture in `@mdx-js/mdx`][architecture] for more on how our compiler\nworks.\nSee [§ Extending MDX][extending] for several plugins that use the new tree to\nenhance MDX, how to use them and other plugins, and how to create plugins.\n\n## TypeScript\n\nAll [`@mdx-js/*` packages][packages] are now fully typed with [TypeScript][]\nthrough JSDoc comments.\nThat means our APIs are exposed as TypeScript types but also that our projects\nare type safe internally.\n\nWe’ve published [`@types/mdx`][types-mdx], a types-only package that can be used\nwith any (community) integration.\nYou can use it, if you’re importing MDX files, to type those imported\ncomponents.\n\nSee [¶ TypeScript in § Getting started][ts] for more on how to use configure\nTypeScript.\n\n## Docs & site\n\nMDX is used and liked a lot.\nBefore version 1 we had amassed a total of **2.5m downloads**.\nNow we hit that number every week.\nOur core compiler `@mdx-js/mdx` is used in **61k projects**.\nOur GitHub repo has **11.6k stars**.\n\nMany people help, often with docs.\n85 contributors committed to our repo since version 1.\nWe’re grateful for these contributions and all those individual insights,\nbut over the years it did result in some inconsistencies and duplicated content.\n\nFor version 2, we rewrote our docs from beginning to end to tell a consistent\nstory for new users, folks that do complex AST and compiler stuff, and\nanyone in between.\n\nWe also made a new website.\nIt’s built on MDX of course, [unified][] itself, and [React Server Components\n(RSC)][rsc].\nWhile we dogfood the former two as they’re projects we maintain, and the\nlatter is extremely experimental, we think compiling things ahead of time and\nbetting on hybrid models, compared to completely server-side sites or completely\nclient-side apps, is the smart choice for us and the web’s future.\n\nOur new site is heavily optimized and fast, gorgeous (subjective but hey), has\nrich metadata, and scores very well in performance and accessibility review\ntools such as Lighthouse and axe.\n\nSee [§ Contribute][contribute] for more on how to help.\n\n## Breaking changes\n\nWhen you’re ready to migrate, please see the\n[Version 2 migration guide][migrating].\n\n## Thanks\n\nWe’d like to say thanks to all our contributors and our happy users.\nSpecial thanks to\nJohn Otander ([**@johno**](https://github.com/johno)),\nChristian Murphy ([**@ChristianMurphy**](https://github.com/ChristianMurphy)),\nJounQin ([**@JounQin**](https://github.com/JounQin)),\nJack Bates ([**@jablko**](https://github.com/jablko)),\nSam Chen ([**@chenxsan**](https://github.com/chenxsan)),\nSam Robbins ([**@samrobbins85**](https://github.com/samrobbins85)),\nRemco Haszing ([**@remcohaszing**](https://github.com/remcohaszing)),\nLB ([**@laurieontech**](https://github.com/laurieontech)),\nGabriel Kirkley ([**@gdgkirkley**](https://github.com/gdgkirkley)>),\nHung-I Wang ([**@Gowee**](https://github.com/Gowee)),\nIlham Wahabi ([**@iwgx**](https://github.com/iwgx)),\nKaito Sugimoto ([**@HelloRusk**](https://github.com/HelloRusk)),\nKarl Horky ([**@karlhorky**](https://github.com/karlhorky)),\nKatie Hughes ([**@glitteringkatie**](https://github.com/glitteringkatie)),\nLachlan Campbell ([**@lachlanjc**](https://github.com/lachlanjc)),\nMarcy Sutton ([**@marcysutton**](https://github.com/marcysutton)),\nMarius Gundersen ([**@mariusGundersen**](https://github.com/mariusGundersen)),\nMarius-Remus Mate,\nMark Skelton ([**@mskelton**](https://github.com/mskelton)),\nMartin V ([**@ndresx**](https://github.com/ndresx)),\nMatija Marohnić ([**@silvenon**](https://github.com/silvenon)),\nMichael Oliver ([**@michaeloliverx**](https://github.com/michaeloliverx)),\nMichaël De Boey ([**@MichaelDeBoey**](https://github.com/MichaelDeBoey)),\nMuescha ([**@muescha**](https://github.com/muescha)),\nNorviah ([**@Norviah**](https://github.com/Norviah)),\nPaul Scanlon ([**@PaulieScanlon**](https://github.com/PaulieScanlon)),\nPeter Mouland ([**@peter-mouland**](https://github.com/peter-mouland)),\nPrince Wilson ([**@maxcell**](https://github.com/maxcell)),\nRafael Almeida ([**@rafaelalmeidatk**](https://github.com/rafaelalmeidatk)),\nRodrez ([**@rodrez**](https://github.com/rodrez)),\nRongjian Zhang ([**@pd4d10**](https://github.com/pd4d10)),\nTaeheon Kim ([**@lonyele**](https://github.com/lonyele)),\nTom Parker-Shemilt ([**@palfrey**](https://github.com/palfrey)),\nTry Ajitiono ([**@imballinst**](https://github.com/imballinst)),\nYamagishi Kazutoshi ([**@ykzts**](https://github.com/ykzts)),\nYoav Kadosh ([**@ykadosh**](https://github.com/ykadosh)),\nYordis Prieto ([**@Yordis**](https://github.com/Yordis)),\nAdrian Foong ([**@adrfoong**](https://github.com/adrfoong)),\nDan Abramov ([**@gaearon**](https://github.com/gaearon)),\n[**@ihupoo**](https://github.com/ihupoo),\n[**@nikhog**](https://github.com/nikhog),\n[**@redallen**](https://github.com/redallen),\nAkshay Kadam ([**@deadcoder0904**](https://github.com/deadcoder0904)),\nя котик пур-пур ([**@mvasilkov**](https://github.com/mvasilkov)),\nAnders D. Johnson ([**@AndersDJohnson**](https://github.com/AndersDJohnson)),\nAndrew Aylett ([**@andrewaylett**](https://github.com/andrewaylett)),\nAnkeet Maini ([**@ankeetmaini**](https://github.com/ankeetmaini)),\nBiswas Nandamuri ([**@Biswas-N**](https://github.com/Biswas-N)),\nBret ([**@bcomnes**](https://github.com/bcomnes)),\nChris Chinchilla ([**@ChrisChinchilla**](https://github.com/ChrisChinchilla)),\nChristopher Biscardi ([**@ChristopherBiscardi**](https://github.com/ChristopherBiscardi)),\nDan Overton ([**@dan-overton**](https://github.com/dan-overton)),\nDomitrius ([**@domitriusclark**](https://github.com/domitriusclark)),\nDovi Winberger ([**@dowi**](https://github.com/dowi)),\nEmmie Päivärinta ([**@emmiep**](https://github.com/emmiep)),\nEugene Ghanizadeh ([**@loreanvictor**](https://github.com/loreanvictor)),\nand anyone we may have forgotten.\n\n[architecture]: /packages/mdx/#architecture\n\n[contribute]: /community/contribute/\n\n[extending]: /docs/extending-mdx/\n\n[getting-started]: /docs/getting-started/\n\n[jsx-runtime]: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html\n\n[micromark]: https://github.com/micromark/micromark\n\n[migrating]: /migrating/v2/\n\n[packages]: /packages/\n\n[rsc]: https://reactjs.org/blog/2020/12/21/data-fetching-with-react-server-components.html\n\n[ts]: /docs/getting-started/#types\n\n[types-mdx]: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mdx\n\n[typescript]: https://www.typescriptlang.org\n\n[unified]: https://unifiedjs.com\n\n[what]: /docs/what-is-mdx/\n"
  },
  {
    "path": "docs/blog/v3.mdx",
    "content": "import {Note} from '../_component/note.jsx'\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2023-10-24')\n}\n\n<Note type=\"info\">\n  **Note**: Info on how to migrate is available in our\n  [Version 3 migration guide][migrating].\n</Note>\n\n# MDX 3\n\nVersion 3 already!\nThis major version contains a couple small changes.\nFor most folks, updating Node.js and plugins is all that’s needed!\n\n{/* more */}\n\n## Contents\n\n* [Breaking changes](#breaking-changes)\n* [Improvements to the MDX format](#improvements-to-the-mdx-format)\n  * [Adjacent block JSX and expressions in MDX](#adjacent-block-jsx-and-expressions-in-mdx)\n  * [Await in MDX](#await-in-mdx)\n  * [ES2024 in MDX](#es2024-in-mdx)\n* [Miscellaneous](#miscellaneous)\n* [Thanks](#thanks)\n\n## Breaking changes\n\nThe main breaking change is that Node.js 16 is now the minimum supported\nversion.\n\nAcross the ecosystem there were several small internal breaking changes.\nEverything’s released already.\nYou can update all plugins now.\nIf you ran into problems before, it should work now.\n\nWe also removed some infrequently used deprecated APIs.\nYou’re likely fine but gloss over the [v3 migration guide][migrating] if you\nget errors.\n\nImportant to note when you use your lesser-known but powerful `evaluate`, `run`,\nor `outputFormat: 'function-body'` APIs, please pass the `baseUrl` option.\nThat makes sure `import.meta.url`, `import`, and `export` work.\nYou’ll get a runtime error when those features are used otherwise.\n\n## Improvements to the MDX format\n\nThere’s also a few small improvements to the MDX format, some of which\ntechnically breaking.\n\n### Adjacent block JSX and expressions in MDX\n\nWe now accept block expressions right next to block JSX tags:\n\n```mdx chrome=no\n<style>{`\n\n  h1 {\n    color: blue;\n  }\n\n`}</style>\n```\n\nPreviously, there was a syntax error, and you had to add a newline between the\nangle brackets and the braces.\n\n### Await in MDX\n\nWe now accept `await` syntax:\n\n```mdx\n{await Promise.resolve(42)}\n```\n\nMost frameworks don’t support promises.\nWhether this works depends on that.\n\nPreviously, there was a runtime error that `await` was used in a context where\nit wasn’t allowed.\n\n### ES2024 in MDX\n\nYou can now use modern JavaScript syntax in MDX.\nAcorn, used internally, is now instructed to use ES2024.\n\n## Miscellaneous\n\nI refactored all the docs.\nUpdating every use example where needed.\nI also wrote a guide on how to inject components from anywhere:\n[§ Injecting components][injecting-components].\n\nThe site is a lot faster.\nThere’s a nice improved playground too: [try it out! »][playground].\nWe also have proper syntax highlighting here, thanks to\n[`wooorm/markdown-tm-language`][markdown-tm-language]\nand [`wooorm/starry-night`][starry-night].\n\nThe generated JS code is a little cleaner (the JSX pragma comment is removed\nand objects are sorted where needed), it also uses spreads instead of\n`Object.assign`, there’s a `'use strict'` added when needed, and the\n`MDXContent` is exported immediately.\n\n## Thanks\n\nWe’d like to say thanks to all our contributors and our happy users.\nSpecial thanks to\n北雁云依 ([**@BeiyanYunyi**](https://github.com/BeiyanYunyi)),\nChristian Murphy ([**@ChristianMurphy**](https://github.com/ChristianMurphy)),\nJokcyLou ([**@Jokcy**](https://github.com/Jokcy)),\nMaël Nison ([**@arcanis**](https://github.com/arcanis)),\nAndreas Deininger ([**@deining**](https://github.com/deining)),\nRemco Haszing ([**@remcohaszing**](https://github.com/remcohaszing)),\nSébastien Lorber ([**@slorber**](https://github.com/slorber)),\nVíctor Fernández ([**@victor23k**](https://github.com/victor23k)),\nTitus Wormer ([**@wooorm**](https://github.com/wooorm)),\nand anyone we may have forgotten.\n\n[injecting-components]: /guides/injecting-components/\n\n[markdown-tm-language]: https://github.com/wooorm/markdown-tm-language\n\n[migrating]: /migrating/v3/\n\n[playground]: /playground/\n\n[starry-night]: https://github.com/wooorm/starry-night\n"
  },
  {
    "path": "docs/community/about.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06')\n}\nexport const navSortSelf = 4\n\n# About\n\nThis article explains in short how MDX came to be and why it exists.\nIt also gives thanks to the people who’ve helped make it and inspired it.\n\n{/* more */}\n\n## What is MDX?\n\nMDX is the combination of markdown with JSX.\nSee [§ What is MDX?][what] for more info.\n\n## Why MDX?\n\nMarkdown does not have a syntax for custom components.\nMDX solves this.\n\nThere are many languages objectively better than markdown, however, markdown is\ngreat because:\n\n* It looks like what it means and is relatively easy to read\n* Although images are [confusing][], most stuff is relatively simple to write\n* It’s loose and ambiguous: it may not work but you won’t get an error (great\n  for someone posting a comment to a forum if they forgot an asterisk)\n\nMarkdown *does* have a way to extend it, HTML, but that has drawbacks:\n\n* HTML in markdown is naïve, how it’s parsed sometimes doesn’t make sense\n* HTML is unsafe by default, so it’s sometimes (partially) unsupported\n* HTML and markdown don’t mix well, resulting in confusing rules such as\n  blank lines or `markdown=\"1\"` attributes\n* HTML is coupled with browsers, markdown is useful for other things too\n\nThe frontend world has an alternative to HTML: JSX.\nJSX is great, amongst other things, because:\n\n* It has a relatively familiar syntax (like XML)\n* It’s agnostic to semantics and intended for compilers (can have any\n  domain-specific meaning)\n* It’s strict and unambiguous (great if an author forgot a slash somewhere, as\n  they’ll get an error early, instead of a book going to print with broken\n  stuff in it)\n\n## Who governs MDX?\n\nThe project is governed by the\n[unified collective][governance].\n\n## Who created MDX?\n\nThe idea of combining [markdown][commonmark], [JavaScript][], and [JSX][] was a\ncollaborative effort by\n[Guillermo Rauch][mdx-rauchg] (**[@rauchg][rauchg]**),\n[James K. Nelson][mdx-jamesknelson] (**[@jamesknelson][jamesknelson]**),\n[John Otander][mdx-johno] (**[@johno][johno]**),\nTim Neutkens (**[@timneutkens][timneutkens]**),\nBrent Jackson (**[@jxnblk][jxnblk]**),\nJessica Stokes (**[@ticky][ticky]**), and more.\n\nWhile everyone above was key to MDX, we want to stress the involvement of\n[John Otander][mdx-johno] (**[@johno][johno]**).\nJohn wrote most of the code for the first alpha and later stable version 1 of\nthis project!\n\n## Who designed the logo?\n\n[Logo designs][design] were created by [Evil Rabbit][] of [Vercel][].\n\n## What projects inspired MDX?\n\nThe following projects, languages, and articles helped shape MDX either in\nimplementation or inspiration.\n\nThe [markdown][] and [JSX][] languages inspired MDX.\nMarkdown was [created by John Gruber][markdown] (**[@gruber][gruber]**).\n[CommonMark][], the most popular markdown variant, by John McFarlane\n(**[@jgm][jgm]**) et al.\nJSX was created by Sebastian Markbåge (**[@sebmarkbage][sebmarkbage]**) et\nal. at Facebook, Inc.\n\nThe `@mdx-js/*` projects currently make heavy use of [unified][] (specifically\n[micromark][], [remark][] and [rehype][]) and [Acorn][].\nunified, remark, rehype, and related tools were created by Titus Wormer\n(**[@wooorm][wooorm]**) et al.\nAcorn by Marijn Haverbeke (**[@marijnh][marijnh]**) et al.\n\nThe following projects inspired `@mdx-js/*` originally:\n\n{/* Note: please keep the original project names intact: */}\n\n* [`jamesknelson/mdxc`](https://github.com/frontarm/mdx-util)\n* [`ticky/markdown-component-loader`](https://github.com/ticky/markdown-component-loader)\n* [`threepointone/markdown-in-js`](https://github.com/threepointone/markdown-in-js)\n* [`fazouane-marouane/remark-jsx`](https://github.com/remarkjs/remark-jsx)\n* [`mapbox/remark-react`](https://github.com/remarkjs/remark-react)\n* [`rx-ts/eslint-mdx`](https://github.com/mdx-js/eslint-mdx)\n\nThe following articles inspired `@mdx-js/*` originally:\n\n* [IA Markdown Content Blocks](https://github.com/iainc/Markdown-Content-Blocks)\n* [Idyll: Markup language for interactive documents](https://idyll-lang.org)\n\n[acorn]: https://github.com/acornjs/acorn\n\n[commonmark]: https://spec.commonmark.org/current/\n\n[confusing]: https://twitter.com/gruber/status/1246489863932821512\n\n[design]: https://github.com/mdx-js/design\n\n[evil rabbit]: https://evilrabb.it\n\n[governance]: https://github.com/unifiedjs/collective\n\n[gruber]: https://github.com/gruber\n\n[jamesknelson]: https://github.com/jamesknelson\n\n[javascript]: https://tc39.es/ecma262/\n\n[jgm]: https://github.com/jgm\n\n[johno]: https://github.com/johno\n\n[jsx]: https://facebook.github.io/jsx/\n\n[jxnblk]: https://github.com/jxnblk\n\n[marijnh]: https://github.com/marijnh\n\n[markdown]: https://daringfireball.net/2004/03/introducing_markdown\n\n[mdx-jamesknelson]: https://github.com/frontarm/mdx-util/tree/0f5f6d62bac4b83edc4bc3890dde3011079fa318\n\n[mdx-johno]: https://github.com/mdx-js/mdx/tree/a96ede2c104084ae21efa8bd95319011e558ec9d\n\n[mdx-rauchg]: https://spectrum.chat/frontend/general/mdx-proposal~1021be59-2738-4511-aceb-c66921050b9a\n\n[micromark]: https://github.com/micromark/micromark\n\n[rauchg]: https://github.com/rauchg\n\n[rehype]: https://github.com/rehypejs/rehype\n\n[remark]: https://github.com/remarkjs/remark\n\n[sebmarkbage]: https://github.com/sebmarkbage\n\n[ticky]: https://github.com/ticky\n\n[timneutkens]: https://github.com/timneutkens\n\n[unified]: https://unifiedjs.com\n\n[vercel]: https://vercel.com\n\n[what]: /docs/what-is-mdx/\n\n[wooorm]: https://github.com/wooorm\n"
  },
  {
    "path": "docs/community/contribute.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2018-11-04')\n}\nexport const navSortSelf = 2\n\n# Contribute\n\nThis article explains how to contribute to MDX.\nPlease read through the following guidelines.\n\n{/* more */}\n\n<Note type=\"important\">\n  **Important**: before participating in our community, please read our\n  [code of conduct][coc].\n  By interacting with this repository, organization, or community you agree to\n  abide by its terms.\n</Note>\n\n## Contributions\n\nThere’s several ways to contribute, not just by writing code.\nIf you have questions, see [§ Support][support].\nIf you can provide financial support, see [§ Sponsor][sponsor].\n\n### Improve docs\n\nAs a user you’re perfect for helping us improve our docs.\nTypo corrections, error fixes, better explanations, new examples, etcetera.\nAll MDX docs live in `docs/`.\n\nYou can run the docs locally, see [¶ Site][site] below.\n\n### Improve issues\n\nSome issues lack information, aren’t reproducible, or are just incorrect.\nYou can help by trying to make them easier to resolve.\nExisting issues might benefit from your unique experience or opinions.\n\n### Write code\n\nCode contributions are very welcome.\nIt’s probably a good idea to first post a question or open an issue to report a\nbug or suggest a new feature before creating a pull request.\n\n## Submitting an issue\n\n* The issue tracker is for issues.\n  Use discussions for support\n* Search the issue tracker (including closed issues) before opening a new\n  issue\n* Ensure you’re using the latest version of our packages\n* Use a clear and descriptive title\n* Include as much information as possible: steps to reproduce the issue,\n  error message, version, operating system, etcetera\n* The more time you put into an issue, the better we will be able to help you\n* The best issue report is a failing test proving it\n\n## Submitting a pull request\n\n* See [¶ Project][project] below for info on how the project is structured,\n  how to test, and how to build the site\n* Non-trivial changes are often best discussed in an issue first, to prevent\n  you from doing unnecessary work\n* For ambitious tasks, you should try to get your work in front of the\n  community for feedback as soon as possible\n* New features should be accompanied by tests and documentation\n* Don’t include unrelated changes\n* Test before submitting code by running `npm test`\n* Write a convincing description of why we should land your pull request:\n  it’s your job to convince us\n\n## Project\n\n### Structure\n\nMDX is a monorepo.\nAll packages are in `packages/`.\nDocumentation is in `docs/`.\n\n### Tests\n\nTo run the tests, first do `npm install`, then do `npm test`.\nThis ensures everything is okay, from code style to unit tests to types.\n\n### Site\n\nTo build the site, first do `npm install`, then do `npm run docs`.\nThis produces the website in `public/`.\n\n### Release\n\nTo release a new version, do:\n\n1. update `version`s of packages with a patch, minor, or major (make sure to\n   update dependency ranges on monorepo packages when needed):\n   ```sh\n   npm version minor --workspaces --no-git-tag-version\n   ```\n2. commit and tag using the version (without `v`) as the message:\n   ```sh\n   git commit --all --message 1.2.3 && git tag 1.2.3 && git push && git push --tags\n   ```\n3. release to the npm registry:\n   ```sh\n   npm publish --workspaces\n   ```\n4. add a changelog entry for the release on GitHub:\n   ```sh\n   open https://github.com/mdx-js/mdx/releases\n   ```\n\n## Resources\n\n* [Good first issues in the MDX repository](https://github.com/mdx-js/mdx/labels/good%20first%20issue%20👋)\n* [How to contribute to open source](https://opensource.guide/how-to-contribute/)\n* [Making your first contribution](https://medium.com/@vadimdemedes/making-your-first-contribution-de6576ddb190)\n* [Using pull requests](https://help.github.com/articles/about-pull-requests/)\n* [GitHub help](https://help.github.com)\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[project]: #project\n\n[site]: #site\n\n[sponsor]: /community/sponsor/\n\n[support]: /community/support/\n"
  },
  {
    "path": "docs/community/index.mdx",
    "content": "{\n  /**\n   * @import {Item} from '../_component/sort.js'\n   */\n\n  /**\n   * @typedef Props\n   * @property {Item} navigationTree\n   */\n}\n\nimport assert from 'node:assert/strict'\nimport {NavigationGroup} from '../_component/nav.jsx'\n\nexport const info = {\n  author: [{name: 'MDX Contributors'}],\n  modified: new Date('2024-07-04'),\n  published: new Date('2021-11-01')\n}\nexport const navSortSelf = 6\n\n# Community\n\nThese pages explain how to contribute, get help, sponsor us, share your work,\nand some background information.\n\n{\n  (function () {\n    const navigationTree = props.navigationTree\n    const category = navigationTree.children.find(function (item) {\n      return item.name === '/community/'\n    })\n    assert(category)\n\n    return (\n      <nav>\n        <NavigationGroup items={category.children} includeDescription />\n      </nav>\n    )\n  })()\n}\n"
  },
  {
    "path": "docs/community/projects.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'}\n  ],\n  modified: new Date('2021-11-01'),\n  published: new Date('2018-08-11')\n}\nexport const navSortSelf = 5\n\n# Projects\n\n<Note type=\"info\">\n  **Note**: have another project built with MDX?\n  Please send a PR to add it here!\n</Note>\n\nThis page lists community projects using MDX.\n\n{/* more */}\n\n## Apps\n\n* [demoboard][]: The simplest editor alive\n\n## Libraries\n\n* [ok-mdx][]: Browser-based MDX editor\n* [docz][]: Documentation framework\n* [mdx-deck][]: MDX-based presentation decks\n* [mdx-docs][]: Next-based documentation framework\n* [mdx-paper][]: MDX-based research articles\n* [spectacle-boilerplate-mdx][]: Boilerplate that facilitates using MDX with\n  Spectacle\n* [Charge][]: An opinionated, zero-config static site generator\n* [MDNEXT][]: An ecosystem of tools to get your NextJS + MDX projects blasting\n  off\n\n## Sites\n\n* This website!\n* [Prisma][]\n* [Max Stoiber’s Blog][mxstbr]\n\n## Other related links\n\n* [awesome-mdx][]\n* [MDX: content for kings and princesses][mdx-fairy-tale]\n\n[awesome-mdx]: https://github.com/transitive-bullshit/awesome-mdx\n\n[charge]: https://charge.js.org\n\n[demoboard]: https://frontarm.com/demoboard\n\n[docz]: https://www.docz.site/\n\n[mdnext]: https://github.com/domitriusclark/mdnext\n\n[mdx-deck]: https://github.com/jxnblk/mdx-deck\n\n[mdx-docs]: https://github.com/jxnblk/mdx-docs\n\n[mdx-fairy-tale]: https://github.com/DeveloperMode/mdx-fairy-tale\n\n[mdx-paper]: https://github.com/hubgit/mdx-paper\n\n[mxstbr]: https://mxstbr.com\n\n[ok-mdx]: https://github.com/jxnblk/ok-mdx\n\n[prisma]: https://www.prisma.io/docs\n\n[spectacle-boilerplate-mdx]: https://github.com/FormidableLabs/spectacle-boilerplate-mdx\n"
  },
  {
    "path": "docs/community/sponsor.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06'),\n}\nexport const navSortSelf = 3\n\n# Sponsor\n\nThis article explains how to contribute financially to MDX.\n\n{/* more */}\n\nIt’s possible to support us financially by becoming a backer or sponsor of\nunified through either [Open Collective][oc] or [GitHub Sponsors][gh].\nWith this support, we can pay for project leadership, finance non-coding work,\nor for fun things for the community like getting stickers for contributors.\nYou’ll be helping unified’s maintainers manage and improve existing projects,\nand additionally support our work to develop new and exciting projects, such\nas [micromark][].\n\n{\n  <table>\n    <tr valign=\"middle\">\n      <td width=\"20%\" align=\"center\" rowSpan={2} colSpan={2}>\n        <a href=\"https://vercel.com\" rel=\"sponsored nofollow\">Vercel</a><br /><br />\n        <a href=\"https://vercel.com\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/14985020?s=256&v=4\" width=\"128\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"20%\" align=\"center\" rowSpan={2} colSpan={2}>\n        <a href=\"https://motif.land\" rel=\"sponsored nofollow\">Motif</a><br /><br />\n        <a href=\"https://motif.land\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/74457950?s=256&v=4\" width=\"128\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"20%\" align=\"center\" rowSpan={2} colSpan={2}>\n        <a href=\"https://www.hashicorp.com\" rel=\"sponsored nofollow\">HashiCorp</a><br /><br />\n        <a href=\"https://www.hashicorp.com\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/761456?s=256&v=4\" width=\"128\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"20%\" align=\"center\" rowSpan={2} colSpan={2}>\n        <a href=\"https://www.gitbook.com\" rel=\"sponsored nofollow\">GitBook</a><br /><br />\n        <a href=\"https://www.gitbook.com\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/7111340?s=256&v=4\" width=\"128\" /></a>\n      </td>\n      <td width=\"20%\" align=\"center\" rowSpan={2} colSpan={2}>\n        <a href=\"https://www.gatsbyjs.org\" rel=\"sponsored nofollow\">Gatsby</a><br /><br />\n        <a href=\"https://www.gatsbyjs.org\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/12551863?s=256&v=4\" width=\"128\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n    </tr>\n    <tr valign=\"middle\" />\n    <tr valign=\"middle\">\n      <td width=\"20%\" align=\"center\" rowSpan={2} colSpan={2}>\n        <a href=\"https://www.netlify.com\" rel=\"sponsored nofollow\">Netlify</a><br /><br />\n        {/* OC has a sharper image */}\n        <a href=\"https://www.netlify.com\" rel=\"sponsored nofollow\"><img src=\"https://images.opencollective.com/netlify/4087de2/logo/256.png\" width=\"128\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"10%\" align=\"center\">\n        <a href=\"https://www.coinbase.com\" rel=\"sponsored nofollow\">Coinbase</a><br /><br />\n        <a href=\"https://www.coinbase.com\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/1885080?s=256&v=4\" width=\"64\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"10%\" align=\"center\">\n        <a href=\"https://themeisle.com\" rel=\"sponsored nofollow\">ThemeIsle</a><br /><br />\n        <a href=\"https://themeisle.com\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/58979018?s=128&v=4\" width=\"64\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"10%\" align=\"center\">\n        <a href=\"https://expo.io\" rel=\"sponsored nofollow\">Expo</a><br /><br />\n        <a href=\"https://expo.io\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/12504344?s=128&v=4\" width=\"64\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"10%\" align=\"center\">\n        <a href=\"https://boostnote.io\" rel=\"sponsored nofollow\">Boost Note</a><br /><br />\n        <a href=\"https://boostnote.io\" rel=\"sponsored nofollow\"><img src=\"https://images.opencollective.com/boosthub/6318083/logo/128.png\" width=\"64\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"10%\" align=\"center\">\n        <a href=\"https://markdown.space\" rel=\"sponsored nofollow\">Markdown Space</a><br /><br />\n        <a href=\"https://markdown.space\" rel=\"sponsored nofollow\"><img src=\"https://images.opencollective.com/markdown-space/e1038ed/logo/128.png\" width=\"64\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"10%\" align=\"center\">\n        <a href=\"https://www.holloway.com\" rel=\"sponsored nofollow\">Holloway</a><br /><br />\n        <a href=\"https://www.holloway.com\" rel=\"sponsored nofollow\"><img src=\"https://avatars1.githubusercontent.com/u/35904294?s=128&v=4\" width=\"64\" style={{display: 'block', maxWidth: '100%'}} /></a>\n      </td>\n      <td width=\"10%\" />\n      <td width=\"10%\" />\n    </tr>\n    <tr valign=\"middle\">\n      <td width=\"100%\" align=\"center\" colSpan={8}>\n        <br />\n        <a href=\"https://opencollective.com/unified\"><strong>You?</strong></a>\n        <br /><br />\n      </td>\n    </tr>\n  </table>\n}\n\n[gh]: https://github.com/sponsors/unifiedjs\n\n[micromark]: https://github.com/micromark/micromark\n\n[oc]: https://opencollective.com/unified\n"
  },
  {
    "path": "docs/community/support.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2019-07-03')\n}\nexport const navSortSelf = 1\n\n# Support\n\nThis article explains where to get help with MDX.\nPlease read through the following guidelines.\n\n{/* more */}\n\n<Note type=\"important\">\n  **Important**: before participating in our community, please read our\n  [code of conduct][coc].\n  By interacting with this repository, organization, or community you agree to\n  abide by its terms.\n</Note>\n\n## Asking quality questions\n\nQuestions can go to [GitHub Discussions][chat].\n\nHelp us help you!\nSpend time framing questions and add links and resources.\nSpending the extra time up front can help save everyone time in the long run.\nHere are some tips:\n\n* Read through [§ Getting started][getting-started]\n* [Talk to a duck!][rubberduck]\n* Don’t fall for the [XY problem][xy]\n* Search to find out if a similar question has been asked\n* Try to define what you need help with:\n  * Is there something in particular you want?\n  * What problem are you encountering and what steps have you taken to try\n    and fix it?\n  * Is there a concept you don’t understand?\n* Provide sample code, such as a [CodeSandbox][cs] or video, if possible\n* Screenshots can help, but if there’s important text such as code or error\n  messages in them, please also provide those as text\n* The more time you put into asking your question, the better we can help you\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[cs]: https://codesandbox.io\n\n[getting-started]: /docs/getting-started/\n\n[rubberduck]: https://rubberduckdebugging.com\n\n[xy]: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem/66378#66378\n"
  },
  {
    "path": "docs/docs/extending-mdx.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06')\n}\nexport const navSortSelf = 4\n\n# Extending MDX\n\nThis article explains how to extend MDX content—specifically, how to *transform*\ncontent with plugins. {/* more */}\nSee [§ Using MDX][use] for how to pass components, props, and the layout.\nSee [§ Getting started][start] for how to integrate MDX into your project.\n\n## Contents\n\n* [Components & plugins](#components--plugins)\n  * [List of components](#list-of-components)\n  * [List of plugins](#list-of-plugins)\n* [Using plugins](#using-plugins)\n* [Creating plugins](#creating-plugins)\n\n## Components & plugins\n\nThere are three extension points when using `@mdx-js/mdx` or one of its\nintegrations:\n\n* Options passed to the compiler (see [¶ API in `@mdx-js/mdx`][api])\n* Plugins that hook into several stages of compilation (see [remark\n  plugins][remark-plugins], [rehype plugins][rehype-plugins], and\n  [recma plugins][recma-plugins])\n* Components passed, defined, or imported at runtime (see [§ Using MDX][use])\n\nMost of the time, these components and plugins are not coupled to MDX.\nFor example, if you’re using React, then you can use\n[`<ReactConfetti />`][react-confetti] with MDX.\nOr, you can use the plugin [`remark-gfm`][remark-gfm] to turn on GFM features in\nMDX.\nSometimes, we need specific components or specific plugins to work with MDX.\nWe’re compiling those here on this page.\n\n### List of components\n\n* [`PaulieScanlon/mdx-embed`](https://github.com/PaulieScanlon/mdx-embed)\n  — React components for embedding 3rd party content, integrates w/\n  MDX provider\n* [`system-ui/theme-ui`](https://github.com/system-ui/theme-ui)\n  — React components for building consistent apps, integrates w/ MDX provider\n\n{/*\n  * Please use alpha sorting on **project** name!\n  * You can use this template:\n  *\n  * ```markdown\n  * * [`user/project`](https://github.com/user/project)\n  *   — somewhat short description of the project\n  * ```\n  */}\n\n<Note type=\"info\">\n  **Note**: have another component that *specifically* works with MDX?\n  Please send a PR to add it here!\n</Note>\n\n### List of plugins\n\nSee also the [list of remark plugins][remark-plugins],\n[list of rehype plugins][rehype-plugins], and\n[list of recma plugins][recma-plugins].\n\n* [`remcohaszing/recma-export-filepath`](https://github.com/remcohaszing/recma-export-filepath)\n  — export the filepath\n* [`ipikuka/recma-mdx-change-props`](https://github.com/ipikuka/recma-mdx-change-props)\n  — changes the param as `_props` in the `_createMdxContent` function\n* [`domdomegg/recma-mdx-displayname`](https://github.com/domdomegg/recma-mdx-displayname)\n  — add a `displayName` to `MDXContent` components, to enable switching\n  on them in production\n* [`ipikuka/recma-mdx-escape-missing-components`](https://github.com/ipikuka/recma-mdx-escape-missing-components)\n  — set a default value of `() => null` for missing components instead of\n  throwing an error\n* [`remcohaszing/recma-mdx-is-mdx-component`](https://github.com/remcohaszing/recma-mdx-is-mdx-component)\n  — add an `isMdxComponent` field on MDX components\n* [`remcohaszing/recma-nextjs-static-props`](https://github.com/remcohaszing/recma-nextjs-static-props)\n  — generate [`getStaticProps`](https://nextjs.org/docs/basic-features/data-fetching/get-static-props)\n  exposing top level identifiers in Next.js\n* [`remcohaszing/recma-module-to-function`](https://github.com/remcohaszing/recma-module-to-function)\n  — convert a module into a function body\n* [`remcohaszing/rehype-mdx-code-props`](https://github.com/remcohaszing/rehype-mdx-code-props)\n  — interpret the code `meta` field as JSX props\n* [`remcohaszing/rehype-mdx-import-media`](https://github.com/remcohaszing/rehype-mdx-import-media)\n  — change media sources to JavaScript imports\n* [`remcohaszing/rehype-mdx-title`](https://github.com/remcohaszing/rehype-mdx-title)\n  — expose the page title as a string\n* [`boning-w/rehype-mdx-toc`](https://github.com/boning-w/rehype-mdx-toc)\n  — export the table of contents data into MDX module\n* [`re-xyr/remark-directive-mdx`](https://github.com/re-xyr/remark-directive-mdx)\n  — transform Markdown directives (`:directive[]`) to JSX elements\n* [`pangelani/remark-mdx-chartjs`](https://github.com/pangelani/remark-mdx-chartjs)\n  — replace fenced code blocks with charts using [`react-chartjs-2`](https://react-chartjs-2.js.org/).\n* [`remcohaszing/remark-mdx-frontmatter`](https://github.com/remcohaszing/remark-mdx-frontmatter)\n  — change frontmatter (YAML) metadata to exports\n* [`goodproblems/remark-mdx-math-enhanced`](https://github.com/goodproblems/remark-mdx-math-enhanced)\n  — enhance math with JavaScript inside it\n\n{/*\n  * Please use alpha sorting on **project** name!\n  * You can use this template:\n  *\n  * ```markdown\n  * * [`user/project`](https://github.com/user/project)\n  *   — somewhat short description of the project\n  * ```\n  */}\n\n<Note type=\"info\">\n  **Note**: have another unified plugin that *specifically* works with MDX?\n  Please send a PR to add it here!\n</Note>\n\n## Using plugins\n\nWhere to pass plugins is encoded in their name:\nremark plugins go in `remarkPlugins`,\nrehype plugins go in `rehypePlugins`,\nand recma plugins go in `recmaPlugins` of\n[`ProcessorOptions`][processor-options].\nThose fields expect lists of plugins and/or of `[plugin, options]`:\n\n```tsx twoslash\nimport {compile} from '@mdx-js/mdx'\nimport rehypeKatex from 'rehype-katex' // Render math with KaTeX.\nimport remarkFrontmatter from 'remark-frontmatter' // YAML and such.\nimport remarkGfm from 'remark-gfm' // Tables, footnotes, strikethrough, task lists, literal URLs.\nimport remarkMath from 'remark-math' // Support math like `$so$`.\n\nconst file = '# hi'\n\n// One plugin:\nawait compile(file, {remarkPlugins: [remarkGfm]})\n\n// A plugin with options:\nawait compile(file, {remarkPlugins: [[remarkFrontmatter, 'toml']]})\n\n// Two plugins:\nawait compile(file, {remarkPlugins: [remarkGfm, remarkFrontmatter]})\n\n// Two plugins, first w/ options:\nawait compile(file, {remarkPlugins: [[remarkGfm, {singleTilde: false}], remarkFrontmatter]})\n\n// remark and rehype plugins:\nawait compile(file, {rehypePlugins: [rehypeKatex], remarkPlugins: [remarkMath]})\n\n// remark and rehype plugins, last w/ options:\nawait compile(file, {\n  // A plugin with options:\n  rehypePlugins: [[rehypeKatex, {strict: true, throwOnError: true}]],\n  remarkPlugins: [remarkMath]\n})\n```\n\n## Creating plugins\n\nCreating a plugin for MDX is mostly the same as creating a plugin for remark,\nrehype, or recma.\nThere are several guides and recipes on that in [§ Learn on\n`unifiedjs.com`][learn].\n\nFor the MDX specific parts of plugins, it’s recommended to read\n[¶ Architecture][architecture] to learn how `@mdx-js/mdx` works.\nFor info on the node types that represent MDX specific features, see\n[¶ Syntax tree in `remark-mdx`][syntax-tree] and use our interactive\n[§ Playground][playground].\n\n[api]: /packages/mdx/#api\n\n[architecture]: /packages/mdx/#architecture\n\n[learn]: https://unifiedjs.com/learn/\n\n[playground]: /playground/\n\n[processor-options]: /packages/mdx/#processoroptions\n\n[react-confetti]: https://github.com/alampros/react-confetti\n\n[recma-plugins]: https://github.com/mdx-js/recma/blob/main/doc/plugins.md#list-of-plugins\n\n[rehype-plugins]: https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins\n\n[remark-gfm]: https://github.com/remarkjs/remark-gfm\n\n[remark-plugins]: https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins\n\n[start]: /docs/getting-started/\n\n[syntax-tree]: /packages/remark-mdx/#syntax-tree\n\n[use]: /docs/using-mdx/\n"
  },
  {
    "path": "docs/docs/getting-started.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-05')\n}\nexport const navSortSelf = 2\n\n# Getting started\n\nThis article explains how to integrate MDX into your project.\nIt shows how to use MDX with your bundler and JSX runtime of choice. {/* more */}\nTo understand how the MDX format works,\nwe recommend that you start with [§ What is MDX][what].\nSee [§ Using MDX][use] when you’re all set up and ready to use MDX.\n\n## Contents\n\n* [Prerequisites](#prerequisites)\n* [Quick start](#quick-start)\n  * [Bundler](#bundler)\n  * [JSX](#jsx)\n  * [Editor](#editor)\n  * [Types](#types)\n  * [Security](#security)\n* [Integrations](#integrations)\n  * [Bundlers](#bundlers)\n  * [Build systems](#build-systems)\n  * [Linters](#linters)\n  * [Compilers](#compilers)\n  * [Site generators](#site-generators)\n  * [JSX runtimes](#jsx-runtimes)\n  * [JavaScript engines](#javascript-engines)\n* [Further reading](#further-reading)\n\n## Prerequisites\n\nMDX relies on JSX,\nso it’s required that your project supports JSX as well.\nAny JSX runtime (React, Preact, Vue, etc.) will do.\nNote that we do compile JSX to JavaScript for you so you don’t have to set that\nup.\n\nAll `@mdx-js/*` packages are written in modern JavaScript.\nA [Node.js][node-js] version of 16 or later is needed to use them.\nOur packages are also [ESM only][github-gist-esm].\n\n<Note type=\"info\">\n  **Note**: Using Rust instead of Node.js?\n  Try [`mdxjs-rs`][mdxjs-rs]!\n</Note>\n\n## Quick start\n\n### Bundler\n\nMDX is a language that’s compiled to JavaScript.\n(We also compile regular markdown to JavaScript.)\nThe easiest way to get started is to use an integration for your bundler if you\nhave one:\n\n* if you use **esbuild** (or Bun),\n  install and configure [`@mdx-js/esbuild`][mdx-esbuild]\n* if you use **Rollup** (or Vite),\n  install and configure [`@mdx-js/rollup`][mdx-rollup]\n* if you use **webpack** (or Next.js),\n  install and configure [`@mdx-js/loader`][mdx-loader]\n\nYou can also use MDX without bundlers:\n\n* you can import MDX files in **Node.js** with\n  [`@mdx-js/node-loader`][mdx-node-loader]\n* you can use our core compiler [`@mdx-js/mdx`][mdx-mdx] to compile MDX files\n* you can use our core compiler [`@mdx-js/mdx`][mdx-mdx] to\n  [evaluate][api-evaluate] (compile *and run*) MDX files\n\nFor more info on these tools,\nsee their dedicated sections:\n[¶ Next.js][site-generator-next],\n[¶ Node.js][js-engine-node],\n[¶ Rollup][bundler-rollup],\n[¶ Vite][build-system-vite],\n[¶ esbuild][bundler-esbuild], and\n[¶ webpack][bundler-webpack].\n\n### JSX\n\nNow you’ve set up an integration or `@mdx-js/mdx` itself,\nit’s time to configure your JSX runtime.\n\n* if you use **React**,\n  that’s the default;\n  optionally install and configure [`@mdx-js/react`][mdx-react]\n* if you use **Preact**,\n  set [`jsxImportSource` in `ProcessorOptions`][api-processor-options] to\n  `'preact'`;\n  optionally install and configure [`@mdx-js/preact`][mdx-preact]\n* if you use **Svelte**,\n  install [`svelte-jsx`][svelte-jsx],\n  and set [`jsxImportSource` in `ProcessorOptions`][api-processor-options] to\n  `'svelte-jsx'`\n* if you use **Vue**,\n  set [`jsxImportSource` in `ProcessorOptions`][api-processor-options] to\n  `'vue'`;\n  optionally install and configure [`@mdx-js/vue`][mdx-vue]\n* if you use **Solid**,\n  set [`jsxImportSource` in `ProcessorOptions`][api-processor-options] to\n  `'solid-js/h'`\n* if you use **Emotion**,\n  set [`jsxImportSource` in `ProcessorOptions`][api-processor-options] to\n  `'@emotion/react'`\n* if you use **Theme UI**,\n  install and configure [`@mdx-js/react`][mdx-react],\n  then wrap your MDX content in a `<ThemeProvider />`\n\nOther JSX runtimes are supported by setting\n[`jsxImportSource` in `ProcessorOptions`][api-processor-options].\n\nFor more info on these tools,\nsee their dedicated sections:\n[¶ Emotion][jsx-runtime-emotion],\n[¶ Preact][jsx-runtime-preact],\n[¶ React][jsx-runtime-react],\n[¶ Solid][jsx-runtime-solid],\n[¶ Svelte][jsx-runtime-svelte],\n[¶ Theme UI][jsx-runtime-theme-ui], and\n[¶ Vue][jsx-runtime-vue].\n\n### Editor\n\nYou can enhance the experience of using MDX by adding support of it to your\neditor:\n\n* if you use **VS Code**,\n  try [`mdx-js/mdx-analyzer`][mdx-analyzer]\n* if you use **Vim**,\n  try [`jxnblk/vim-mdx-js`][vim-mdx-js]\n* if you use **Sublime Text**,\n  try [`jonsuh/mdx-sublime`][mdx-sublime]\n* if you use **JetBrains IntelliJ/WebStorm**,\n  try [`JetBrains/mdx-intellij-plugin`][mdx-intellij-plugin]\n\nThe syntax highlighting that powers our VS Code extension and that is used\nto highlight code blocks on GitHub is maintained at\n[`wooorm/markdown-tm-language`][markdown-tm-language].\n\n### Types\n\n<details>\n  <summary>Expand example of typed imports</summary>\n\n  First install the package:\n\n  ```sh\n  npm install @types/mdx\n  ```\n\n  …TypeScript should automatically pick it up:\n\n  ```js twoslash path=\"example.js\"\n  // @filename: types.d.ts\n  import type {} from 'mdx'\n  // @filename: example.js\n  // ---cut---\n  import Post from './post.mdx' // `Post` is now typed.\n  ```\n</details>\n\nOur packages are typed with [TypeScript][].\nFor types to work,\nthe `JSX` namespace must be typed.\nThis is done by installing and using the types of your framework,\nsuch as [`@types/react`][definitely-typed-react],\nthen augmenting the `mdx/types.js` module.\n\n```ts twoslash path=\"example.ts\"\nimport * as React from 'react'\n\ndeclare module 'mdx/types.js' {\n  export import JSX = React.JSX\n}\n```\n\nTo enable types for imported `.mdx`, `.md`, etc.,\ninstall and use [`@types/mdx`][definitely-typed-mdx].\nThis package also exports several useful types,\nsuch as `MDXComponents` which represents the `components` prop.\nYou can import them like so:\n\n```ts twoslash path=\"example.ts\"\nimport type {MDXComponents} from 'mdx/types.js'\n```\n\n### Security\n\nMDX is a programming language.\nIf you trust your authors,\nthat’s fine.\nIf you don’t,\nit’s unsafe.\n\nDo not let random people from the internet write MDX.\nIf you do,\nyou might want to look into using `<iframe>`s with `sandbox`,\nbut security is hard,\nand that doesn’t seem to be 100%.\nFor Node.js,\n[vm2][] sounds interesting.\nBut you should probably also sandbox the whole OS using Docker or similar,\nperform rate limiting,\nand make sure processes can be killed when taking too long.\n\n## Integrations\n\n### Bundlers\n\n#### esbuild\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"example.js\"\n  import mdx from '@mdx-js/esbuild'\n  import esbuild from 'esbuild'\n\n  await esbuild.build({\n    entryPoints: ['index.mdx'],\n    format: 'esm',\n    outfile: 'output.js',\n    plugins: [mdx({/* jsxImportSource: …, otherOptions… */})]\n  })\n  ```\n</details>\n\nWe support [esbuild][].\nInstall and configure the esbuild plugin [`@mdx-js/esbuild`][mdx-esbuild].\n[Configure your JSX runtime][jsx] depending on which one (React, Preact, Vue,\netc.) you use.\n\nTo use more modern JavaScript features than what your users support,\n[configure esbuild’s `target`][esbuild-target].\n\nSee also [¶ Bun][javascript-engines-bun],\nwhich you might be using,\nfor more info.\n\n#### Rollup\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"rollup.config.js\"\n  /**\n   * @import {RollupOptions} from 'rollup'\n   */\n\n  import mdx from '@mdx-js/rollup'\n  import {babel} from '@rollup/plugin-babel'\n\n  /** @type {RollupOptions} */\n  const config = {\n    // …\n    plugins: [\n      // …\n      mdx({/* jsxImportSource: …, otherOptions… */}),\n      // Babel is optional:\n      babel({\n        // Also run on what used to be `.mdx` (but is now JS):\n        extensions: ['.js', '.jsx', '.cjs', '.mjs', '.md', '.mdx'],\n        // Other options…\n      })\n    ]\n  }\n\n  export default config\n  ```\n</details>\n\nWe support [Rollup][].\nInstall and configure the Rollup plugin [`@mdx-js/rollup`][mdx-rollup].\n[Configure your JSX runtime][jsx] depending on which one (React, Preact, Vue,\netc.) you use.\n\nTo use more modern JavaScript features than what your users support,\n[install and configure `@rollup/plugin-babel`][mdx-rollup-babel].\n\nSee also [¶ Vite][build-system-vite],\nif you use Rollup through it,\nfor more info.\n\n#### Webpack\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"webpack.config.js\"\n  /**\n   * @import {Options} from '@mdx-js/loader'\n   * @import {Configuration} from 'webpack'\n   */\n\n  /** @type {Configuration} */\n  const webpackConfig = {\n    module: {\n      // …\n      rules: [\n        // …\n        {\n          test: /\\.mdx?$/,\n          use: [\n            // Babel is optional:\n            {loader: 'babel-loader', options: {}},\n            {\n              loader: '@mdx-js/loader',\n              /** @type {Options} */\n              options: {/* jsxImportSource: …, otherOptions… */}\n            }\n          ]\n        }\n      ]\n    }\n  }\n\n  export default webpackConfig\n  ```\n</details>\n\nWe support [webpack][].\nInstall and configure the webpack loader [`@mdx-js/loader`][mdx-loader].\n[Configure your JSX runtime][jsx] depending on which one (React, Preact, Vue,\netc.) you use.\n\nTo use more modern JavaScript features than what your users support,\n[install and configure `babel-loader`][mdx-loader-babel].\n\nSee also [¶ Next.js][site-generator-next],\nif you use webpack through it,\nfor more info.\n\n### Build systems\n\n#### Vite\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"vite.config.js\"\n  import mdx from '@mdx-js/rollup'\n  import {defineConfig} from 'vite'\n\n  const viteConfig = defineConfig({\n    plugins: [\n      mdx(/* jsxImportSource: …, otherOptions… */)\n    ]\n  })\n\n  export default viteConfig\n  ```\n</details>\n\nWe support [Vite][].\nInstall and configure the Rollup plugin [`@mdx-js/rollup`][mdx-rollup].\n[Configure your JSX runtime][jsx] depending on which one (React, Preact, Vue,\netc.) you use.\n\nTo use more modern JavaScript features than what your users support,\n[configure Vite’s `build.target`][vite-build-target].\n\n<Note type=\"info\">\n  **Note**: If you also use `@vitejs/plugin-react`,\n  you must force `@mdx-js/rollup` to run in the `pre` phase before it:\n\n  ```js twoslash path=\"vite.config.js\"\n  import mdx from '@mdx-js/rollup'\n  import react from '@vitejs/plugin-react'\n  import {defineConfig} from 'vite'\n  // ---cut---\n  // …\n  const viteConfig = defineConfig({\n    plugins: [\n      {enforce: 'pre', ...mdx({/* jsxImportSource: …, otherOptions… */})},\n      react({include: /\\.(jsx|js|mdx|md|tsx|ts)$/})\n    ]\n  })\n  // …\n  ```\n</Note>\n\nSee also [¶ Rollup][bundler-rollup] which is used in Vite and see\n[¶ Vue][jsx-runtime-vue] if you’re using that,\nfor more info.\n\n### Linters\n\n#### ESLint\n\nYou can lint your MDX code with [ESLint][] using [`eslint-mdx`][eslint-mdx].\n\n#### mdxlint\n\nYou can lint your MDX code with [`remark-lint`][remark-lint] and other\n[remark plugins][] using [`mdxlint`][mdxlint].\n\n### Compilers\n\n#### Babel\n\n<details>\n  <summary>Expand plugin and sample use</summary>\n\n  This plugin:\n\n  ```js twoslash path=\"plugin.js\"\n  /**\n   * @import {ParseResult, ParserOptions} from '@babel/parser'\n   * @import {File} from '@babel/types'\n   * @import {Program} from 'estree'\n   * @import {Plugin} from 'unified'\n   */\n\n  import parser from '@babel/parser'\n  import {compileSync} from '@mdx-js/mdx'\n  import estreeToBabel from 'estree-to-babel'\n\n  /**\n   * Plugin that tells Babel to use a different parser.\n   */\n  export function babelPluginSyntaxMdx() {\n    return {parserOverride: babelParserWithMdx}\n  }\n\n  /**\n   * Parser that handles MDX with `@mdx-js/mdx` and passes other things through\n   * to the normal Babel parser.\n   *\n   * @param {string} value\n   * @param {ParserOptions} options\n   * @returns {ParseResult<File>}\n   */\n  function babelParserWithMdx(value, options) {\n    /** @type {string | undefined} */\n    // @ts-expect-error: babel changed the casing at some point and the types are out of date.\n    const filename = options.sourceFilename || options.sourceFileName\n\n    if (filename && /\\.mdx?$/.test(filename)) {\n      // Babel does not support async parsers, unfortunately.\n      const file = compileSync(\n        {value, path: options.sourceFilename},\n        {recmaPlugins: [recmaBabel] /* jsxImportSource: …, otherOptions… */}\n      )\n      return /** @type {ParseResult<File>} */ (file.result)\n    }\n\n    return parser.parse(value, options)\n  }\n\n  /**\n   * A “recma” plugin is a unified plugin that runs on the estree (used by\n   * `@mdx-js/mdx` and much of the JS ecosystem but not Babel).\n   * This plugin defines `'estree-to-babel'` as the compiler,\n   * which means that the resulting Babel tree is given back by `compileSync`.\n   *\n   * @type {Plugin<[], Program, unknown>}\n   */\n  function recmaBabel() {\n    // @ts-expect-error: `Program` is similar enough to a unist node.\n    this.compiler = compiler\n\n    /**\n     * @param {Program} tree\n     * @returns {unknown}\n     */\n    function compiler(tree) {\n      // @ts-expect-error: TS2349: This expression *is* callable, `estreeToBabel` types are wrong.\n      return estreeToBabel(tree)\n    }\n  }\n  ```\n\n  …can be used like so with the Babel API:\n\n  ```js twoslash path=\"example.js\"\n  /// <reference types=\"node\" />\n  // ---cut---\n  // @filename: plugin.js\n  /**\n   * @import {ParseResult, ParserOptions} from '@babel/parser'\n   * @import {File} from '@babel/types'\n   * @import {Program} from 'estree'\n   * @import {Plugin} from 'unified'\n   */\n\n  import parser from '@babel/parser'\n  import {compileSync} from '@mdx-js/mdx'\n  import estreeToBabel from 'estree-to-babel'\n\n  /**\n   * Plugin that tells Babel to use a different parser.\n   */\n  export function babelPluginSyntaxMdx() {\n    return {parserOverride: babelParserWithMdx}\n  }\n\n  /**\n   * Parser that handles MDX with `@mdx-js/mdx` and passes other things through\n   * to the normal Babel parser.\n   *\n   * @param {string} value\n   * @param {ParserOptions} options\n   * @returns {ParseResult<File>}\n   */\n  function babelParserWithMdx(value, options) {\n    /** @type {string | undefined} */\n    // @ts-expect-error: babel types are wrong.\n    const filename = options.sourceFilename || options.sourceFileName\n\n    if (filename && /\\.mdx?$/.test(filename)) {\n      // Babel does not support async parsers, unfortunately.\n      const file = compileSync(\n        {value, path: options.sourceFilename},\n        {recmaPlugins: [recmaBabel] /* jsxImportSource: …, otherOptions… */}\n      )\n      return /** @type {ParseResult<File>} */ (file.result)\n    }\n\n    return parser.parse(value, options)\n  }\n\n  /**\n   * A “recma” plugin is a unified plugin that runs on the estree (used by\n   * `@mdx-js/mdx` and much of the JS ecosystem but not Babel).\n   * This plugin defines `'estree-to-babel'` as the compiler,\n   * which means that the resulting Babel tree is given back by `compileSync`.\n   *\n   * @type {Plugin<[], Program, unknown>}\n   */\n  function recmaBabel() {\n    // @ts-expect-error: `Program` is similar enough to a unist node.\n    this.compiler = compiler\n\n    /**\n     * @param {Program} tree\n     * @returns {unknown}\n     */\n    function compiler(tree) {\n      // @ts-expect-error: TS2349: This expression *is* callable, `estreeToBabel` types are wrong.\n      return estreeToBabel(tree)\n    }\n  }\n  // @filename: example.js\n  // ---cut---\n  import babel from '@babel/core'\n  import {babelPluginSyntaxMdx} from './plugin.js'\n\n  const document = '# Hello, world!'\n\n  // Note that a filename must be set for our plugin to know it’s MDX instead of JS.\n  const result = await babel.transformAsync(document, {\n    filename: 'example.mdx',\n    plugins: [babelPluginSyntaxMdx]\n  })\n\n  console.log(result)\n  ```\n</details>\n\nYou should probably use Rollup or webpack instead of Babel directly as that\ngives the best interface.\nIt is possible to use `@mdx-js/mdx` in Babel and it’s a bit faster, as it skips\n`@mdx-js/mdx` serialization and Babel parsing, if Babel is used anyway.\n\nBabel does not support syntax extensions to its parser (it has “syntax” plugins\nbut those only turn internal flags on or off).\nIt does support setting a different parser.\nWhich in turn lets us choose whether to use the `@mdx-js/mdx` or\n`@babel/parser`.\n\n### Site generators\n\n#### Astro\n\n[Astro][] has its own MDX integration.\nYou can add the integration with the Astro CLI: `npx astro add mdx`.\n\nThis base setup lets you import markdown, Astro components, and MDX files as\ncomponents.\nSee Astro’s [Framework components guide][astro-framework-components] for info\non how to use components from frameworks in your MDX files.\n\nFor more on how to combine Astro and MDX,\nsee [Astro’s MDX integration docs][astro-mdx].\n\n#### Docusaurus\n\n[Docusaurus][] supports MDX by default.\nSee [Docusaurus’ MDX and React guide][docusaurus-markdown-react] for info on\nhow to use MDX with Docusaurus.\n\n#### Gatsby\n\n[Gatsby][] has its own plugin to support MDX.\nSee [`gatsby-plugin-mdx`][gatsby-plugin-mdx] on how to use MDX with Gatsby.\n\n#### Next.js\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"next.config.js\"\n  import nextMdx from '@next/mdx'\n\n  const withMdx = nextMdx({\n    // By default only the `.mdx` extension is supported.\n    extension: /\\.mdx?$/,\n    options: {/* otherOptions… */}\n  })\n\n  const nextConfig = withMdx({\n    // Support MDX files as pages:\n    pageExtensions: ['md', 'mdx', 'tsx', 'ts', 'jsx', 'js'],\n  })\n\n  export default nextConfig\n  ```\n</details>\n\n[Next.js][next] has its own MDX integration.\nInstall and configure [`@next/mdx`][next-mdx].\n\nDo not use `providerImportSource` and `@mdx-js/react` with Next to inject\ncomponents.\nAdd an `mdx-components.tsx` (in `src/` or `/`) file instead.\nSee [Configuring MDX on `nextjs.org`][next-configuring-mdx] for more info.\n\n#### Parcel\n\n[Parcel][] has its own plugin to support MDX.\nSee [`@parcel/transformer-mdx`][parcel-mdx]\non how to use MDX with Parcel.\n\n<Note type=\"info\">\n  **Note**: the official Parcel plugin is currently not maintained.\n  For a maintained alternative,\n  try [`parcel-transformer-mdx`][parcel-transformer-mdx].\n</Note>\n\n### JSX runtimes\n\n#### Emotion\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"example.js\"\n  import {compile} from '@mdx-js/mdx'\n\n  const js = String(await compile('# hi', {jsxImportSource: '@emotion/react', /* otherOptions… */}))\n  ```\n</details>\n\n[Emotion][] is supported when\n[`jsxImportSource` in `ProcessorOptions`][api-processor-options] is set to\n`'@emotion/react'`.\nYou can optionally install and configure [`@mdx-js/react`][mdx-react] to\nsupport context based component passing.\n\nSee also [¶ React][jsx-runtime-react],\nwhich is used in Emotion,\nand see [¶ Rollup][bundler-rollup] and [¶ webpack][bundler-webpack],\nwhich you might be using,\nfor more info.\n\n#### Ink\n\n<details>\n  <summary>Expand example</summary>\n\n  ```mdx path=\"example.mdx\"\n  # Hi!\n  ```\n\n  ```js twoslash path=\"example.js\"\n  // @filename: types.d.ts\n  import type {} from 'mdx'\n  // @filename: example.js\n  // @errors: 2769 -- something with Ink/twoslash/react getting different versions of React?\n  // ---cut---\n  import React from 'react'\n  import {Text, render} from 'ink'\n  import Content from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\n  render(\n    React.createElement(Content, {\n      components: {\n        h1(properties) {\n          return React.createElement(Text, {bold: true, ...properties})\n        },\n        p: Text\n      }\n    })\n  )\n  ```\n\n  Can be used with:\n\n  ```sh\n  node --loader=@mdx-js/node-loader example.js\n  ```\n</details>\n\n[Ink][] uses the React JSX runtime,\nso set that up.\nYou will need to swap HTML elements out for Ink’s components.\nSee [§ Table of components][table-of-components] for what those are and Ink’s\ndocs on what they can be replaced with.\n\nSee also [¶ Node.js][js-engine-node] and [¶ React][jsx-runtime-react] for more\ninfo.\n\n#### Preact\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"example.js\"\n  import {compile} from '@mdx-js/mdx'\n\n  const js = String(await compile('# hi', {jsxImportSource: 'preact', /* otherOptions… */}))\n  ```\n</details>\n\nPreact is supported when [`jsxImportSource` in\n`ProcessorOptions`][api-processor-options] is set to `'preact'`.\nYou can optionally install and configure [`@mdx-js/preact`][mdx-preact] to\nsupport context based component passing.\n\nSee also [¶ Rollup][bundler-rollup], [¶ esbuild][bundler-esbuild], and\n[¶ webpack][bundler-webpack],\nwhich you might be using,\nfor more info.\n\n#### React\n\nReact is supported by default.\nYou can optionally install and configure [`@mdx-js/react`][mdx-react] to\nsupport context based component passing.\n\nSee also [¶ Rollup][bundler-rollup], [¶ esbuild][bundler-esbuild], and\n[¶ webpack][bundler-webpack],\nwhich you might be using,\nfor more info.\n\n#### Theme UI\n\n[Theme UI][theme-ui] has its own plugin to support MDX.\nSee [`@theme-ui/mdx`][theme-ui-mdx] on how to use MDX with Theme UI.\n\n#### Svelte\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"example.js\"\n  import {compile} from '@mdx-js/mdx'\n\n  const js = String(await compile('# hi', {jsxImportSource: 'svelte-jsx', /* otherOptions… */}))\n  ```\n</details>\n\nSvelte is supported when [`jsxImportSource` in\n`ProcessorOptions`][api-processor-options] is set to\n[`'svelte-jsx'`][svelte-jsx].\n\nSee also [¶ Rollup][bundler-rollup], [¶ esbuild][bundler-esbuild], and\n[¶ webpack][bundler-webpack],\nwhich you might be using,\nfor more info.\n\n#### Vue\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"example.js\"\n  import {compile} from '@mdx-js/mdx'\n\n  const js = String(await compile('# hi', {jsxImportSource: 'vue', /* otherOptions… */}))\n  ```\n</details>\n\nVue is supported when [`jsxImportSource` in\n`ProcessorOptions`][api-processor-options] is set to `'vue'`.\nYou can optionally install and configure [`@mdx-js/vue`][mdx-vue] to\nsupport context based component passing.\n\nSee also [¶ Vite][build-system-vite],\nwhich you might be using,\nfor more info.\n\n#### Solid\n\n<details>\n  <summary>Expand example</summary>\n\n  ```js twoslash path=\"example.js\"\n  import {compile} from '@mdx-js/mdx'\n\n  const js = String(await compile('# hi', {jsxImportSource: 'solid-js/h', /* otherOptions… */}))\n  ```\n</details>\n\nSolid is supported when [`jsxImportSource` in\n`ProcessorOptions`][api-processor-options] is set to `'solid-js/h'`.\n\nSee also [¶ Rollup][bundler-rollup] and [¶ Vite][build-system-vite],\nwhich you might be using,\nfor more info.\n\n### JavaScript engines\n\n#### Node.js\n\nMDX files can be imported in Node by using\n[`@mdx-js/node-loader`][mdx-node-loader].\nSee its readme on how to configure it.\n\n#### Bun\n\nMDX files can be imported in [Bun][] by using\n[`@mdx-js/esbuild`][mdx-esbuild].\n\n<details>\n  <summary>Expand example</summary>\n\n  ```toml path=\"bunfig.toml\"\n  preload = [\"./bun-mdx.ts\"]\n  ```\n\n  ```ts twoslash path=\"bun-mdx.ts\"\n  /// <reference types=\"bun-types\" />\n  // ---cut---\n  import mdx from '@mdx-js/esbuild'\n  import {type BunPlugin, plugin} from 'bun'\n\n  await plugin(mdx() as unknown as BunPlugin)\n  ```\n</details>\n\n## Further reading\n\n* If you want to use MDX content in your project,\n  see [§ Using MDX][use]\n* If you’re getting errors integrating MDX,\n  see [§ Troubleshooting MDX][trouble] or [§ Support][support]\n\n[api-evaluate]: /packages/mdx/#evaluatefile-options\n\n[api-processor-options]: /packages/mdx/#processoroptions\n\n[astro]: https://astro.build/\n\n[astro-framework-components]: https://docs.astro.build/en/core-concepts/framework-components/\n\n[astro-mdx]: https://docs.astro.build/en/guides/integrations-guide/mdx/\n\n[build-system-vite]: #vite\n\n[bun]: https://bun.sh\n\n[bundler-esbuild]: #esbuild\n\n[bundler-rollup]: #rollup\n\n[bundler-webpack]: #webpack\n\n[definitely-typed-mdx]: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/mdx\n\n[definitely-typed-react]: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react\n\n[docusaurus]: https://docusaurus.io\n\n[docusaurus-markdown-react]: https://docusaurus.io/docs/next/markdown-features/react\n\n[emotion]: https://emotion.sh/docs/introduction\n\n[esbuild]: https://esbuild.github.io\n\n[esbuild-target]: https://esbuild.github.io/api/#target\n\n[eslint]: https://eslint.org\n\n[eslint-mdx]: https://github.com/mdx-js/eslint-mdx\n\n[gatsby]: https://www.gatsbyjs.com\n\n[gatsby-plugin-mdx]: https://www.gatsbyjs.com/plugins/gatsby-plugin-mdx/\n\n[github-gist-esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[ink]: https://github.com/vadimdemedes/ink\n\n[javascript-engines-bun]: #bun\n\n[js-engine-node]: #nodejs\n\n[jsx]: #jsx\n\n[jsx-runtime-emotion]: #emotion\n\n[jsx-runtime-preact]: #preact\n\n[jsx-runtime-react]: #react\n\n[jsx-runtime-solid]: #solid\n\n[jsx-runtime-svelte]: #svelte\n\n[jsx-runtime-theme-ui]: #theme-ui\n\n[jsx-runtime-vue]: #vue\n\n[markdown-tm-language]: https://github.com/wooorm/markdown-tm-language\n\n[mdx-analyzer]: https://github.com/mdx-js/mdx-analyzer\n\n[mdx-esbuild]: /packages/esbuild/\n\n[mdx-intellij-plugin]: https://github.com/JetBrains/intellij-plugins/tree/master/mdx\n\n[mdx-loader]: /packages/loader/\n\n[mdx-loader-babel]: /packages/loader/#combine-with-babel\n\n[mdx-mdx]: /packages/mdx/\n\n[mdx-node-loader]: /packages/node-loader/\n\n[mdx-preact]: /packages/preact/\n\n[mdx-react]: /packages/react/\n\n[mdx-rollup]: /packages/rollup/\n\n[mdx-rollup-babel]: /packages/rollup/#combine-with-babel\n\n[mdx-sublime]: https://github.com/jonsuh/mdx-sublime\n\n[mdx-vue]: /packages/vue/\n\n[mdxjs-rs]: https://github.com/wooorm/mdxjs-rs\n\n[mdxlint]: https://github.com/remcohaszing/mdxlint\n\n[next]: https://nextjs.org\n\n[next-configuring-mdx]: https://nextjs.org/docs/pages/building-your-application/configuring/mdx\n\n[next-mdx]: https://github.com/vercel/next.js/tree/canary/packages/next-mdx\n\n[node-js]: https://nodejs.org\n\n[parcel]: https://parceljs.org\n\n[parcel-mdx]: https://parceljs.org/languages/mdx/\n\n[parcel-transformer-mdx]: https://github.com/EasyWebApp/Parcel-transformer-MDX\n\n[remark plugins]: https://github.com/remarkjs/remark/blob/main/doc/plugins.md\n\n[remark-lint]: https://github.com/remarkjs/remark-lint\n\n[rollup]: https://rollupjs.org\n\n[site-generator-next]: #nextjs\n\n[support]: /community/support/\n\n[svelte-jsx]: https://github.com/kenoxa/svelte-jsx\n\n[table-of-components]: /table-of-components/\n\n[theme-ui]: https://theme-ui.com\n\n[theme-ui-mdx]: https://theme-ui.com/mdx\n\n[trouble]: /docs/troubleshooting-mdx/\n\n[typescript]: https://www.typescriptlang.org\n\n[use]: /docs/using-mdx/\n\n[vim-mdx-js]: https://github.com/jxnblk/vim-mdx-js\n\n[vite]: https://vitejs.dev\n\n[vite-build-target]: https://vitejs.dev/guide/build.html#browser-compatibility\n\n[vm2]: https://github.com/patriksimek/vm2\n\n[webpack]: https://webpack.js.org\n\n[what]: /docs/what-is-mdx/\n"
  },
  {
    "path": "docs/docs/index.mdx",
    "content": "{\n  /**\n   * @import {Item} from '../_component/sort.js'\n   */\n\n  /**\n   * @typedef Props\n   * @property {Item} navigationTree\n   */\n}\n\nimport assert from 'node:assert/strict'\nimport {NavigationGroup} from '../_component/nav.jsx'\n\nexport const info = {\n  author: [{name: 'MDX Contributors'}],\n  modified: new Date('2024-07-04'),\n  published: new Date('2021-11-01')\n}\nexport const navSortSelf = 1\n\n# Docs\n\nThese docs explain the core concepts of MDX.\nHow the format works, how to add it to your site, how to use MDX files, and how\nto extend them.\nReading through these should give you a good understanding of MDX.\n\n{\n  (function () {\n    const navigationTree = props.navigationTree\n    const category = navigationTree.children.find(function (item) {\n      return item.name === '/docs/'\n    })\n    assert(category)\n\n    return (\n      <nav>\n        <NavigationGroup items={category.children} includeDescription />\n      </nav>\n    )\n  })()\n}\n"
  },
  {
    "path": "docs/docs/troubleshooting-mdx.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-18')\n}\nexport const navSortSelf = 5\n\n{/* lint disable maximum-heading-length */}\n\n<Note type=\"info\">\n  **Note**: Had trouble with something that wasn’t explained here but should be?\n  Please let us know.\n  See [§ Contribute][contribute] for how to help.\n</Note>\n\n# Troubleshooting MDX\n\nThis article goes through several common problems and errors that might occur\nwhen using MDX. {/* more */}\nTo understand how the MDX format works, we recommend that you start with\n[§ What is MDX][what].\nHow to use [our packages][packages] is documented in their readmes.\nTo migrate to the latest MDX, see [§ Migrating from v1 to v2][migation-v2].\n\n## Contents\n\n* [Problems integrating MDX](#problems-integrating-mdx)\n  * [ESM](#esm)\n* [Problems using MDX](#problems-using-mdx)\n  * [`` `options.renderer` is no longer supported ``](#optionsrenderer-is-no-longer-supported)\n  * [`` Incorrect `format: 'detect'` ``](#incorrect-format-detect)\n  * [`` Unexpected `format: 'detect'` ``](#unexpected-format-detect)\n  * [`` Missing `pragma` in classic runtime with `pragmaImportSource` ``](#missing-pragma-in-classic-runtime-with-pragmaimportsource)\n  * [`` Unexpected deprecated option `jsxRuntime: 'classic'`, `pragma`, `pragmaFrag`, or `pragmaImportSource` ``](#unexpected-deprecated-option-jsxruntime-classic-pragma-pragmafrag-or-pragmaimportsource)\n  * [`` Expected `Fragment` given to `evaluate` ``](#expected-fragment-given-to-evaluate)\n  * [`` Expected `jsx` given to `evaluate` ``](#expected-jsx-given-to-evaluate)\n  * [`` Expected `jsxs` given to `evaluate` ``](#expected-jsxs-given-to-evaluate)\n  * [``Unexpected missing `options.baseUrl` needed…``](#unexpected-missing-optionsbaseurl-needed)\n* [Problems writing MDX](#problems-writing-mdx)\n  * [`Could not parse import/exports with acorn: $error`](#could-not-parse-importexports-with-acorn-error)\n  * [``Unexpected `$type` in code: only import/exports are supported``](#unexpected-type-in-code-only-importexports-are-supported)\n  * [`` Unexpected end of file in expression, expected a corresponding closing brace for `{` ``](#unexpected-end-of-file-in-expression-expected-a-corresponding-closing-brace-for-)\n  * [`Unexpected lazy line in expression in container`](#unexpected-lazy-line-in-expression-in-container)\n  * [`Could not parse expression with acorn: $error`](#could-not-parse-expression-with-acorn-error)\n  * [`Could not parse expression with acorn: Unexpected content after expression`](#could-not-parse-expression-with-acorn-unexpected-content-after-expression)\n  * [`Unexpected extra content in spread: only a single spread is supported`](#unexpected-extra-content-in-spread-only-a-single-spread-is-supported)\n  * [``Unexpected `$type` in code: only spread elements are supported``](#unexpected-type-in-code-only-spread-elements-are-supported)\n  * [`Unexpected empty expression`](#unexpected-empty-expression)\n  * [`Unexpected end of file $at, expected $expect`](#unexpected-end-of-file-at-expected-expect)\n  * [`Unexpected character $at, expected $expect`](#unexpected-character-at-expected-expect)\n  * [``Unexpected closing slash `/` in tag, expected an open tag first``](#unexpected-closing-slash--in-tag-expected-an-open-tag-first)\n  * [`Unexpected lazy line in container, expected line to be…`](#unexpected-lazy-line-in-container-expected-line-to-be)\n  * [`Unexpected attribute in closing tag, expected the end of the tag`](#unexpected-attribute-in-closing-tag-expected-the-end-of-the-tag)\n  * [``Unexpected self-closing slash `/` in closing tag, expected the end of the tag``](#unexpected-self-closing-slash--in-closing-tag-expected-the-end-of-the-tag)\n  * [``Unexpected closing tag `</$tag>`, expected corresponding closing tag for `<$tag>` ($at)``](#unexpected-closing-tag-tag-expected-corresponding-closing-tag-for-tag-at)\n  * [``Cannot close `$type` ($at): a different token (`$type`, $at) is open``](#cannot-close-type-at-a-different-token-type-at-is-open)\n  * [``Cannot close document, a token (`$type`, $at) is still open``](#cannot-close-document-a-token-type-at-is-still-open)\n\n## Problems integrating MDX\n\n### ESM\n\nIf you’re having problems integrating MDX with different tools, that’s likely\ndue to ESM: ECMAScript modules.\nThey’ve been in the works since 2015, we’ve supported them in MDX files from the\nstart, and in MDX version 2 we completely switched to them.\nMany tools support ESM already.\nMost other tools are working hard to support them.\nSome still require extra configuration.\n\nThere’s a great [Gist by\n**@sindresorhus**](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c)\nwhich explains in detail how to use ESM with many different tools.\nIf you’re having trouble with MDX, some other tool, and ESM,\nyou’ll likely find what you’re looking for there.\nPlease give it a thorough read.\nIf you’re still having problems, the issue tracker of the tools you’re\nintegrating MDX with might provide the answer.\n\nIf you’re having trouble with tools that don’t support ESM, such as Electron,\none short-term solution is to use a bundler to make a CJS version.\n\n<details>\n  <summary>Expand example of making a CJS bundle</summary>\n\n  With [esbuild](https://esbuild.github.io), this bundles the ESM package\n  `@mdx-js/mdx` as CJS in `vendor/mdx.js`:\n\n  ```sh\n  npx esbuild @mdx-js/mdx --bundle --platform=node --outfile=vendor/mdx.js\n  ```\n</details>\n\n## Problems using MDX\n\nProblems that occur when using MDX typically relate to the APIs of\n[our packages][packages] and how to use them.\nPlease see the documentation of the packages, functions, and options you are\nusing for more info and examples.\n\n### `` `options.renderer` is no longer supported ``\n\nThis error is thrown by [`@mdx-js/loader`][loader],\nour webpack loader.\nIt was introduced in version 2 to help with migration.\n\nThe `renderer` option allowed arbitrary text to be injected before each compiled\nMDX file.\nThis was typically used to support frameworks other than React such as Preact.\nWe now have options such as `jsxImportSource` for that and arbitrary JavaScript\ncan be added with `recmaPlugins`.\nBecause version 2 uses an AST based approach, it is no longer feasible to\nsupport a `renderer`, so it was removed.\n\nPlease see [¶ Preact in § Getting started](/docs/getting-started/#preact) for\nhow to support Preact.\nSee [¶ Creating plugins in § Extending MDX](/docs/extending-mdx/#creating-plugins)\nfor how to create plugins.\n\n### `` Incorrect `format: 'detect'` ``\n\n### `` Unexpected `format: 'detect'` ``\n\nThe full error message in MDX 2 is as follows:\n\n```mdx-invalid chrome=no\nIncorrect `format: 'detect'`: `createProcessor` can support either `md` or `mdx`; it does not support detecting the format\n```\n\nThe full error message in MDX 3 is:\n\n```mdx-invalid chrome=no\nUnexpected `format: 'detect'`, which is not supported by `createProcessor`, expected `'mdx'` or `'md'`\n```\n\nThis error is thrown by [`@mdx-js/mdx`][mdx], our core compiler.\nIt was introduced in version 2 when the `format` option was introduced.\n\nThe `format` option, when configured with `'detect'`, allows inferring whether a\nfile is MDX or plain markdown.\nBased on that information, plugins are configured differently, and with\ndifferent options.\nThis is impossible with `createProcessor` and `unified`.\n\nTo detect the format of passed files, please either use `compile` from\n`@mdx-js/mdx` or one of the integrations.\n\n### `` Missing `pragma` in classic runtime with `pragmaImportSource` ``\n\nThis error is thrown by [`@mdx-js/mdx`][mdx], our core compiler.\nIt was introduced in version 2 when the `jsxRuntime`, `pragma`, and\n`pragmaImportSource` options were introduced.\n\nThis error is thrown when `jsxRuntime` is configured with `'classic'` (the\ndefault is `'automatic'`), `pragmaImportSource` is defined (the default is\n`'react'`), but `pragma` is defined as a falsey value (the default is\n`React.createElement`).\n\nIf you are using the classic runtime, you have to define a `pragma`.\n\n### `` Unexpected deprecated option `jsxRuntime: 'classic'`, `pragma`, `pragmaFrag`, or `pragmaImportSource` ``\n\nThis is a warning.\nIt is not an error.\nYou can keep on using these options, but expect them to be removed in the\nfuture.\n\nAll major frameworks currently support the automatic JSX runtime.\nThe classic runtime, from MDX perspective, comes with several potential\nproblems.\n\nBecause of that, we strongly recommend using an automatic JSX runtime and are\nconsidering removing support for the classic JSX runtime.\n\n### `` Expected `Fragment` given to `evaluate` ``\n\n### `` Expected `jsx` given to `evaluate` ``\n\n### `` Expected `jsxs` given to `evaluate` ``\n\nThese errors are thrown by [`@mdx-js/mdx`][loader],\nour core compiler.\nThey were introduced in version 2 when `evaluate` (and `evaluateSync`) were\nintroduced.\n\n`evaluate` supports React and other frameworks.\nBut these frameworks must support an automatic JSX runtime that exposes these\nthree exports.\nIf you’re getting this error, that means that either a) the framework does not\nsupport the automatic JSX runtime, or b) that you’re not passing them correctly\nto `evaluate`.\n\nPlease see [`evaluate` in `@mdx-js/mdx`](/packages/mdx/#evaluatefile-options)\nfor examples on how to pass these values.\n\n### ``Unexpected missing `options.baseUrl` needed…``\n\nThe full error message in MDX is as follows:\n\n```mdx-invalid chrome=no\nUnexpected missing `options.baseUrl` needed to support `export … from`, `import`, or `import.meta.url` when generating `function-body`\n```\n\nThis error is thrown when MDX runs that is specifically compiled with\n`evaluate`, or with the `outputFormat: 'function-body'` option to evluate\nsomewhere later, and `import.meta.url`, `import`, or `export … from` is used.\nThese JavaScript features depend on a particular URL to run from, which is not\navailable or not correct when running a function body.\nTo solve this, pass a `baseUrl` option.\nLikely set to `import.meta.url` (or `window.location.href`).\n\n## Problems writing MDX\n\nProblems that occur when writing MDX typically have relate to how to combine\nJS(X) and markdown.\nIt’s an odd mix of two languages: markdown is **whitespace sensitive** and\n**forgiving** (what you type may not exactly work but it won’t crash) whereas\nJavaScript is **whitespace insensitive** and **unforgiving** (it does crash on\ntypos).\n\nErrors typically fall in these three categories:\n\n* **Not escaping `<` and `{`**\n  — Escape these (`\\<`, `\\{`) if you mean them as plain text instead of JS(X)\n* **Incorrect interleaving**\n  — See the rules in\n  [¶ Interleaving in § What is MDX?][interleaving]\n* **Broken JavaScript**\n  — Make sure the JavaScript you write is valid\n\n### `Could not parse import/exports with acorn: $error`\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when the keywords `import` or `export` are found at the start of a\nline but they are not followed by valid JavaScript.\nAn example is:\n\n```mdx-invalid chrome=no\nimport 1/1\n```\n\nThe reason for this error is that the parser is expecting a JavaScript import or\nexport statement.\nIf you want the word import or export, make sure it’s not at the start of a\nparagraph.\nIf you do want an import or export statement, please make sure that it’s valid\nJavaScript.\n\n### ``Unexpected `$type` in code: only import/exports are supported``\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when, after an `import` or `export` statement, more JavaScript is\nfound.\nAn example is:\n\n```mdx-invalid chrome=no\nexport const a = 1\nconst b = 2\n```\n\nThe reason for this error is that we only allow `import` and `export` to define\ndata.\nIf you want to define a variable or function, please export it.\n\n### `` Unexpected end of file in expression, expected a corresponding closing brace for `{` ``\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when there is an opening curly brace not followed by a closing brace.\nAn example is:\n\n```mdx-invalid chrome=no\na { b\n```\n\nThe reason for this error is that the parser is expecting another curly brace.\nIf you just want a brace but not an expression, escape it: `\\{`.\nIf you do want an expression, please make sure to close it with a closing brace\n`}`.\nIf there is a closing brace somewhere, make sure that the braces are each on\ntheir own lines with no text before the opening brace and no text after the\nclosing brace, or that there are no blank lines between the braces.\n\n### `Unexpected lazy line in expression in container`\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 3.\nIt occurs when containers with lazy lines are combined with expressions\nAn example is:\n\n```mdx-invalid chrome=no\n* {1 +\n2}\n\n> {1 +\n2}\n```\n\nThe reason for this error is that the parser it likely points to a bug.\nBe explicit with your list items and block quotes:\n\n```mdx-invalid chrome=no\n* {1 +\n  2}\n\n> {1 +\n> 2}\n```\n\n### `Could not parse expression with acorn: $error`\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when there are matching curly braces that, when interpreting what’s\ninside them as JavaScript, results in a syntax error.\nAn example is:\n\n```mdx-invalid chrome=no\na {const b = 'c'} d\n```\n\nAnother example:\n\n```mdx-invalid chrome=no\na {!} d\n```\n\nThe reason for this error is that the parser is expecting a JavaScript\nexpression.\nIf you just want braces instead of an expression, escape the opening: `\\{`.\nIf you do want an expression, make sure that it’s valid JavaScript and that it\nis an expression.\nThat means statements (such as `if` and `else` and `for` loops) do not work.\nIf you need complex logic, you can wrap statements and whole programs into an\nIIFE, or move it out to a different file, export it from there, and import it in\nMDX.\n\n### `Could not parse expression with acorn: Unexpected content after expression`\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when there are matching curly braces that, and valid JavaScript is\ninside them, but there’s too much JavaScript.\nAn example is:\n\n```mdx-invalid chrome=no\na {'b' 'c'} d\n```\n\nThe reason for this error is that the parser is expecting a single JavaScript\nexpression yielding one value.\nIf you just want braces instead of an expression, escape the opening: `\\{`.\nIf you do want an expression, make sure that it yields a single value.\n\n### `Unexpected extra content in spread: only a single spread is supported`\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when there are multiple values spread into a JSX tag.\nAn example is:\n\n```mdx-invalid chrome=no\n<div {...a, ...b} />\n```\n\nThe reason for this error is that JSX only allows spreading a single value at a\ntime:\n\n```mdx chrome=no\n<div {...a} {...b} />\n```\n\n### ``Unexpected `$type` in code: only spread elements are supported``\n\n### `Unexpected empty expression`\n\nThese errors are thrown by our MDX parser.\nThey were introduced in version 2.\nThey occur when something other than a spread is used in braces.\nAn example is:\n\n```mdx-invalid chrome=no\n<div {values} {/* comment */} {} />\n```\n\nThe reason for this error is that JSX only allows spreading values:\n\n```mdx chrome=no\n<div {...a} />\n```\n\n### `Unexpected end of file $at, expected $expect`\n\n### `Unexpected character $at, expected $expect`\n\nThese errors are thrown by our MDX parser.\nThey were introduced in MDX version 2.\nThey occur when something unexpected was found in a JSX tag.\nSome examples are:\n\n```mdx-invalid chrome=no\n<\n<.>\n</\n</.>\n<a\n<a?>\n<a:\n<a:+>\n<a.\n<a./>\n<a b\n<a b!>\n<a b:\n<a b:1>\n<a b=\n<a b=>\n<a b=\"\n<a b='\n<a b={\n<a/\n<a/->\n```\n\nThe reason for these errors is that JSX has a very strict grammar and expects\ntags to be valid.\nThere are different solutions depending on what was expected.\nPlease read the error message carefully as it indicates where the problem\noccurred and what was expected instead.\n\n### ``Unexpected closing slash `/` in tag, expected an open tag first``\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when a closing tag is found but there are no open tags.\nAn example is:\n\n```mdx-invalid chrome=no\n</div>\n```\n\nThe reason for this error is that only open tags can be closed.\nYou probably forgot an opening tag somewhere.\n\n### `Unexpected lazy line in container, expected line to be…`\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 3.\nIt occurs when containers with lazy lines are combined with JSX.\nAn example is:\n\n```mdx-invalid chrome=no\n* <x\ny />\n\n> <x\ny />\n```\n\nThe reason for this error is that the parser it likely points to a bug.\nBe explicit with your list items and block quotes:\n\n```mdx-invalid chrome=no\n* <x\n  y />\n\n> <x\n> y />\n```\n\n### `Unexpected attribute in closing tag, expected the end of the tag`\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when attributes are placed on closing tags.\nAn example is:\n\n```mdx-invalid chrome=no\n<h1>Text</h1 id=\"text\">\n```\n\nThe reason for this error is that only open tags can have attributes.\nMove these attributes to the corresponding opening tag.\n\n### ``Unexpected self-closing slash `/` in closing tag, expected the end of the tag``\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when a closing tag is also marked as self-closing.\nAn example is:\n\n```mdx-invalid chrome=no\n<h1>Text</h1/>\n```\n\nThe reason for this error is that only opening tags can be marked as\nself-closing.\nRemove the slash after the tag name and before `>`.\n\n### ``Unexpected closing tag `</$tag>`, expected corresponding closing tag for `<$tag>` ($at)``\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt occurs when a closing tag is seen that does not match the expected opening\ntag.\nAn example is:\n\n```mdx-invalid chrome=no\n<a>Text</b>\n```\n\nThe reason for this error is that tags must match in JSX.\nYou likely forgot to open or close one of the two correctly.\n\n### ``Cannot close `$type` ($at): a different token (`$type`, $at) is open``\n\n### ``Cannot close document, a token (`$type`, $at) is still open``\n\nThis error is thrown by our MDX parser.\nIt was introduced in version 2.\nIt typically occurs when markdown and JSX are not interleaved correctly.\nAn example is:\n\n```mdx-invalid chrome=no\n> <div>\n```\n\nThe reason for this error is that a markdown construct ends while there are\nstill tags open.\nSee the rules on\n[¶ Interleaving in § What is MDX?][interleaving]\n\n[contribute]: /community/contribute/\n\n[interleaving]: /docs/what-is-mdx/#interleaving\n\n[loader]: /packages/loader/\n\n[mdx]: /packages/mdx/\n\n[migation-v2]: /migrating/v2/\n\n[packages]: /packages/\n\n[what]: /docs/what-is-mdx/\n"
  },
  {
    "path": "docs/docs/using-mdx.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-09-30')\n}\nexport const navSortSelf = 3\n\n# Using MDX\n\nThis article explains how to use MDX files in your project.\nIt shows how you can pass props and how to import, define, or pass components. {/* more */}\nSee [§ Getting started][start] for how to integrate MDX into your project.\nTo understand how the MDX format works, we recommend that you start with\n[§ What is MDX][what].\n\n## Contents\n\n* [How MDX works](#how-mdx-works)\n* [MDX content](#mdx-content)\n  * [Props](#props)\n  * [Components](#components)\n  * [Layout](#layout)\n* [MDX provider](#mdx-provider)\n\n## How MDX works\n\nAn integration compiles MDX syntax to JavaScript.\nSay we have an MDX document, `example.mdx`:\n\n```mdx path=\"input.mdx\"\nexport function Thing() {\n  return <>World</>\n}\n\n# Hello <Thing />\n```\n\nThat’s *roughly* turned into the following JavaScript.\nThe below might help to form a mental model:\n\n```jsx twoslash path=\"output-outline.jsx\"\n/* @jsxRuntime automatic */\n/* @jsxImportSource react */\n\nexport function Thing() {\n  return <>World</>\n}\n\nexport default function MDXContent() {\n  return <h1>Hello <Thing /></h1>\n}\n```\n\nSome observations:\n\n* The output is serialized JavaScript that still needs to be evaluated\n* A comment is injected to configure how JSX is handled\n* It’s a complete file with import/exports\n* A component (`MDXContent`) is exported\n\nThe *actual* output is:\n\n```js twoslash path=\"output-actual.js\"\n// @noErrors\nimport {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n\nexport function Thing() {\n  return _jsx(_Fragment, {children: 'World'})\n}\n\nfunction _createMdxContent(props) {\n  const _components = {h1: 'h1', ...props.components}\n  return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})\n}\n\nexport default function MDXContent(props = {}) {\n  const {wrapper: MDXLayout} = props.components || {}\n  return MDXLayout\n    ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})\n    : _createMdxContent(props)\n}\n```\n\nSome more observations:\n\n* JSX is compiled away to function calls and an import of React†\n* The content component can be given `{components: {wrapper: MyLayout}}` to\n  wrap all content\n* The content component can be given `{components: {h1: MyComponent}}` to use\n  something else for the heading\n\n† MDX is not coupled to React.\nYou can also use it with [Preact][],\n[Vue][], [Emotion][],\n[Theme UI][],\netc.\nBoth the classic and automatic JSX runtimes are supported.\n\n## MDX content\n\nWe just saw that MDX files are compiled to components.\nYou can use those components like any other component in your framework of\nchoice.\nTake this file:\n\n```mdx path=\"example.mdx\"\n# Hi!\n```\n\nIt could be imported and used in a React app like so:\n\n```jsx twoslash path=\"example.jsx\"\n// @filename: types.d.ts\nimport type {} from 'mdx'\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\n// ---cut---\nimport {createRoot} from 'react-dom/client'\nimport Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconst container = document.getElementById('root')\nif (!container) throw new Error('Expected `root`')\nconst root = createRoot(container)\nroot.render(<Example />)\n```\n\nThe main content is exported as the default export.\nAll other values are also exported.\nTake this example:\n\n```mdx path=\"example.mdx\"\nexport function Thing() {\n  return <>World</>\n}\n\n# Hello <Thing />\n```\n\nIt could be imported in the following ways:\n\n```js twoslash path=\"example.js\"\n// @filename: types.d.ts\ndeclare module '*.mdx' {\n  export {MDXContent as default} from 'mdx/types';\n  export function Thing(): unknown;\n}\n// @filename: example.js\n/// <reference types=\"node\" />\n// ---cut---\n// A namespace import to get everything:\nimport * as everything from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\nconsole.log(everything) // {Thing: [Function: Thing], default: [Function: MDXContent]}\n\n// Default export shortcut and a named import specifier:\nimport Content, {Thing} from './example.mdx'\nconsole.log(Content) // [Function: MDXContent]\nconsole.log(Thing) // [Function: Thing]\n\n// Import specifier with another local name:\nimport {Thing as AnotherName} from './example.mdx'\nconsole.log(AnotherName) // [Function: Thing]\n```\n\n### Props\n\nIn [§ What is MDX][what], we showed that JavaScript expressions, inside curly\nbraces, can be used in MDX:\n\n```mdx path=\"example.mdx\"\nimport {year} from './data.js'\nexport const name = 'world'\n\n# Hello {name.toUpperCase()}\n\nThe current year is {year}\n```\n\nInstead of importing or defining data within MDX, data can also be passed\nto `MDXContent`.\nThe passed data is called `props`.\nTake for example:\n\n```mdx path=\"example.mdx\"\n# Hello {props.name.toUpperCase()}\n\nThe current year is {props.year}\n```\n\nThis file could be used as:\n\n```jsx twoslash path=\"example.jsx\"\n// @filename: types.d.ts\nimport type {} from 'mdx'\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\n// ---cut---\nimport React from 'react'\nimport Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\n// Use a `createElement` call:\nconsole.log(React.createElement(Example, {name: 'Venus', year: 2021}))\n\n// Use JSX:\nconsole.log(<Example name=\"Mars\" year={2022} />)\n```\n\n<Note type=\"info\">\n  **Note**:\n  Users of the MDX VS Code extension can add type\n  checking of `props` with a JSDoc comment.\n  See [`mdx-js/mdx-analyzer`][mdx-analyzer] for more info.\n</Note>\n\n### Components\n\nThere is one special prop: `components`.\nIt takes an object mapping component names to components.\nTake this example:\n\n```mdx path=\"example.mdx\"\n# Hello *<Planet />*\n```\n\nIt can be imported from JavaScript and passed components like so:\n\n```jsx twoslash path=\"example.jsx\"\n// @filename: types.d.ts\nimport type {} from 'mdx'\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\n/* @jsxImportSource react */\n// ---cut---\nimport Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconsole.log(\n  <Example\n    components={{\n      Planet() {\n        return <span style={{color: 'tomato'}}>Pluto</span>\n      }\n    }}\n  />\n)\n```\n\nYou don’t have to pass components.\nYou can also define or import them within MDX:\n\n```mdx path=\"example.mdx\"\nimport {Box, Heading} from 'rebass'\n\nMDX using imported components!\n\n<Box>\n  <Heading>Here’s a heading</Heading>\n</Box>\n```\n\nBecause MDX files *are* components, they can also import each other:\n\n```mdx path=\"example.mdx\"\nimport License from './license.md' // Assumes an integration is used to compile markdown -> JS.\nimport Contributing from './docs/contributing.mdx'\n\n# Hello world\n\n<License />\n\n---\n\n<Contributing />\n```\n\nHere are some other examples of passing components:\n\n```jsx twoslash path=\"example.jsx\"\n// @filename: types.d.ts\nimport type {} from 'mdx'\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\n/* @jsxImportSource react */\nimport Example from './example.mdx'\n// @errors: 2322 -- something with React 19 and nested components.\n// ---cut---\nconsole.log(\n  <Example\n    components={{\n      // Map `h1` (`# heading`) to use `h2`s.\n      h1: 'h2',\n      // Rewrite `em`s (`*like so*`) to `i` with a goldenrod foreground color.\n      em(props) {\n        return <i style={{color: 'goldenrod'}} {...props} />\n      },\n      // Pass a layout (using the special `'wrapper'` key).\n      wrapper({components, ...rest}) {\n        return <main {...rest} />\n      },\n      // Pass a component.\n      Planet() {\n        return 'Neptune'\n      },\n      // This nested component can be used as `<theme.text>hi</theme.text>`\n      theme: {\n        text(props) {\n          return <span style={{color: 'grey'}} {...props} />\n        }\n      }\n    }}\n  />\n)\n```\n\nThe following keys can be passed in `components`:\n\n* HTML equivalents for the things you write with markdown such as `h1` for\n  `# heading` (see [§ Table of components][toc] for examples)\n* `wrapper`, which defines the layout (but a local layout takes precedence)\n* anything else that is a valid JSX identifier (`foo`, `Quote`,\n  `custom-element`, `_`, `$x`, `a1`) for the things you write with JSX (like\n  `<So />` or `<like.so />`, note that locally defined components take\n  precedence)**‡**\n\n**‡** The rules for whether a name in JSX (so `x` in `<x>`) is a literal tag\nname (like `h1`) or not (like `Component`) are as follows:\n\n* if there’s a dot,\n  it’s a member expression (`<a.b>` → `h(a.b)`),\n  which means a reference to the key `b` taken from object `a`\n* otherwise,\n  if the name is not a valid JS identifier,\n  it’s a literal (`<a-b>` → `h('a-b')`)\n* otherwise,\n  if it starts with a lowercase,\n  it’s a literal (`<a>` → `h('a')`)\n* otherwise,\n  it’s a reference (`<A>` → `h(A)`)\n\nThese keys in `components` and the difference between literal tag names and\nreferences is illustrated as follows.\nWith the following MDX:\n\n```mdx path=\"example.mdx\"\n* [markdown syntax](#alpha)\n* <a href=\"#bravo\">JSX with a lowercase name</a>\n* <Link to=\"#charlie\">JSX with a capitalized name</Link>\n```\n\n…passed some components:\n\n```jsx twoslash path=\"example.jsx\"\n// @filename: types.d.ts\nimport type {} from 'mdx'\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\n/* @jsxImportSource react */\n// ---cut---\nimport Example from './example.mdx'\n\nconsole.log(\n  <Example\n    components={{\n      a(props) {\n        return <a {...props} style={{borderTop: '1px dotted', color: 'violet'}} />\n      },\n      Link(props) {\n        return <a href={props.to} children={props.children} style={{borderTop: '1px dashed', color: 'tomato'}} />\n      }\n    }}\n  />\n)\n```\n\n…we’d get:\n\n{\n  <div className=\"card\">\n    <ul>\n      <li><a href=\"#alpha\" style={{borderTop: '1px dotted', color: 'violet'}}>markdown syntax</a></li>\n      <li><a href=\"#bravo\">JSX with a lowercase name</a></li>\n      <li><a href=\"#charlie\" style={{borderTop: '1px dashed', color: 'tomato'}}>JSX with a capitalized name</a></li>\n    </ul>\n  </div>\n}\n\nObserve that the first link (`#alpha`) is dotted and violet.\nThat’s because `a` is the HTML equivalent for the markdown syntax being used.\nThe second link (`#bravo`) remains unchanged,\nbecause in JSX syntax `a` is a literal tag name.\nThe third link (`#charlie`) is dashed and tomato,\nbecause in JSX syntax `Link` is a reference.\n\n### Layout\n\nThere is one special component: the layout.\nIf it is defined, it’s used to wrap all content.\nA layout can be defined from within MDX using a default export:\n\n```mdx\nexport default function Layout({children}) {\n  return <main>{children}</main>;\n}\n\nAll the things.\n```\n\nThe layout can also be imported and *then* exported with an `export … from`:\n\n```mdx\nexport {Layout as default} from './components.js'\n```\n\nThe layout can also be passed as `components.wrapper` (but a local one takes\nprecedence).\n\n## MDX provider\n\nYou probably don’t need a provider.\nPassing components is typically fine.\nProviders often only add extra weight.\nTake for example this file:\n\n```mdx path=\"post.mdx\"\n# Hello world\n```\n\nUsed like so:\n\n```jsx twoslash path=\"app.jsx\"\n// @filename: components.d.ts\nimport React from 'react'\ndeclare const Heading: {H1: React.ComponentType}\ndeclare const Table: React.ComponentType\n// @filename: types.d.ts\nimport type {} from 'mdx'\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\n// ---cut---\nimport {createRoot} from 'react-dom/client'\nimport {Heading, /* … */ Table} from './components.js'\nimport Post from './post.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconst components = {\n  h1: Heading.H1,\n  // …\n  table: Table\n}\n\nconst container = document.getElementById('root')\nif (!container) throw new Error('Expected `root`')\nconst root = createRoot(container)\nroot.render(<Post components={components} />)\n```\n\nThat works, those components are used.\n\nBut when you’re nesting MDX files (importing them into each other) it can become\ncumbersome.\nLike so:\n\n```mdx path=\"post.mdx\"\nimport License from './license.md' // Assumes an integration is used to compile markdown -> JS.\nimport Contributing from './docs/contributing.mdx'\n\n# Hello world\n\n<License components={props.components} />\n\n---\n\n<Contributing components={props.components} />\n```\n\nTo solve this, a *[context][]* can be used in React, Preact, and Vue.\nContext provides a way to pass data through the component tree without having to\npass props down manually at every level.\nSet it up like so:\n\n1. Install either [`@mdx-js/react`][mdx-react], [`@mdx-js/preact`][mdx-preact],\n   or [`@mdx-js/vue`][mdx-vue],\n   depending on what framework you’re using\n2. Configure your MDX integration with\n   [`providerImportSource` in `ProcessorOptions`][processor-options]\n   set to that package, so either `'@mdx-js/react'`, `'@mdx-js/preact'`, or\n   `'@mdx-js/vue'`\n3. Import `MDXProvider` from that package.\n   Use it to wrap your top-most MDX content component and pass it your\n   `components` instead:\n\n```diff\n+import {MDXProvider} from '@mdx-js/react'\n import {createRoot} from 'react-dom/client'\n import {Heading, /* … */ Table} from './components/index.js'\n import Post from './post.mdx' // Assumes an integration is used to compile MDX -> JS.\n@@ -13,4 +14,8 @@ const components = {\n\n const container = document.getElementById('root')\n if (!container) throw new Error('Expected `root`')\n const root = createRoot(container)\n-root.render(<Post components={components} />)\n+root.render(\n+  <MDXProvider components={components}>\n+    <Post />\n+  </MDXProvider>\n+)\n```\n\nNow you can remove the explicit and verbose component passing:\n\n```diff\n import License from './license.md' // Assumes an integration is used to compile markdown -> JS.\n import Contributing from './docs/contributing.mdx'\n\n # Hello world\n\n-<License components={props.components} />\n+<License />\n\n ---\n\n-<Contributing components={props.components} />\n+<Contributing />\n```\n\nWhen `MDXProvider`s are nested, their components are merged.\nTake this example:\n\n```jsx twoslash\n// @filename: types.d.ts\nimport React from 'react'\nimport type {MDXContent} from 'mdx/types.js'\ndeclare const Component1: React.ComponentType\ndeclare const Component2: React.ComponentType\ndeclare const Component3: React.ComponentType\ndeclare const Component4: React.ComponentType\ndeclare const Content: MDXContent\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\nimport {MDXProvider} from '@mdx-js/react'\nimport React from 'react'\nimport {Component1, Component2, Component3, Component4, Content} from './types.js'\n// ---cut---\nconsole.log(\n  <MDXProvider components={{h1: Component1, h2: Component2}}>\n    <MDXProvider components={{h2: Component3, h3: Component4}}>\n      <Content />\n    </MDXProvider>\n  </MDXProvider>\n)\n```\n\n…which results in `h1`s using `Component1`, `h2`s using `Component3`, and `h3`s\nusing `Component4`.\n\nTo merge differently or not at all, pass a function to `components`.\nIt’s given the current context `components` and what it returns will be used\ninstead.\nIn this example the current context components are discarded:\n\n```jsx twoslash\n// @filename: types.d.ts\nimport React from 'react'\nimport type {MDXContent} from 'mdx/types.js'\ndeclare const Component1: React.ComponentType\ndeclare const Component2: React.ComponentType\ndeclare const Component3: React.ComponentType\ndeclare const Component4: React.ComponentType\ndeclare const Content: MDXContent\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\nimport {MDXProvider} from '@mdx-js/react'\nimport React from 'react'\nimport {Component1, Component2, Component3, Component4, Content} from './types.js'\n// ---cut---\nconsole.log(\n  <MDXProvider components={{h1: Component1, h2: Component2}}>\n    <MDXProvider\n      components={\n        function () {\n          return {h2: Component3, h3: Component4}\n        }\n      }\n    >\n      <Content />\n    </MDXProvider>\n  </MDXProvider>\n)\n```\n\n…which results in `h2`s using `Component3` and `h3`s using `Component4`.\nNo component is used for `h1`.\n\nIf you’re not nesting MDX files, or not nesting them often, don’t use\nproviders: pass components explicitly.\n\n[context]: https://reactjs.org/docs/context.html\n\n[emotion]: /docs/getting-started/#emotion\n\n[mdx-analyzer]: https://github.com/mdx-js/mdx-analyzer\n\n[mdx-preact]: /packages/preact/\n\n[mdx-react]: /packages/react/\n\n[mdx-vue]: /packages/vue/\n\n[preact]: /docs/getting-started/#preact\n\n[processor-options]: /packages/mdx/#processoroptions\n\n[start]: /docs/getting-started/\n\n[theme ui]: /docs/getting-started/#theme-ui\n\n[toc]: /table-of-components/\n\n[vue]: /docs/getting-started/#vue\n\n[what]: /docs/what-is-mdx/\n"
  },
  {
    "path": "docs/docs/what-is-mdx.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'},\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2018-08-11')\n}\nexport const navSortSelf = 1\n\n# What is MDX?\n\nThis article explains what the MDX format is.\nIt shows how markdown, JSX, JavaScript expressions, and `import` and\n`export` statements in ESM can be used inside MDX. {/* more */}\nSee [§ Getting started][start] for details on how to integrate MDX into your\nproject.\nSee [§ Using MDX][use] when you’re already all set up to use MDX.\n\n## Contents\n\n* [Prerequisites](#prerequisites)\n* [Markdown for the component era](#markdown-for-the-component-era)\n* [MDX syntax](#mdx-syntax)\n  * [Markdown](#markdown)\n  * [JSX](#jsx)\n  * [Expressions](#expressions)\n  * [ESM](#esm)\n  * [Interleaving](#interleaving)\n* [Further reading](#further-reading)\n\n## Prerequisites\n\nTo write and enjoy MDX, you should be familiar with both markdown\n(see this [cheat sheet and tutorial][commonmark-help] for help) and\nJavaScript (specifically [JSX][jsx-spec]).\n\n## Markdown for the component era\n\nMDX allows you to use JSX in your markdown content.\nYou can import components, such as interactive charts or alerts, and embed them\nwithin your content.\nThis makes writing long-form content with components a blast.\n🚀\n\nMore practically MDX can be explained as a format that combines markdown with\nJSX and looks as follows:\n\n```mdx\n# Hello, world!\n\n<div className=\"note\">\n  > Some notable things in a block quote!\n</div>\n```\n\nThe heading and block quote are markdown, while those *HTML-like tags* are JSX.\nMarkdown often feels more natural to type than HTML or JSX for common things\nlike emphasis or headings.\nJSX is an extension to JavaScript that *looks* like HTML but makes it convenient\nto use components (reusable things).\n\nThis example uses `className` on the `<div>`.\nThat’s because it was written for React and React expects classes that way.\nOther frameworks, such as Vue and Preact, expect classes to be defined\ndifferently, so note that there are some differences in how JSX has to be\nauthored depending on what tools it’s used with.\n\nA few other features from JavaScript are supported in MDX as well: expressions\nin braces (`{1 + 1}`) and ESM (`import` and `export`).\n\n## MDX syntax\n\n<Note type=\"info\">\n  **Note**:\n  You don’t have to use this syntax with `@mdx-js/*` packages.\n  Or use it always.\n  If you’re using a bundler integration you can change between MDX and\n  markdown through the file extension (`.mdx` vs. `.md`).\n  Alternatively, `options.format` can be used.\n</Note>\n\nThe MDX syntax combines markdown with JSX.\nThis gives us something along the lines of literate programming.\nIt also gives us an odd mix of two languages: markdown is **whitespace\nsensitive** and **forgiving** (what you type may not exactly work but it\nwon’t crash) whereas JavaScript is **whitespace insensitive** and\n**unforgiving** (it does crash on typos).\n\nWeirdly enough we quite like how they combine!\n\n### Markdown\n\nMarkdown often feels more natural to type than HTML or JSX for common things\nlike emphasis or headings.\nMarkdown typically looks more like what’s intended and is terser.\nInstead of the following HTML:\n\n```html\n<blockquote>\n  <p>A blockquote with <em>some</em> emphasis.</p>\n</blockquote>\n```\n\nYou can write the equivalent in markdown (or MDX) like so:\n\n```md\n> A blockquote with *some* emphasis.\n```\n\nMDX supports standard markdown by default ([CommonMark][]):\n\n````md\n# Heading (rank 1)\n## Heading 2\n### 3\n#### 4\n##### 5\n###### 6\n\n> Block quote\n\n* Unordered\n* List\n\n1. Ordered\n2. List\n\nA paragraph, introducing a thematic break:\n\n---\n\n```js\nsome.code()\n```\n\na [link](https://example.com), an ![image](./image.png), some *emphasis*,\nsomething **strong**, and finally a little `code()`.\n````\n\nNonstandard markdown features (such as GFM, frontmatter, math, syntax\nhighlighting) can be enabled with plugins (see\n[¶ Using plugins][using-plugins]).\n\nSome markdown features don’t work in MDX:\n\n* Indented code does not work in MDX:\n  ```mdx\n      console.log(1) // this is a paragraph in MDX!\n  ```\n  The reason for that is so you can nicely indent your components:\n  ```mdx\n  <main>\n    <article>\n      # Hello!\n    </article>\n  </main>\n  ```\n* Autolinks do not work in MDX.\n  The reason is that they can be indistinguishable from JSX (for example:\n  `<svg:rect>`) and we prefer being explicit.\n  If you want links, use full links:\n  `[descriptive text](https://and-the-link-here.com)`\n* HTML syntax doesn’t work in MDX as it’s replaced by JSX (`<img>` to\n  `<img />`).\n  Instead of HTML comments, you can use JavaScript comments in braces:\n  `{/* comment! */}`\n* Unescaped left angle bracket / less than (`<`) and left curly brace (`{`)\n  have to be escaped: `\\<` or `\\{` (or use expressions: `{'<'}`, `{'{'}`)\n\nMore on how MDX differs from markdown is\n[documented here](https://github.com/micromark/mdx-state-machine#72-deviations-from-markdown).\n\n### JSX\n\n[JSX][] is an extension to JavaScript that *looks* like HTML but makes it\nconvenient to use components (reusable things).\nJSX is typically combined with a frontend framework like React, Preact, or Vue.\nThese frameworks add support for components, which let you change repeating\nthings like the following markup:\n\n```html\n<h2>Hello, Venus!</h2>\n<h2>Hello, Mars!</h2>\n```\n\n…to JSX (or MDX) like this:\n\n```mdx\n<Welcome name=\"Venus\" />\n<Welcome name=\"Mars\" />\n```\n\nJSX is good for **components**.\nIt makes repeating things more clear and allows for separation of concerns.\nMDX supports JSX syntax.\nThe following looks a lot like HTML:\n\n```mdx\n<h1>Heading!</h1>\n\n<abbr title=\"HyperText Markup Language\">HTML</abbr> is a lovely language.\n\n<section>\n  And here is *markdown* in **JSX**!\n</section>\n```\n\nBut as previously mentioned you can use components too.\nNote that components must be defined.\nYou can import them, define them locally, or pass them in later (see\n[§ Using MDX][use]):\n\n```mdx\n<MyComponent id=\"123\" />\n\nYou can also use objects with components, such as the `thisOne` component on\nthe `myComponents` object: <myComponents.thisOne />\n\n<Component\n  open\n  x={1}\n  label={'this is a string, *not* markdown!'}\n  icon={<Icon />}\n/>\n```\n\nThere are a few edge cases\n[where MDX differs from JSX](https://github.com/micromark/mdx-state-machine#73-deviations-from-jsx).\n\n### Expressions\n\nMDX also supports JavaScript expressions inside curly braces:\n\n```mdx\nTwo 🍰 is: {Math.PI * 2}\n```\n\nExpressions can contain whole JavaScript programs as long as they’re\n(wrapped in) an expression that evaluates to something that can be rendered.\nYou can use an [IIFE][] like so:\n\n```mdx\n{(function () {\n  const guess = Math.random()\n\n  if (guess > 0.66) {\n    return <span style={{color: 'tomato'}}>Look at us.</span>\n  }\n\n  if (guess > 0.33) {\n    return <span style={{color: 'violet'}}>Who would have guessed?!</span>\n  }\n\n  return <span style={{color: 'goldenrod'}}>Not me.</span>\n})()}\n```\n\nExpressions can be empty or contain just a comment:\n\n```mdx\n{/* A comment! */}\n```\n\n### ESM\n\nMDX supports `import` and `export` statements from JavaScript as well.\nThese ESM features can be used within MDX to define things:\n\n```mdx\nimport {External} from './some/place.js'\n\nexport const Local = properties => <span style={{color: 'red'}} {...properties} />\n\nAn <External>external</External> component and a <Local>local one</Local>.\n```\n\nESM can also be used for non-components (data):\n\n```mdx\nimport {Chart} from './chart.js'\nimport population from './population.js'\nexport const pi = 3.14\n\n<Chart data={population} label={'Something with ' + pi} />\n```\n\n### Interleaving\n\nYou can use markdown “inlines” but not “blocks” inside JSX if the text and tags\nare on the same line:\n\n```mdx\n<div># this is not a heading but *this* is emphasis</div>\n```\n\nText and tags on one line don’t produce blocks so they don’t produce `<p>`s\neither.\nOn separate lines, they do:\n\n```mdx\n<div>\n  This is a `p`.\n</div>\n```\n\nWe differentiate using this rule (same line or not).\nNot based on semantics of elements in HTML.\nSo you *can* build incorrect HTML (which you shouldn’t):\n\n```mdx\n<h1 className=\"main\">\n  Don’t do this: it’s a `p` in an `h1`\n</h1>\n\n<h1 className=\"main\">Do this: an `h1` with `code`</h1>\n```\n\nIt’s not possible to wrap “blocks” if text and tags are on the same line but the\ncorresponding opening and closing tags are in different blocks\n(so this is invalid!):\n\n```mdx-invalid chrome=no\nWelcome! <a href=\"about.html\">\n\nThis is home of...\n\n# The Falcons!</a>\n```\n\nTo parse markdown, we first have to divide it into “blocks”.\nSo in this case two paragraphs and a heading.\nLeaving an opening `a` tag in the first paragraph and a closing `a` tag in\nthe heading.\nWhich causes an error as it is misnested.\n\n## Further reading\n\n* If you want to use MDX in your project, see [§ Getting started][start];\n  see [§ Using MDX][use] when you’re already all set up\n* If you’re getting errors when working with the format, see\n  [§ Troubleshooting MDX][trouble]\n\n[commonmark]: https://commonmark.org\n\n[commonmark-help]: https://commonmark.org/help/\n\n[iife]: https://developer.mozilla.org/en-US/docs/Glossary/IIFE\n\n[jsx]: https://reactjs.org/docs/introducing-jsx.html\n\n[jsx-spec]: https://facebook.github.io/jsx/\n\n[start]: /docs/getting-started/\n\n[trouble]: /docs/troubleshooting-mdx/\n\n[use]: /docs/using-mdx/\n\n[using-plugins]: /docs/extending-mdx/#using-plugins\n"
  },
  {
    "path": "docs/guides/embed.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06')\n}\nexport const navSortSelf = 5\n\n# Embed\n\nThis guide explores how to embed things like tweets, gists or codepens in\nmarkdown. {/* more */}\nMDX supports standard markdown syntax ([CommonMark][]).\nIt does not support embeds by default.\n\nThere are two ways to accomplish embeds: at compile time or at runtime.\nDoing it at compile time means the effort is spent upfront so that readers will\nhave a fast experience as no requests have to be made on the client.\nDoing it at runtime gives more flexibility by moving the work to the client.\nThis can result in a slow experience for readers though.\nIt also depends on what framework you use (as in it’s specific to React, Preact,\nVue, etc.)\n\n## Embeds at compile time\n\nYou can use [`@remark-embedder/core`][remark-embedder] by doing something like\nthis:\n\n```js path=\"example.js\"\nimport {compile} from '@mdx-js/mdx'\n// Note: `@remark-embedder` is currently using faux-esm.\nimport fauxRemarkEmbedder from '@remark-embedder/core'\nimport fauxOembedTransformer from '@remark-embedder/transformer-oembed'\n\nconst remarkEmbedder = fauxRemarkEmbedder.default\nconst oembedTransformer = fauxOembedTransformer.default\n\nconst code = `\nCheck out this video:\n\nhttps://www.youtube.com/watch?v=dQw4w9WgXcQ\n`\n\nconsole.log(\n  String(\n    await compile(code, {\n      remarkPlugins: [\n        [\n          // @ts-expect-error: `remarkEmbedder` types are wrong.\n          remarkEmbedder,\n          {transformers: [oembedTransformer]}\n        ]\n      ]\n    })\n  )\n)\n```\n\n<details>\n  <summary>Expand equivalent JSX</summary>\n\n  ```jsx path=\"output.jsx\"\n  <>\n    <p>Check out this video:</p>\n    <iframe\n      width=\"200\"\n      height=\"113\"\n      src=\"https://www.youtube.com/embed/dQw4w9WgXcQ?feature=oembed\"\n      frameBorder=\"0\"\n      allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"\n      allowFullScreen\n      title=\"Rick Astley - Never Gonna Give You Up (Official Music Video)\"\n    ></iframe>\n  </>\n  ```\n</details>\n\n## Embeds at run time\n\nYou can use the React-specific [MDX Embed][mdx-embed] to embed things in MDX.\nHere is an example MDX file that uses a specific embed without `@mdx-js/react`:\n\n```mdx path=\"example.mdx\"\nimport {CodePen} from 'mdx-embed'\n\nHere’s a codepen, and some other blog post text.\n\n<CodePen codePenId=\"PNaGbb\" />\n```\n\n<details>\n  <summary>Expand equivalent JSX</summary>\n\n  ```jsx path=\"output.jsx\"\n  <>\n    <p>Here’s a codepen, and some other blog post text.</p>\n    <CodePen codePenId=\"PNaGbb\" />\n  </>\n  ```\n</details>\n\nIf you don’t want to use explicit imports in MDX files:\n\n```mdx path=\"example.mdx\"\nHere’s a codepen, and some other blog post text.\n\n<CodePen codePenId=\"PNaGbb\" />\n```\n\nThen you can either pass all components:\n\n```jsx path=\"example.jsx\"\nimport * as embeds from 'mdx-embed'\nimport Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconsole.log(<Example components={...embeds} />)\n```\n\nOr, if you’ve installed and configured [`@mdx-js/react`][mdx-react], you can\nalso use `MDXEmbedProvider`:\n\n```jsx path=\"example.jsx\"\nimport {MDXEmbedProvider} from 'mdx-embed'\nimport Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconsole.log(\n  <MDXEmbedProvider>\n    <Example />\n  </MDXEmbedProvider>\n)\n```\n\n[commonmark]: https://spec.commonmark.org/current/\n\n[mdx-embed]: https://mdx-embed.netlify.app/\n\n[mdx-react]: /packages/react/\n\n[remark-embedder]: https://github.com/remark-embedder/core\n"
  },
  {
    "path": "docs/guides/frontmatter.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06')\n}\nexport const navSortSelf = 2\n\n# Frontmatter\n\nThis guide explores how to support YAML frontmatter in MDX. {/* more */}\nMDX supports standard markdown syntax ([CommonMark][]).\nThat means frontmatter is not supported by default.\n\nMDX comes with a powerful and dynamic alternative to frontmatter, namely ESM\n(`import`/`export`).\nThese exports:\n\n```mdx path=\"example.mdx\"\nexport const name = 'World'\nexport const title = 'Hi, ' + name + '!'\n\n# {title}\n```\n\nCan be used like so:\n\n```js twoslash path=\"example.js\"\n// @filename: types.d.ts\ndeclare module '*.mdx' {\n  export {MDXContent as default} from 'mdx/types'\n  export const name: string\n  export const title: string\n}\n// @filename: example.js\n/// <reference types=\"node\" />\n// ---cut---\nimport * as Post from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconsole.log(Post.title) // Prints 'Hi, World!'\n```\n\nYou might prefer frontmatter though, as it lets you define data that can be\nextracted from the file system *before* compiling.\nSay our MDX with frontmatter looked like this:\n\n```mdx path=\"example.mdx\"\n---\ntitle: Hi, World!\n---\n\n# Hi, World!\n```\n\nThen without compiling or evaluating the metadata can be accessed like so:\n\n```js twoslash path=\"example.js\"\n/// <reference types=\"node\" />\n// ---cut---\nimport {read} from 'to-vfile'\nimport {matter} from 'vfile-matter'\n\nconst file = await read('example.mdx')\nmatter(file)\n\nconsole.log(file.data.matter)\n```\n\nOur compiler, `@mdx-js/mdx`, doesn’t understand YAML frontmatter by default but\nit can be enabled by using a remark plugin,\n[`remark-frontmatter`][remark-frontmatter]:\n\n```js twoslash path=\"example.js\"\n// @filename: example.js\n/// <reference types=\"node\" />\n// ---cut---\nimport fs from 'node:fs/promises'\nimport {compile} from '@mdx-js/mdx'\nimport remarkFrontmatter from 'remark-frontmatter'\n\nconst file = await compile(await fs.readFile('example.mdx'), {\n  remarkPlugins: [remarkFrontmatter]\n})\n\nconsole.log(file)\n```\n\nNow it “works”.\nThe frontmatter is not rendered as if it was markdown.\nBut the data embedded in the frontmatter isn’t available from *inside* the MDX.\nWhat if we wanted that too?\nLike so:\n\n```mdx path=\"example.mdx\"\n---\ntitle: Hi, World!\n---\n\n# {title}\n```\n\nThat’s exactly what the remark plugin\n[`remark-mdx-frontmatter`][remark-mdx-frontmatter] does.\n\nThat plugin, like all remark plugins, can be passed as\n[`remarkPlugins` in `ProcessorOptions`][processor-options].\nMore info on plugins is available in [§ Extending MDX][extend]\n\n[commonmark]: https://spec.commonmark.org/current/\n\n[extend]: /docs/extending-mdx/\n\n[processor-options]: /packages/mdx/#processoroptions\n\n[remark-frontmatter]: https://github.com/remarkjs/remark-frontmatter\n\n[remark-mdx-frontmatter]: https://github.com/remcohaszing/remark-mdx-frontmatter\n"
  },
  {
    "path": "docs/guides/gfm.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06')\n}\nexport const navSortSelf = 1\n\n# GitHub flavored markdown (GFM)\n\nThis guide explores how to support GFM features such as autolink literals,\nfootnotes, strikethrough, tables, and task lists. {/* more */}\nMDX supports standard markdown syntax ([CommonMark][]).\nThat means [GitHub flavored markdown (GFM)][gfm] extensions are not supported by\ndefault.\nThey can be enabled by using a remark plugin: [`remark-gfm`][remark-gfm].\nThat plugin, like all remark plugins, can be passed in [`remarkPlugins` in\n`ProcessorOptions`][processor-options].\nMore info on plugins is available in [§ Extending MDX][extend]\n\nSay we have an MDX file like this:\n\n```mdx path=\"example.mdx\"\n# GFM\n\n## Autolink literals\n\nwww.example.com, https://example.com, and contact@example.com.\n\n## Footnote\n\nA note[^1]\n\n[^1]: Big note.\n\n## Strikethrough\n\n~one~ or ~~two~~ tildes.\n\n## Table\n\n| a | b  |  c |  d  |\n| - | :- | -: | :-: |\n\n## Tasklist\n\n* [ ] to do\n* [x] done\n```\n\nThe above MDX with GFM can be transformed with the following module:\n\n```js twoslash path=\"example.js\"\n// @filename: example.js\n/// <reference types=\"node\" />\n// ---cut---\nimport fs from 'node:fs/promises'\nimport {compile} from '@mdx-js/mdx'\nimport remarkGfm from 'remark-gfm'\n\nconsole.log(\n  String(\n    await compile(await fs.readFile('example.mdx'), {remarkPlugins: [remarkGfm]})\n  )\n)\n```\n\n<details>\n  <summary>Expand equivalent JSX</summary>\n\n  ```jsx path=\"output.jsx\"\n  <>\n    <h1>GFM</h1>\n    <h2>Autolink literals</h2>\n    <p>\n      <a href=\"http://www.example.com\">www.example.com</a>,{' '}\n      <a href=\"https://example.com\">https://example.com</a>, and{' '}\n      <a href=\"mailto:contact@example.com\">contact@example.com</a>.\n    </p>\n    <h2>Footnote</h2>\n    <p>\n      A note\n      <sup>\n        <a\n          href=\"#user-content-fn-1\"\n          id=\"user-content-fnref-1\"\n          data-footnote-ref=\"true\"\n          aria-describedby=\"footnote-label\"\n        >\n          1\n        </a>\n      </sup>\n    </p>\n    <h2>Strikethrough</h2>\n    <p>\n      <del>one</del> or <del>two</del> tildes.\n    </p>\n    <h2>Table</h2>\n    <table>\n      <thead>\n        <tr>\n          <th>a</th>\n          <th style={{textAlign: 'left'}}>b</th>\n          <th style={{textAlign: 'right'}}>c</th>\n          <th style={{textAlign: 'center'}}>d</th>\n        </tr>\n      </thead>\n    </table>\n    <h2>Tasklist</h2>\n    <ul className=\"contains-task-list\">\n      <li className=\"task-list-item\">\n        <input type=\"checkbox\" disabled /> to do\n      </li>\n      <li className=\"task-list-item\">\n        <input type=\"checkbox\" disabled checked />\n        done\n      </li>\n    </ul>\n    <section data-footnotes=\"true\" className=\"footnotes\">\n      <h2 className=\"sr-only\" id=\"footnote-label\">\n        Footnotes\n      </h2>\n      <ol>\n        <li id=\"user-content-fn-1\">\n          <p>\n            Big note.{' '}\n            <a\n              href=\"#user-content-fnref-1\"\n              data-footnote-backref=\"\"\n              aria-label=\"Back to reference 1\"\n              className=\"data-footnote-backref\"\n            >\n              ↩\n            </a>\n          </p>\n        </li>\n      </ol>\n    </section>\n  </>\n  ```\n</details>\n\n[commonmark]: https://spec.commonmark.org/current/\n\n[extend]: /docs/extending-mdx/\n\n[gfm]: https://github.github.com/gfm/\n\n[processor-options]: /packages/mdx/#processoroptions\n\n[remark-gfm]: https://github.com/remarkjs/remark-gfm\n"
  },
  {
    "path": "docs/guides/index.mdx",
    "content": "{\n  /**\n   * @import {Item} from '../_component/sort.js'\n   */\n\n  /**\n   * @typedef Props\n   * @property {Item} navigationTree\n   */\n}\n\nimport assert from 'node:assert/strict'\nimport {NavigationGroup} from '../_component/nav.jsx'\n\nexport const info = {\n  author: [{name: 'MDX Contributors'}],\n  modified: new Date('2024-07-04'),\n  published: new Date('2021-11-01')\n}\nexport const navSortSelf = 2\n\n# Guides\n\nThese guides explain how to accomplish several common use cases and patterns\naround MDX.\n\n{\n  (function () {\n    const navigationTree = props.navigationTree\n    const category = navigationTree.children.find(function (item) {\n      return item.name === '/guides/'\n    })\n    assert(category)\n\n    return (\n      <nav>\n        <NavigationGroup items={category.children} includeDescription />\n      </nav>\n    )\n  })()\n}\n"
  },
  {
    "path": "docs/guides/injecting-components.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2024-07-04'),\n  published: new Date('2023-10-24')\n}\nexport const navSortSelf = 7\n\n# Injecting components\n\nThis guide shows how to inject arbitrary components into MDX when it\nruns. {/* more */}\nIt shows how the underlying features used by our providers (`@mdx-js/react`,\n`@mdx-js/preact`) and the [`mdx-components.tsx`][next-mdx-components] file\nsupported by Next.js work,\nand how you can take advantage of that functionality yourself.\n\nIn many cases you do not need this,\nas you can pass components to MDX:\n\n```mdx path=\"example.mdx\"\n# Hello *<Planet />*\n```\n\nYou can pass `Planet` and say a component used instead of the `h1`:\n\n```jsx twoslash path=\"example.jsx\"\n// @filename: types.d.ts\nimport type {} from 'mdx'\n// @filename: example.jsx\n/// <reference lib=\"dom\" />\n/* @jsxImportSource react */\n// ---cut---\nimport Example from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconsole.log(\n  <Example\n    components={{\n      Planet() {\n        return 'Pluto'\n      },\n      h1(properties) {\n        return <h2 {...properties} />\n      }\n    }}\n  />\n)\n```\n\nWhen you find yourself passing that `components` prop around a lot,\nyou might want to look at an alternative.\nYou might reach for our context based providers (`@mdx-js/react`,\n`@mdx-js/preact`),\nbut context has performance downsides and context doesn’t always work (such as\nin RSC).\n\nBut first,\nhow does component passing work?\nThat can be illustrated by looking at the code generated by MDX for the above\n`example.mdx`.\nHere is a diff that shows what the example normally compiles to and what\nchanges when `providerImportSource: 'xxx'` is passed:\n\n```diff\n@@ -1,7 +1,13 @@\n import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n+import {useMDXComponents as _provideComponents} from 'xxx'\n\n function _createMdxContent(props) {\n-  const _components = {em: 'em', h1: 'h1', ...props.components}\n+  const _components = {\n+    em: 'em',\n+    h1: 'h1',\n+    ..._provideComponents(),\n+    ...props.components\n+  }\n   const {Planet} = _components\n   if (!Planet) _missingMdxReference('Planet', true)\n   return _jsxs(_components.h1, {\n@@ -10,7 +16,7 @@ function _createMdxContent(props) {\n }\n\n export default function MDXContent(props = {}) {\n-  const {wrapper: MDXLayout} = props.components || {}\n+  const {wrapper: MDXLayout} = {..._provideComponents(), ...props.components}\n   return MDXLayout\n     ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})\n     : _createMdxContent(props)\n```\n\nObserve that components have defaults (such as that `h1` will use `'h1'`) and\nthat components are taken from `props.components`.\nWhat changes is an added call to `_provideComponents`,\nwhich refers to an `useMDXComponents` export from the module we specified\n(`xxx`).\n\nWe can use this interface to inject components from a file.\nIn that file,\nwe need a `useMDXComponents` function that returns our components.\n\n```jsx twoslash path=\"mdx-components.js\"\n// @filename: mdx-components.jsx\n/* @jsxImportSource react */\n// ---cut---\n/**\n * @import {MDXComponents} from 'mdx/types.js'\n */\n\n/** @returns {MDXComponents} */\nexport function useMDXComponents() {\n  return {\n    Planet() {\n      return 'Pluto'\n    },\n    h1(properties) {\n      return <h2 {...properties} />\n    }\n  }\n}\n```\n\nAnd now passing a file path or URL to that file as `providerImportSource`,\nsuch as with `import.meta.resolve('./mdx-components.js')`:\n\n```diff\n@@ -1,5 +1,5 @@\n import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n-import {useMDXComponents as _provideComponents} from 'xxx'\n+import {useMDXComponents as _provideComponents} from 'file:///Users/tilde/…/mdx-components.js'\n```\n\nNow our locally defined components will be used in all MDX files!\n\n[next-mdx-components]: https://nextjs.org/docs/pages/building-your-application/configuring/mdx\n"
  },
  {
    "path": "docs/guides/math.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06')\n}\nexport const navSortSelf = 3\n\n# Math\n\nThis guide explores how to support math (LaTeX) in MDX. {/* more */}\nMDX supports standard markdown syntax ([CommonMark][]).\nThat means math is not supported by default.\nMath can be enabled by using a remark plugin: [`remark-math`][remark-math],\ncombined with a rehype plugin: either\n[`rehype-katex`][rehype-katex] (KaTeX) or [`rehype-mathjax`][rehype-mathjax]\n(MathJax).\nLike other remark and rehype plugins, they can be passed in [`remarkPlugins`\nand `rehypePlugins`, respectively, in `ProcessorOptions`][processor-options].\nMore info on plugins is available in [§ Extending MDX][extend]\n\nSay we have an MDX file like this:\n\n```mdx path=\"example.mdx\"\n# $$\\sqrt{a^2 + b^2}$$\n```\n\nThe above MDX with math can be transformed with the following module:\n\n```js twoslash path=\"example.js\"\n// @filename: example.js\n/// <reference types=\"node\" />\n// ---cut---\nimport fs from 'node:fs/promises'\nimport {compile} from '@mdx-js/mdx'\nimport rehypeKatex from 'rehype-katex'\nimport remarkMath from 'remark-math'\n\nconsole.log(\n  String(\n    await compile(await fs.readFile('example.mdx'), {\n      rehypePlugins: [rehypeKatex],\n      remarkPlugins: [remarkMath]\n    })\n  )\n)\n```\n\n<details>\n  <summary>Expand equivalent JSX</summary>\n\n  ```jsx path=\"output.jsx\"\n  <>\n    <h1>\n      <span className=\"katex\">\n        <span className=\"katex-mathml\">\n          <math xmlns=\"http://www.w3.org/1998/Math/MathML\">…</math>\n        </span>\n        <span className=\"katex-html\" aria-hidden=\"true\">\n          …\n        </span>\n      </span>\n    </h1>\n  </>\n  ```\n</details>\n\n<Note type=\"important\">\n  **Important**: if you chose `rehype-katex`, you should also use `katex.css`\n  somewhere on the page to style math properly.\n  At the time of writing, the last version is:\n\n  ```html\n  <!-- Get the latest one from: https://katex.org/docs/browser -->\n  <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css\" integrity=\"sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+\" crossorigin=\"anonymous\">\n  ```\n\n  To get the latest link to the stylesheet, go to [`katex docs`][katex-browser].\n\n  {/* to do: once in a while, get the latest. */}\n</Note>\n\n<Note type=\"info\">\n  **Note:** see also\n  [`remark-mdx-math-enhanced`](https://github.com/goodproblems/remark-mdx-math-enhanced),\n  which you can use to support JavaScript expressions inside of math (such as to\n  access properties or to make calculations)\n</Note>\n\n[commonmark]: https://spec.commonmark.org/current/\n\n[extend]: /docs/extending-mdx/\n\n[katex-browser]: https://katex.org/docs/browser#loading-as-global\n\n[processor-options]: /packages/mdx/#processoroptions\n\n[rehype-katex]: https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex\n\n[rehype-mathjax]: https://github.com/remarkjs/remark-math/tree/main/packages/rehype-mathjax\n\n[remark-math]: https://github.com/remarkjs/remark-math/tree/main/packages/remark-math\n"
  },
  {
    "path": "docs/guides/mdx-on-demand.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-11-13')\n}\nexport const navSortSelf = 6\n\n# MDX on demand\n\nThis guide shows how to use `@mdx-js/mdx` to compile MDX on the server and run\nthe result on clients. {/* more */}\nSome frameworks, such as Next.js and Remix, make it easy to split work between\nservers and clients.\nUsing that it’s possible to for example do most of the work on demand on the\nserver instead of at build time, then pass the resulting data to clients, where\nthey finally use it.\n\nThis is similar to what people sometimes use [`mdx-bundler`][mdx-bundler] or\n[`next-mdx-remote`][next-mdx-remote] for, but MDX also supports it.\n\n## Quick example\n\nOn the server:\n\n```js twoslash path=\"server.js\"\nimport {compile} from '@mdx-js/mdx'\n\nconst code = String(await compile('# hi', {\n  outputFormat: 'function-body',\n  /* …otherOptions */\n}))\n// To do: send `code` to the client somehow.\n```\n\nOn the client:\n\n```js twoslash path=\"client.js\"\nimport {run} from '@mdx-js/mdx'\nimport * as runtime from 'react/jsx-runtime'\n\nconst code = '' // To do: get `code` from server somehow.\n\nconst {default: Content} = await run(code, {...runtime, baseUrl: import.meta.url})\n```\n\n`Content` is now an `MDXContent` component that you can use like normal in your\nframework (see [§ Using MDX][use]).\n\nMore information is available in the API docs of `@mdx-js/mdx` for\n[`compile`][compile] and [`run`][run].\nFor other use cases, you can also use [`evaluate`][eval], which both compiles\nand runs in one.\n\n<Note type=\"info\">\n  **Note**: MDX is not a bundler (esbuild, webpack, and Rollup are bundlers):\n  you can’t import other code from the server within the string of MDX and get a\n  nicely minified bundle out or so.\n</Note>\n\n## Next.js example\n\nSome frameworks let you write the server and client code in one file, such as\nNext.\n\n```js twoslash path=\"pages/hello.js\"\n/**\n * @import {MDXModule} from 'mdx/types.js'\n * @import {Dispatch, ReactElement, SetStateAction} from 'react'\n */\n\nimport {compile, run} from '@mdx-js/mdx'\nimport {Fragment, useEffect, useState} from 'react'\nimport * as runtime from 'react/jsx-runtime'\n\n/**\n * @param {{code: string}} props\n * @returns {ReactElement}\n */\nexport default function Page({code}) {\n  /** @type {[MDXModule | undefined, Dispatch<SetStateAction<MDXModule | undefined>>]} */\n  const [mdxModule, setMdxModule] = useState()\n  const Content = mdxModule ? mdxModule.default : Fragment\n\n  useEffect(\n    function () {\n      ;(async function () {\n        setMdxModule(await run(code, {...runtime, baseUrl: import.meta.url}))\n      })()\n    },\n    [code]\n  )\n\n  return <Content />\n}\n\nexport async function getStaticProps() {\n  const code = String(\n    await compile('# hi', {\n      outputFormat: 'function-body'\n      /* …otherOptions */\n    })\n  )\n  return {props: {code}}\n}\n```\n\n[compile]: /packages/mdx/#compilefile-options\n\n[eval]: /packages/mdx/#evaluatefile-options\n\n[mdx-bundler]: https://github.com/kentcdodds/mdx-bundler\n\n[next-mdx-remote]: https://github.com/hashicorp/next-mdx-remote\n\n[run]: /packages/mdx/#runcode-options\n\n[use]: /docs/using-mdx/\n"
  },
  {
    "path": "docs/guides/syntax-highlighting.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2021-10-06')\n}\nexport const navSortSelf = 4\n\n# Syntax highlighting\n\nThis guide explores how to apply syntax highlighting to code\nblocks. {/* more */}\nMDX supports standard markdown syntax ([CommonMark][]).\nIt does not apply syntax highlighting to code blocks by default.\n\nThere are two ways to accomplish syntax highlighting: at compile time or at\nruntime.\nDoing it at compile time means the effort is spent upfront so that readers will\nhave a fast experience as no extra code is sent to them (syntax highlighting\nneeds a *lot* of code to work).\nDoing it at runtime gives more flexibility by moving the work to the client.\nThis can result in a slow experience for readers though.\nIt also depends on what framework you use (as in it’s specific to React, Preact,\nVue, etc.)\n\n## Syntax highlighting at compile time\n\nUse for example [`rehype-starry-night`][rehype-starry-night] (`starry-night`),\n[`rehype-highlight`][rehype-highlight] (`lowlight`, `highlight.js`),\nor [`@mapbox/rehype-prism`][rehype-prism] (`refractor`, `prism`)\nby doing something like this:\n\n```js twoslash path=\"example.js\"\n/// <reference types=\"node\" />\n// ---cut---\nimport {compile} from '@mdx-js/mdx'\nimport rehypeStarryNight from 'rehype-starry-night'\n\nconst code = `~~~js\nconsole.log(1)\n~~~`\n\nconsole.log(\n  String(await compile(code, {rehypePlugins: [rehypeStarryNight]}))\n)\n```\n\n<details>\n  <summary>Expand equivalent JSX</summary>\n\n  ```jsx path=\"output.jsx\"\n  <>\n    <pre>\n      <code className=\"language-js\">\n        <span className=\"pl-en\">console</span>.<span className=\"pl-c1\">log</span>(<span className=\"pl-c1\">1</span>)\n      </code>\n    </pre>\n  </>\n  ```\n</details>\n\n<Note type=\"important\">\n  **Important**: you must likely also include CSS somewhere on the page.\n  See the documentation of the plugin you’re using for more information.\n</Note>\n\n## Syntax highlighting at run time\n\nUse for example\n[`react-syntax-highlighter`][react-syntax-highlighter],\nby doing something like this:\n\n{/* Note: `react-syntax-highlighter` doesn’t seem actively maintained so no twoslash to check this example. */}\n\n```jsx path=\"example.jsx\"\nimport SyntaxHighlighter from 'react-syntax-highlighter'\nimport Post from './example.mdx' // Assumes an integration is used to compile MDX -> JS.\n\nconsole.log(<Post components={{code}} />)\n\nfunction code({className, ...properties}) {\n  const match = /language-(\\w+)/.exec(className || '')\n  return match\n    ? <SyntaxHighlighter language={match[1]} PreTag=\"div\" {...properties} />\n    : <code className={className} {...properties} />\n}\n```\n\n<details>\n  <summary>Expand equivalent JSX</summary>\n\n  ```jsx path=\"output.jsx\"\n  <>\n    <pre>\n      <div\n        className=\"language-js\"\n        style={{\n          background: '#F0F0F0',\n          color: '#444',\n          display: 'block',\n          overflowX: 'auto',\n          padding: '0.5em'\n        }}\n      >\n        <code style={{whiteSpace: 'pre'}}>\n          <span>console.</span>\n          <span style={{color: '#397300'}}>log</span>\n          <span>(</span>\n          <span style={{color: '#880000'}}>1</span>\n          <span>)</span>\n        </code>\n      </div>\n    </pre>\n  </>\n  ```\n</details>\n\n## Syntax highlighting with the `meta` field\n\nMarkdown supports a meta string for code:\n\n````mdx path=\"example.mdx\"\n```js filename=\"index.js\"\nconsole.log(1)\n```\n````\n\nThe `meta` part is everything after the language (in this case, `js`).\nThis is a *hidden* part of markdown: it’s normally ignored.\nBut as the above example shows, it’s a useful place to put some extra fields.\n\n`@mdx-js/mdx` doesn’t know whether you’re handling code as a component or what\nthe format of that meta string is, so it defaults to how markdown handles it:\n`meta` is ignored.\n\nBut what if you want to access `meta` at runtime?\nThat’s exactly what the rehype plugin\n[`rehype-mdx-code-props`][rehype-mdx-code-props] does.\nIt lets you type JSX attributes in the `meta` part which you can access by\nwith a component for `pre`.\n\nThat plugin, like all rehype plugins, can be passed as\n[`rehypePlugins` in `ProcessorOptions`][processor-options].\nMore info on plugins is available in [§ Extending MDX][extend]\n\n[commonmark]: https://spec.commonmark.org/current/\n\n[extend]: /docs/extending-mdx/\n\n[processor-options]: /packages/mdx/#processoroptions\n\n[react-syntax-highlighter]: https://github.com/react-syntax-highlighter/react-syntax-highlighter\n\n[rehype-highlight]: https://github.com/rehypejs/rehype-highlight\n\n[rehype-mdx-code-props]: https://github.com/remcohaszing/rehype-mdx-code-props\n\n[rehype-prism]: https://github.com/mapbox/rehype-prism\n\n[rehype-starry-night]: https://github.com/rehypejs/rehype-starry-night\n"
  },
  {
    "path": "docs/index.mdx",
    "content": "import {Chart} from './_component/snowfall.jsx'\n\nexport {Home as default} from './_component/home.jsx'\nexport const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'},\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2017-12-23'),\n  schemaOrg: {\n    \"@context\": \"https://schema.org\",\n    \"@type\": \"SoftwareApplication\",\n    \"additionalType\": \"ComputerLanguage\",\n    \"applicationCategory\": \"DeveloperApplication\",\n    \"description\": \"an authorable format for writing JSX in markdown documents\",\n    \"name\": \"MDX\",\n    \"offers\": {\n      \"@type\": \"Offer\",\n      \"price\": \"0.00\",\n      \"priceCurrency\": \"USD\"\n    },\n    \"operatingSystem\": \"Windows, MacOS, Linux\",\n    \"sameAs\": [\n      \"https://www.wikidata.org/wiki/Q95971592\",\n      \"https://www.wikidata.org/wiki/Q27966906\",\n      \"https://www.wikidata.org/wiki/Q95961071\",\n      \"https://en.wikipedia.org/wiki/MDX_(markup_language)\",\n      \"https://github.com/mdx-js/mdx\"\n    ],\n    \"url\": \"https://mdxjs.com\"\n  }\n}\nexport const year = 2023\n\n{/* lint disable heading-style */}\n\nMarkdown for the\\\n**component era**\n=================\n\nMDX lets you use JSX in your markdown content.\nYou can import components, such as interactive charts or alerts, and embed them\nwithin your content.\nThis makes writing long-form content with components a blast. {/* more */}\n🚀\n[Continue reading »][what]\n\n<div className=\"card big\">\n  ## New: MDX 3!\n\n  A small major this time, nothing big, which is also nice sometimes!\n  This mainly drops support for old Node (use 16 or later), adds modern ES2024\n  support in MDX, supports `await` in MDX (if your framework does too), and\n  removes several deprecated options.\n\n  [Continue reading »][v3]\n</div>\n\n## What does MDX do?\n\n<div className=\"big-columns\">\n  <div>\n    You write markdown with embedded components through JSX:\n\n    ```mdx path=\"example.mdx\"\n    import {Chart} from './snowfall.js'\n    export const year = 2023\n\n    # Last year’s snowfall\n\n    In {year}, the snowfall was above average.\n    It was followed by a warm spring which caused\n    flood conditions in many of the nearby rivers.\n\n    <Chart color=\"#fcb32c\" year={year} />\n    ```\n  </div>\n\n  <div>\n    It gets compiled to JavaScript that you can use in any framework that\n    supports JSX:\n\n    {/* lint disable no-multiple-toplevel-headings */}\n\n    <div className=\"home-preview\">\n      # Last year’s snowfall\n\n      In {year}, the snowfall was above average.\n      It was followed by a warm spring which caused flood conditions in many of\n      the nearby rivers.\n\n      <Chart color=\"#fcb32c\" year={year} />\n    </div>\n\n    {/* lint enable no-multiple-toplevel-headings */}\n  </div>\n</div>\n\nWe made an interactive playground where you can try MDX out and see what it\nturns into.\n[Play »][playground]\n\n## Get started\n\nThere are integrations for most bundlers, frameworks, and editors.\nWhether you build with Docusaurus, Next.js, or Vite.\nYou prefer Rollup, esbuild, or webpack.\nYou’re using React, Preact, or Vue.\n[Get started »][getting-started]\n\n## MDX in short\n\n<div className=\"emoji-list\">\n  * ❤️ **Powerful**: MDX blends markdown and JSX syntax to fit perfectly in\n    JSX-based projects\n  * 💻 **Everything is a component**: Use existing components in your\n    MDX and import other MDX files as components\n  * 🔧 **Customizable**: Decide which component is rendered for each markdown\n    construct (`{h1: MyHeading}`)\n  * 📚 **Markdown-based**: The simplicity and elegance of markdown remains,\n    you use JSX only when you want to\n  * 🔥 **Blazingly blazing fast**: MDX has no runtime, all compilation occurs\n    during the build stage\n</div>\n\n> lol mdx is so good\n>\n> — **@dan\\_abramov**\n\n[getting-started]: /docs/getting-started/\n\n[playground]: /playground/\n\n[v3]: /blog/v3/\n\n[what]: /docs/what-is-mdx/\n"
  },
  {
    "path": "docs/migrating/v1.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2019-04-04')\n}\nexport const navExclude = true\n\n<Note type=\"legacy\">\n  **Note**: This is an old migration guide.\n  See [§ Migrating from v1 to v2](/migrating/v2/).\n  The below is kept as is for historical purposes.\n</Note>\n\n# Migrating from v0 to v1\n\nUnfortunately, we’ve had to introduce a few breaking changes, so we’ve written a\nmigration guide.\nIn order to ensure as seamless of an upgrade as possible we plan on supporting\nv0 for the next 12 months so there’s not a huge rush to update (though we’d\nlove for you to ASAP) 📆.\n\n## ⚠️ Breaking changes\n\n* [🚨 `@mdx-js/tag` is replaced by `@mdx-js/react` and an `mdx`\n  pragma](#pragma) 🚨\n* [MDXProvider now merges component contexts when nested](#mdxprovider)\n* [React support now requires `>= 16.8` in `@mdx-js/react`](#react)\n\n## Pragma\n\nFor v1 you need to remove `@mdx-js/tag` and replace it with `@mdx-js/react`:\n\n```sh\nyarn remove @mdx-js/tag\nyarn add @mdx-js/react\n```\n\n### What’s different?\n\nThe MDXTag implementation has been removed with a custom pragma implementation\ninspired by\n[Emotion](https://emotion.sh/docs/css-prop#jsx-pragma).\nThis ensures that transpiled JSX is more readable and that JSX blocks use the\nsame component as its markdown counterpart.\nIt also allows MDXProvider to provide global component scope like a `Youtube`\ncomponent.\n\nThe pragma implementation will also cause JSX HTML elements to be rendered with\nthe component mapping passed to MDXProvider.\nSo, the following will result in two identically rendered `h1`s:\n\n```mdx\n# Hello, world!\n\n<h1>Hello, world!</h1>\n```\n\n[See the blog post for further reading](/blog/custom-pragma/)\n\n## MDXProvider\n\nThis shouldn’t affect most usecases, however if you’re nesting component\ncontexts and rely on them not being merged you will have to use the functional\nform which allows you to customize the merge.\nBy ignoring outer context components and returning a new component mapping, you\nwill restore the old behavior:\n\n```tsx\n<MDXProvider components={components}>\n  <MDXProvider components={outerComponents => newComponents}>\n    {children}\n  </MDXProvider>\n</MDXProvider>\n```\n\n## React\n\nBefore upgrading to `@mdx-js/mdx@1`, update your website/application to\n`react@16.8 react-dom@16.8` and ensure it works as expected.\nThen upgrade to v1.\n"
  },
  {
    "path": "docs/migrating/v2.mdx",
    "content": "import {Note} from '../_component/note.jsx'\n\nexport const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2022-02-01')\n}\nexport const navExclude = true\n\n<Note type=\"legacy\">\n  **Note**: This is an old migration guide.\n  See [§ Migrating from v2 to v3](/migrating/v3/).\n  The below is kept as is for historical purposes.\n</Note>\n\n# Migrating from v1 to v2\n\n## Contents\n\n* [ESM](#esm)\n* [Update `@mdx-js/*` packages](#update-mdx-js-packages)\n  * [`@mdx-js/loader`](#mdx-jsloader)\n  * [`@mdx-js/react`, `@mdx-js/preact`, `@mdx-js/vue`](#mdx-jsreact-mdx-jspreact-mdx-jsvue)\n  * [`@mdx-js/mdx`](#mdx-jsmdx)\n  * [`@mdx-js/runtime`](#mdx-jsruntime)\n  * [`remark-mdx`](#remark-mdx)\n  * [`@mdx-js/vue-loader`](#mdx-jsvue-loader)\n  * [`@mdx-js/parcel-plugin-mdx`](#mdx-jsparcel-plugin-mdx)\n  * [Other packages](#other-packages)\n* [Update MDX files](#update-mdx-files)\n  * [JSX](#jsx)\n  * [Expressions](#expressions)\n  * [ESM](#esm-1)\n  * [Markdown](#markdown)\n  * [GFM](#gfm)\n* [Update MDX content](#update-mdx-content)\n\n## ESM\n\nWhen upgrading to version 2, you might run into import problems.\nOur packages are now ESM only.\nYou have to load them with `import foo from 'foo'` instead of\n`const foo = require('foo')`.\nPlease see [¶ ESM in § Troubleshooting MDX][trouble-esm].\n\n## Update `@mdx-js/*` packages\n\nYou need to make changes when upgrading some `mdx-js/*` packages.\nIn this section we will discuss the needed changes for each package.\nIf you’re experiencing problems, please see [§ Troubleshooting MDX][trouble]\nfor common errors and how to solve them.\n\n### `@mdx-js/loader`\n\nTo update our webpack loader `@mdx-js/loader`, please first update to recent\nversions of webpack and React.\nThen make sure ESM is supported.\n[ESM is explained above][esm].\nIf you’re having trouble using ESM in your webpack config, here’s an example\nthat works with our previous `@mdx-js/loader` (`1.6.22`):\n\n<details>\n  <summary>Expand example of a `webpack.config.js` in ESM</summary>\n\n  ```tsx path=\"webpack.config.js\"\n  import {fileURLToPath} from 'node:url'\n  import webpack from 'webpack'\n\n  const config = {\n    context: fileURLToPath(new URL('src/', import.meta.url)),\n    entry: ['./index.js'],\n    mode: 'none',\n    module: {\n      rules: [\n        {\n          test: /\\.mdx?$/,\n          use: [\n            {\n              loader: 'babel-loader',\n              options: {presets: ['@babel/preset-env', '@babel/preset-react']}\n            },\n            {\n              loader: '@mdx-js/loader',\n              /** @type {import('@mdx-js/loader').Options} */\n              options: {}\n            }\n          ]\n        }\n      ]\n    },\n    output: {\n      filename: 'bundle.js',\n      path: fileURLToPath(new URL('dest/', import.meta.url))\n    }\n  };\n\n  export default config\n  ```\n</details>\n\nThen install MDX version 2:\n\n```sh\nnpm install @mdx-js/loader @mdx-js/react remark-gfm\n```\n\nYou can update your code as follows:\n\n<div className=\"big-columns\">\n  <div>\n    Before:\n\n    ```tsx path=\"webpack.config.js\"\n    // …\n    {\n      test: /\\.mdx?$/,\n      use: [\n        {\n          loader: 'babel-loader',\n          options: {\n            presets: [\n              '@babel/preset-env',\n              '@babel/preset-react'\n            ]\n          }\n        },\n        {\n          loader: '@mdx-js/loader',\n          /** @type {import('@mdx-js/loader').Options} */\n          options: {}\n        }\n      ]\n    }\n    // …\n    ```\n  </div>\n\n  <div>\n    After:\n\n    ```tsx path=\"webpack.config.js\"\n    import remarkGfm from 'remark-gfm'\n\n    // …\n    {\n      test: /\\.mdx?$/,\n      use: [\n        {\n          loader: 'babel-loader',\n          options: {\n            presets: [\n              '@babel/preset-env'\n            ]\n          }\n        },\n        {\n          loader: '@mdx-js/loader',\n          /** @type {import('@mdx-js/loader').Options} */\n          options: {\n            providerImportSource: '@mdx-js/react',\n            remarkPlugins: [remarkGfm]\n          }\n        }\n      ]\n    }\n    // …\n    ```\n  </div>\n</div>\n\nThe above changes get MDX 2 close to how MDX 1 worked.\nYou can make it simpler:\n\n* [`babel-loader`][babel-loader] is optional.\n  It compiles modern JavaScript to JavaScript your users support.\n  If you don’t need that you can remove it before `@mdx-js/loader`\n* [`remark-gfm`][remark-gfm] is optional.\n  It adds support for autolink literals, footnotes, strikethrough, tables, and\n  task lists.\n  If you don’t want them, you can uninstall it, remove the import, and remove\n  it from `options.remarkPlugins`.\n  More info in [our guide on GFM][guide-gfm]\n* [`@mdx-js/react`][mdx-react] is optional.\n  It adds support for context based components passing.\n  If you don’t need that, you can uninstall it and remove\n  `options.providerImportSource`.\n  More info in [¶ MDX provider in § Using MDX][mdx-provider]\n\n`@mdx-js/loader` now supports Preact and other JSX runtimes through\nconfiguration.\nUsing Preact as an example:\n\n```tsx path=\"webpack.config.js\"\n// …\n{\n  loader: '@mdx-js/loader',\n  /** @type {import('@mdx-js/loader').Options} */\n  options: {\n    jsxImportSource: 'preact',\n    // Optional: either remove the following line or install `@mdx-js/preact`.\n    providerImportSource: '@mdx-js/preact'\n  }\n}\n// …\n```\n\nFor more information, please see [§ API in `@mdx-js/loader`][loader-api].\n\n###### Changes\n\nThe options accepted by the loader changed:\n\n* `renderer` is replaced by `jsxImportSource`, `providerImportSource`, and\n  others options.\n  More info in [§ API in `@mdx-js/mdx`][mdx-api]\n* Other options were undocumented but passed to `@mdx-js/mdx`.\n  See `@mdx-js/mdx` below if needed\n\nFor more information, please see [§ API in `@mdx-js/loader`][loader-api].\n\n### `@mdx-js/react`, `@mdx-js/preact`, `@mdx-js/vue`\n\nTo update our framework integrations, please first update to recent versions of\nReact, Preact, or Vue 3.\nThen make sure ESM is supported.\n[ESM is explained above][esm].\nThen install version 2:\n\n```sh\nnpm install @mdx-js/react # Change `react` to `preact` or `vue` if needed\n```\n\nNote that these packages now only add support for context based components\npassing.\nIf you don’t need that, you can uninstall them.\nMore info in [¶ MDX provider in § Using MDX][mdx-provider].\n\n###### Changes\n\nThe interface of changed slightly:\n\n* The named export `mdx`, which was a `createElement` function, is removed.\n  You can use your framework’s functions instead: `React.createElement`,\n  `h` from `preact`, etc.\n\n### `@mdx-js/mdx`\n\nTo update our core compiler `@mdx-js/mdx`, first make sure ESM is supported.\n[ESM is explained above][esm].\nThen install version 2:\n\n```sh\nnpm install @mdx-js/mdx @mdx-js/react remark-gfm\n```\n\nYou can update your code as follows:\n\n<div className=\"big-columns\">\n  <div>\n    Before:\n\n    ```tsx path=\"old.js\"\n    import mdx from '@mdx-js/mdx'\n\n    const result = await mdx('# hi')\n\n    console.log(result)\n    ```\n  </div>\n\n  <div>\n    After:\n\n    ```tsx path=\"new.js\"\n    import {compile} from '@mdx-js/mdx'\n    import remarkGfm from 'remark-gfm'\n\n    const result = await compile('# hi', {\n      providerImportSource: '@mdx-js/react',\n      remarkPlugins: [remarkGfm]\n    })\n\n    console.log(String(result))\n    ```\n  </div>\n</div>\n\nThe above changes get MDX 2 close to how MDX 1 worked.\nYou can make it simpler:\n\n* [`remark-gfm`][remark-gfm] is optional.\n  It adds support for autolink literals, footnotes, strikethrough, tables, and\n  task lists.\n  If you don’t want them, you can uninstall it, remove the import, and remove\n  it from `options.remarkPlugins`.\n  More info in [our guide on GFM][guide-gfm]\n* [`@mdx-js/react`][mdx-react] is optional.\n  It adds support for context based components passing.\n  If you don’t need that, you can uninstall it and remove\n  `options.providerImportSource`.\n  More info in [¶ MDX provider in § Using MDX][mdx-provider]\n\n`@mdx-js/mdx` now supports Preact and other JSX runtimes through configuration.\nUsing Preact as an example:\n\n```tsx path=\"new-preact.js\"\nimport {compile} from '@mdx-js/mdx'\n\nconst result = await compile('# hi', {jsxImportSource: 'preact'})\n```\n\nFor more information, please see [§ API in `@mdx-js/mdx`][mdx-api]\n\n###### Changes\n\nThe interface of `@mdx-js/mdx` changed:\n\n* The default export is replaced by the named export [`compile`][mdx-compile]\n* The named export `sync` is replaced by [`compileSync`][mdx-compilesync]\n* The named export `createCompiler` is replaced by\n  [`createProcessor`][mdx-createprocessor]\n* The named export `createMdxAstCompiler` is removed, use `remark` with\n  `remark-mdx` instead\n* The return value of `compile`, `compileSync` are now [VFile][]s instead of\n  strings\n* There are new exports [`evaluate`][mdx-evaluate],\n  [`evaluateSync`][mdx-evaluatesync] to eval (compile and run) MDX\n\nOptions in version 1 were undocumented.\nIf you used them:\n\n* `filepath` is replaced by accepting a VFile or compatible object as the\n  first argument `file`\n* `compilers` is replaced by `recmaPlugins`\n* `hastPlugins` is replaced by `rehypePlugins`\n* `mdPlugins` is replaced by `options.remarkPlugins`\n* `skipExport` is removed, [`evaluate`][mdx-evaluate] can do this\n  automatically\n* `wrapExport` is removed, use a custom recma plugin instead\n* There are many new options to support different JSX runtimes, non-React JSX,\n  compile JSX away, source maps, normal markdown, and otherwise change how MDX\n  is compiled\n\nFor more information, please see [§ API in `@mdx-js/mdx`][mdx-api].\n\n### `@mdx-js/runtime`\n\nWe’ve deprecated `@mdx-js/runtime`.\nOur core compiler `@mdx-js/mdx` can now do the same and more.\nTo update, first make sure ESM is supported.\n[ESM is explained above][esm].\nPlease also make sure you are using a recent version of React.\nThen uninstall `@mdx-js/runtime` and install `@mdx-js/mdx` and `@mdx-js/react`:\n\n```sh\nnpm uninstall @mdx-js/runtime\nnpm install @mdx-js/mdx @mdx-js/react\n```\n\nYou can update your code as follows:\n\n<div className=\"big-columns\">\n  <div>\n    Before:\n\n    ```tsx path=\"old.js\"\n    import MDX from '@mdx-js/runtime'\n\n    const components = {/* … */}\n    const value = '# hi'\n\n    export default function () {\n      return <MDX components={components}>\n        {value}\n      </MDX>\n    }\n    ```\n  </div>\n\n  <div>\n    After:\n\n    ```tsx path=\"new.js\"\n    import * as runtime from 'react/jsx-runtime'\n    import * as provider from '@mdx-js/react'\n    import {evaluate} from '@mdx-js/mdx'\n\n    const components = {/* … */}\n    const value = '# hi'\n    const {default: Content} = await evaluate(value, {...provider, ...runtime})\n\n    export default function () {\n      return <Content components={components} />\n    }\n    ```\n  </div>\n</div>\n\nThe above changes get MDX 2 close to how MDX 1 worked.\nYou can make it simpler:\n\n* [`@mdx-js/react`][mdx-react] is optional.\n  It adds support for context based components passing.\n  If you don’t need that, you can uninstall it and remove\n  `options.providerImportSource`.\n  More info in [¶ MDX provider in § Using MDX][mdx-provider]\n\n`@mdx-js/mdx` now supports Preact and other JSX runtimes through configuration.\nUsing Emotion as an example:\n\n```tsx path=\"new-emotion.js\"\n// …\nimport * as runtime from '@emotion/react/jsx-runtime'\n// …\n```\n\nFor more information, please see [`evaluate` in `@mdx-js/mdx`][mdx-evaluate].\n\n###### Changes\n\n* The package `@mdx-js/runtime` is replaced by [`evaluate`][mdx-evaluate]\n  from `@mdx-js/mdx`\n* `evaluate` supports any JSX runtime and providers are optional\n* `evaluate` yields an `MDXContent` component just like how importing\n  and MDX file works\n* `evaluate` supports imports and exports inside evaluated MDX\n\nFor more information, please see [`evaluate` in `@mdx-js/mdx`][mdx-evaluate].\n\n### `remark-mdx`\n\nTo update our remark plugin `remark-mdx`, first make sure ESM is supported.\n[ESM is explained above][esm].\nThen install version 2:\n\n```sh\nnpm install remark-mdx\n```\n\nFor more information, please see [§ Use in `remark-mdx`][remark-mdx-use].\n\n### `@mdx-js/vue-loader`\n\nWe’ve deprecated `@mdx-js/vue-loader`.\nOur main loader `@mdx-js/loader` can now do the same and more.\nTo update, first remove `@mdx-js/vue-loader` and upgrade to Vue 3.\nThen, see [¶ Vue in § Getting started](/docs/getting-started/#vue) on how to use\nVue with MDX.\n\n### `@mdx-js/parcel-plugin-mdx`\n\nWe’ve deprecated `@mdx-js/parcel-plugin-mdx`.\nParcel 2 has their own plugin.\nTo update, first remove `@mdx-js/parcel-plugin-mdx` and upgrade to Parcel 2.\nThen, see [¶ Parcel in § Getting started](/docs/getting-started/#parcel) on how\nto use Parcel with MDX.\n\n### Other packages\n\nWe removed several packages doing internal work for us.\nThese packages are:\n\n* `@mdx-js/util`\n  — no longer needed internal helpers\n* `@mdx-js/test-util`\n  — no longer needed test helpers, `evaluate` can do them\n* `gatsby-theme-mdx`\n  — no longer needed website template\n* `remark-mdx-remove-imports`, `babel-plugin-extract-import-names`\n  — no longer needed transforms, our compiler handles imports\n* `remark-mdx-remove-exports`, `babel-plugin-remove-export-keywords`\n  — no longer needed transforms, our compiler handles exports\n* `babel-plugin-html-attributes-to-jsx`\n  — no longer needed transform, something similar is done by\n  [`hast-util-to-estree`](https://github.com/syntax-tree/hast-util-to-estree)\n* `babel-plugin-apply-mdx-type-props`\n  — no longer needed transform due to the new architecture\n* `create-mdx`\n  — no longer needed, we recommend to start your project with whatever other\n  integrations you prefer and *then* add MDX to it\n\n## Update MDX files\n\nNow you’ve updated our packages, you can update your MDX files.\nIn version 2, we improved the syntax of the MDX format.\nWhen upgrading, you’ll likely get errors.\nRead those error messages carefully, as they typically explain what\nhappened where and how to fix it.\nSee [§ Troubleshooting MDX][trouble] for common errors and how to solve them.\n\n### JSX\n\nLet’s kick off with a couple of things that are now possible with JSX in MDX.\nYou don’t need blank lines between JSX and markdown anymore:\n\n```mdx chrome=no\n<hgroup>\n# This is a heading now\n</hgroup>\n```\n\nYou can now indent your JSX and markdown:\n\n````mdx chrome=no\n<article>\n  <hgroup>\n    # This is a heading now, not code or plain text\n  </hgroup>\n  <section>\n    ```js\n    // if you do want code blocks, use fenced code\n    ```\n  </section>\n</article>\n````\n\nYou can use markdown “inlines” but not “blocks” inside JSX if the text and tags\nare on the same line:\n\n```mdx chrome=no\n<div># this is not a heading but *this* is emphasis</div>\n```\n\nText and tags on one line don’t produce blocks so they don’t produce `<p>`s\neither.\nOn separate lines, they do:\n\n```mdx chrome=no\n<div>\n  This is a `p`.\n</div>\n```\n\nWe differentiate using this rule (same line or not).\nNot based on semantics of elements in HTML.\nSo you *can* build incorrect HTML (which you shouldn’t):\n\n```mdx chrome=no\n<h1 className=\"main\">\n  Don’t do this: it’s a `p` in an `h1`\n</h1>\n\n<h1 className=\"main\">Do this: an `h1` with `code`</h1>\n```\n\nIt’s not possible to wrap “blocks” if text and tags are on the same line but the\ncorresponding tags are on different lines:\n\n```mdx chrome=no\nWelcome! <a href=\"about.html\">\n\nThis is home of...\n\n# The Falcons!</a>\n```\n\nThat’s because to parse markdown, we first have to divide it into “blocks”.\nSo in this case two paragraphs and a heading.\nLeaving an opening `a` tag in the first paragraph and a stray closing `a` tag in\nthe heading.\n\nWe also fixed several cases where JSX was not parsed or handled correctly or\neven crashed.\nMore on JSX in MDX is in [¶ JSX in § What is MDX?][what-jsx]\n\n### Expressions\n\nYou can now use expressions in MDX to include JavaScript.\nYou can also use them as an escape hatch if you ever *just* want strings or JSX\nrather than markdown:\n\n```mdx chrome=no\n{\n  <h1>\n    This just JSX, these *asterisks* have no meaning.\n  </h1>\n}\n\nThis is just {'`text`'}, not code.\n```\n\nMore on expressions in MDX is in\n[¶ Expressions in § What is MDX?][what-expressions]\n\n### ESM\n\nYou can more easily embed components in MDX because blank lines are allowed:\n\n{/* Note: `language` because theme in VS Code is broken. */}\n\n```mdx chrome=no\nexport function Button(props) {\n  const style = {color: 'red'}\n\n  return <button style={style} {...props} />\n}\n```\n\nWe also fixed several cases where `import` and `export` were not parsed or\nhandled correctly or even crashed.\nMore on ESM in MDX is in [¶ ESM in § What is MDX?][what-esm]\n\n### Markdown\n\nWe turned off several things that are allowed in regular markdown to make MDX\nless ambiguous.\nMore on markdown in MDX and where it differs is in\n[¶ Markdown in § What is MDX?][what-markdown]\n\n### GFM\n\nWe turned off GFM features in MDX by default.\nGFM extends CommonMark to add autolink literals, footnotes, strikethrough,\ntables, and task lists.\nIf you do want these features, you can use a plugin.\nSee [our guide on GFM][guide-gfm].\n\n## Update MDX content\n\nThe interface of the generated JavaScript from MDX changed:\n\n* Missing components now throw an error rather than render their children\n  and emit a warning to the console, which is closer to how frameworks like\n  React handle missing undefined JSX components\n* `parent.child` combos such as `ol.li`, to pass components, were removed, we\n  recommend to style your `ol`s, `ul`s, and `li`s separately\n* The special component name `inlineCode` was removed, we recommend to use\n  `pre` for the block version of code, and `code` for both the block and\n  inline versions\n* `MDXContent.isMDXContent` was removed, we recommend treating `MDXContent`\n  like any other component\n* Locally defined or imported components precede over passed components\n* We now “sandbox” components, for lack of a better name.\n  It means that when you pass a component for `h1`, it does get used for\n  `# hi` but not for `<h1>hi</h1>`\n* You can now pass and use objects of components: if you pass\n  `components={{theme}}`, where `theme` is an object with a `Box` component,\n  it can be used with: `<theme.Box>stuff</theme.Box>`\n* the values exports from an MDX file are no longer passed to layouts, you\n  can achieve the same with:\n  ```tsx\n  import * as everything from './example.mdx'\n  const {default: Content, ...exported} = everything\n  <Content {...exported} />\n  ```\n\nWe also fixed several cases where defined, imported, or passed components\nweren’t handled correctly or even crashed.\n\n***\n\nPhew.\nYou made it!\nWelcome on the MDX 2 train, it’s been a journey.\nWe know it wasn’t the easiest to migrate, we’re happy you’re still here, we’ll\ntry to make migration easier next time.\nWith our new AST, we’re able to create codemods from now on.\n\\<3\n\n[babel-loader]: https://webpack.js.org/loaders/babel-loader/\n\n[esm]: #esm\n\n[guide-gfm]: /guides/gfm/\n\n[loader-api]: /packages/loader/#api\n\n[mdx-api]: /packages/mdx/#api\n\n[mdx-compile]: /packages/mdx/#compilefile-options\n\n[mdx-compilesync]: /packages/mdx/#compilesyncfile-options\n\n[mdx-createprocessor]: /packages/mdx/#createprocessoroptions\n\n[mdx-evaluate]: /packages/mdx/#evaluatefile-options\n\n[mdx-evaluatesync]: /packages/mdx/#evaluatesyncfile-options\n\n[mdx-provider]: /docs/using-mdx/#mdx-provider\n\n[mdx-react]: /packages/react/\n\n[remark-gfm]: https://github.com/remarkjs/remark-gfm\n\n[remark-mdx-use]: /packages/remark-mdx/#use\n\n[trouble]: /docs/troubleshooting-mdx/\n\n[trouble-esm]: /docs/troubleshooting-mdx/#esm\n\n[vfile]: https://github.com/vfile/vfile\n\n[what-esm]: /docs/what-is-mdx/#esm\n\n[what-expressions]: /docs/what-is-mdx/#expressions\n\n[what-jsx]: /docs/what-is-mdx/#jsx\n\n[what-markdown]: /docs/what-is-mdx/#markdown\n"
  },
  {
    "path": "docs/migrating/v3.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2023-10-24'),\n  published: new Date('2023-10-24')\n}\nexport const navExclude = true\n\n# Migrating from v2 to v3\n\nA couple small changes this time around.\nFor most folks, updating Node.js and plugins is all that’s needed!\n\n## Contents\n\n* [Update Node.js](#update-nodejs)\n* [Update plugins](#update-plugins)\n* [Pass `baseUrl` to `evaluate`, `run`](#pass-baseurl-to-evaluate-run)\n* [Use the automatic JSX runtime](#use-the-automatic-jsx-runtime)\n* [Replace `MDXContext`, `withMDXComponents` with `useMDXComponents`](#replace-mdxcontext-withmdxcomponents-with-usemdxcomponents)\n* [Replace `@mdx-js/register` with `@mdx-js/node-loader`](#replace-mdx-jsregister-with-mdx-jsnode-loader)\n\n## Update Node.js\n\nIf you’re still on old Node, it’s time to update.\nUse at least Node 16.\n\n## Update plugins\n\nIf you use rehype and remark plugins: update.\n\nMost of them remain working between versions.\nParticularly if you use TypeScript, there was a breaking internal change in the\ntypes, which is now supported here.\nThere were also some small internal changes in how the parser works, which\naffect `remark-gfm` and `remark-math`.\n\n## Pass `baseUrl` to `evaluate`, `run`\n\nIf you use `evaluate` or `run` (or `outputFormat: 'function-body'`), you should\npass the `baseUrl` option.\nLikely set to `import.meta.url`.\n\nIf MDX content uses `export` statements, `import` expressions/statements,\nor `import.meta.url`, we compile to code that works, but it needs to know\nwhere the code runs: you need to pass where you are.\n\nYou will get a runtime error if these features are used in MDX without\n`baseUrl`.\n\nIf you passed the `useDynamicImport` option before, remove it, the behavior\nis now the default.\n\n```tsx\nimport * as runtime from 'react/jsx-runtime'\n\nconst result = await run('# hi', {...runtime, baseUrl: import.meta.url})\n```\n\n## Use the automatic JSX runtime\n\nIf you use the classic runtime, switch to the automatic runtime.\nClassic is still supported but you will now see a warning if you use the\nclassic JSX runtime.\n\nThe classic runtime can still be nice in other places, but it causes potential\nproblems in MDX.\nIf you specify `jsxRuntime: 'classic'` (and `pragma`, `pragmaFrag`,\n`pragmaImportSource`), consider switching to `automatic`.\nAll major frameworks support the automatic runtime.\nSupport for the classic runtime will likely be removed next major.\n\n## Replace `MDXContext`, `withMDXComponents` with `useMDXComponents`\n\nIf you use the deprecated symbols `MDXContext` and `withMDXComponents`, use\n`useMDXComponents` instead.\n\nReminder: you probably don’t need the context based `@mdx-js/react` or\n`@mdx-js/preact` packages.\n\n## Replace `@mdx-js/register` with `@mdx-js/node-loader`\n\nIf you use the deprecated package `@mdx-js/register`, use `@mdx-js/node-loader` instead.\n"
  },
  {
    "path": "docs/packages/index.mdx",
    "content": "{\n  /**\n   * @import {Item} from '../_component/sort.js'\n   */\n\n  /**\n   * @typedef Props\n   * @property {Item} navigationTree\n   */\n}\n\nimport assert from 'node:assert/strict'\nimport {NavigationGroup} from '../_component/nav.jsx'\n\nexport const info = {\n  author: [{name: 'MDX Contributors'}],\n  modified: new Date('2024-07-04'),\n  published: new Date('2021-11-01')\n}\nexport const navSortSelf = 3\n\n# Packages\n\nThis index lists the packages that are maintained in our monorepo.\nThey include `@mdx-js/mdx`, which is our core compiler; `remark-mdx`, which is\nthe remark plugin to support the MDX syntax; and several integrations with\nbundlers and frontend frameworks.\n\n{\n  (function () {\n    const navigationTree = props.navigationTree\n    const category = navigationTree.children.find(function (item) {\n      return item.name === '/packages/'\n    })\n    assert(category)\n\n    return (\n      <nav>\n        <NavigationGroup items={category.children} includeDescription />\n      </nav>\n    )\n  })()\n}\n"
  },
  {
    "path": "docs/playground.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'},\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2023-12-24'),\n  published: new Date('2021-09-13')\n}\nexport const navSortSelf = 5\n\n# Playground\n\nHere you can play with the MDX format.\nWrite some MDX to find out what it turns into. {/* more */}\nYou can see the rendered result, the generated code, and the intermediary\nASTs.\nThis can be helpful for debugging or exploring.\nTo read about how the MDX format works, we recommend that you start with\n[§ What is MDX][what].\n\n<div className=\"full-bleed\">\n  <div id=\"js-editor\" />\n</div>\n\n[what]: /docs/what-is-mdx/\n"
  },
  {
    "path": "docs/table-of-components.mdx",
    "content": "export const info = {\n  author: [\n    {github: 'johno', name: 'John Otander'},\n    {github: 'wooorm', name: 'Titus Wormer'}\n  ],\n  modified: new Date('2025-01-27'),\n  published: new Date('2020-03-11')\n}\nexport const navSortSelf = 4\n\n# Components\n\nA great thing about MDX is that you can write markdown and specify a component\nto be used instead of an HTML element. {/* more */}\nThe following table lists those HTML elements that can be overwritten,\nthe needed markdown,\nand what the normal JSX equivalent would be.\nBut, taking the first row for `a` as an example, you can replace that hyperlink\nwith `<FancyLink>` by doing:\n\n```tsx\nimport Readme from './readme.md' // Assumes an integration is used to compile MDX -> JS.\nimport {FancyLink} from './components/fancy-link.js'\n\n<Readme components={{a: FancyLink}} />\n```\n\nMore information on how to use markdown can be found in [CommonMark][].\n\n<div className=\"full-bleed\">\n  <table>\n    <thead>\n      <tr>\n        <th scope=\"col\">Name</th>\n        <th scope=\"col\">Markdown syntax</th>\n        <th scope=\"col\">Equivalent JSX</th>\n      </tr>\n    </thead>\n\n    <tbody>\n      <tr>\n        <th scope=\"row\">`a`</th>\n\n        <td>\n          ```mdx chrome=no\n          [MDX](https://mdxjs.com \"title\")\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p><a href=\"https://mdxjs.com\" title=\"title\">MDX</a></p>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`blockquote`</th>\n\n        <td>\n          ```mdx chrome=no\n          > A greater than…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <blockquote>\n              <p>A greater than…</p>\n            </blockquote>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`br`</th>\n\n        <td>\n          ```mdx chrome=no\n          A backslash\\\n          before a line break…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p>\n              A backslash<br />\n              before a line break…\n            </p>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`code`</th>\n\n        <td>\n          ````mdx chrome=no\n          Some `backticks` for inline.\n\n          ```javascript\n          backtick.fences('for blocks')\n          ```\n          ````\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p>\n              Some <code>backticks</code> for inline.\n            </p>\n            <pre><code className=\"language-javascript\">backtick.fences('for blocks')\n            </code></pre>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`em`</th>\n\n        <td>\n          ```mdx chrome=no\n          Some *asterisks* for emphasis.\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p>Some <em>asterisks</em> for emphasis.</p>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`h1`</th>\n\n        <td>\n          ```mdx chrome=no\n          # One number sign…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <h1>One number sign…</h1>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`h2`</th>\n\n        <td>\n          ```mdx chrome=no\n          ## Two number signs…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <h2>Two number signs…</h2>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`h3`</th>\n\n        <td>\n          ```mdx chrome=no\n          ### Three number signs…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <h3>Three number signs…</h3>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`h4`</th>\n\n        <td>\n          ```mdx chrome=no\n          #### Four number signs…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <h4>Four number signs…</h4>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`h5`</th>\n\n        <td>\n          ```mdx chrome=no\n          ##### Five number signs…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <h5>Five number signs…</h5>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`h6`</th>\n\n        <td>\n          ```mdx chrome=no\n          ###### Six number signs…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <h6>Six number signs…</h6>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`hr`</th>\n\n        <td>\n          ```mdx chrome=no\n          Three asterisks for a thematic break:\n\n          ***\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p>Three asterisks for a thematic break:</p>\n            <hr />\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`img`</th>\n\n        <td>\n          ```mdx chrome=no\n          ![Alt text](/logo.png \"title\")\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p><img src=\"/logo.png\" alt=\"Alt text\" title=\"title\" /></p>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`li`</th>\n\n        <td>\n          ```mdx chrome=no\n          * asterisks for unordered items\n\n          1. decimals and a dot for ordered items\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <ul>\n              <li>asterisks for unordered items</li>\n            </ul>\n            <ol>\n              <li>decimals and a dot for ordered items</li>\n            </ol>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`ol`</th>\n\n        <td>\n          ```mdx chrome=no\n          1. decimals and a dot for ordered\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <ol>\n              <li>decimals and a dot for ordered</li>\n            </ol>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`p`</th>\n\n        <td>\n          ```mdx chrome=no\n          Just some text…\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p>Just some text…</p>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`pre`</th>\n\n        <td>\n          ````mdx chrome=no\n          ```javascript\n          backtick.fences('for blocks')\n          ```\n          ````\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <pre><code className=\"language-javascript\">backtick.fences('for blocks')\n            </code></pre>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`strong`</th>\n\n        <td>\n          ```mdx chrome=no\n          Two **asterisks** for strong.\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <p>Two <strong>asterisks</strong> for strong.</p>\n          </>\n          ```\n        </td>\n      </tr>\n\n      <tr>\n        <th scope=\"row\">`ul`</th>\n\n        <td>\n          ```mdx chrome=no\n          * asterisks for unordered\n          ```\n        </td>\n\n        <td>\n          ```tsx chrome=no\n          <>\n            <ul>\n              <li>asterisks for unordered</li>\n            </ul>\n          </>\n          ```\n        </td>\n      </tr>\n    </tbody>\n  </table>\n</div>\n\nThe components you can overwrite use their standard HTML names.\nNormally, in markdown, those names are: `a`, `blockquote`, `br`, `code`, `em`,\n`h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `hr`, `img`, `li`, `ol`, `p`, `pre`,\n`strong`, and `ul`.\nWith [`remark-gfm`][gfm] ([see guide][guide-gfm]), you can also use: `del`,\n`input`, `section`, `sup`, `table`, `tbody`, `td`, `th`, `thead`, and `tr`.\nOther remark plugins that add support for new constructs and advertise that they\nwork with rehype, will also work with MDX.\n\nMore information on components is available in\n[¶ Components in § Using MDX][components].\n\n[commonmark]: https://spec.commonmark.org/current/\n\n[components]: /docs/using-mdx/#components\n\n[gfm]: https://github.com/remarkjs/remark-gfm\n\n[guide-gfm]: /guides/gfm/\n"
  },
  {
    "path": "license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Compositor and Vercel, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"private\": true,\n  \"name\": \"monorepo\",\n  \"license\": \"MIT\",\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": \"mdx-js/mdx\",\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"type\": \"module\",\n  \"workspaces\": [\n    \"packages/remark-mdx/\",\n    \"packages/mdx/\",\n    \"packages/react/\",\n    \"packages/preact/\",\n    \"packages/vue/\",\n    \"packages/esbuild/\",\n    \"packages/loader/\",\n    \"packages/node-loader/\",\n    \"packages/rollup/\"\n  ],\n  \"#\": \"note: `lz-string` is included because `@typescript/vfs` (through `twoslash`) types use it w/o marking it as a dep\",\n  \"overrides\": {\n    \"@types/react\": \"^19.0.0\",\n    \"react\": \"^19.0.0\",\n    \"react-dom\": \"^19.0.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/types\": \"^7.0.0\",\n    \"@docsearch/css\": \"^3.0.0\",\n    \"@docsearch/js\": \"^3.0.0\",\n    \"@floating-ui/dom\": \"^1.0.0\",\n    \"@next/mdx\": \"^15.0.0\",\n    \"@rollup/plugin-babel\": \"^6.0.0\",\n    \"@sparticuz/chromium\": \"^138.0.0\",\n    \"@types/babel__core\": \"^7.0.0\",\n    \"@types/dlv\": \"^1.0.0\",\n    \"@types/mdx\": \"^2.0.0\",\n    \"@types/react\": \"^19.0.0\",\n    \"@types/react-dom\": \"^19.0.0\",\n    \"@types/ungap__structured-clone\": \"^1.0.0\",\n    \"@ungap/structured-clone\": \"^1.0.0\",\n    \"@vitejs/plugin-react\": \"^5.0.0\",\n    \"@vue/server-renderer\": \"^3.0.0\",\n    \"@wooorm/starry-night\": \"^3.0.0\",\n    \"acorn\": \"^8.0.0\",\n    \"ap-style-title-case\": \"^2.0.0\",\n    \"autoprefixer\": \"^10.0.0\",\n    \"bun-types\": \"^1.0.0\",\n    \"c8\": \"^10.0.0\",\n    \"copy-to-clipboard\": \"^3.0.0\",\n    \"cssnano\": \"^7.0.0\",\n    \"devlop\": \"^1.0.0\",\n    \"dlv\": \"^1.0.0\",\n    \"esbuild\": \"^0.25.0\",\n    \"eslint-config-xo-react\": \"^0.28.0\",\n    \"eslint-plugin-es\": \"^4.0.0\",\n    \"eslint-plugin-react\": \"^7.0.0\",\n    \"eslint-plugin-react-hooks\": \"^5.0.0\",\n    \"estree-to-babel\": \"^11.0.0\",\n    \"estree-util-scope\": \"^1.0.0\",\n    \"estree-util-value-to-estree\": \"^3.0.0\",\n    \"estree-walker\": \"^3.0.0\",\n    \"globby\": \"^14.0.0\",\n    \"hast-util-from-html\": \"^2.0.0\",\n    \"hast-util-sanitize\": \"^5.0.0\",\n    \"hast-util-select\": \"^6.0.0\",\n    \"hast-util-to-html\": \"^9.0.0\",\n    \"hast-util-to-jsx-runtime\": \"^2.0.0\",\n    \"hast-util-to-text\": \"^4.0.0\",\n    \"hastscript\": \"^9.0.0\",\n    \"ink\": \"^6.0.0\",\n    \"lz-string\": \"^1.0.0\",\n    \"mdxlint\": \"^1.0.0\",\n    \"p-all\": \"^5.0.0\",\n    \"postcss\": \"^8.0.0\",\n    \"postcss-cli\": \"^11.0.0\",\n    \"preact\": \"^10.0.0\",\n    \"preact-render-to-string\": \"^6.0.0\",\n    \"prettier\": \"^3.0.0\",\n    \"puppeteer\": \"^24.0.0\",\n    \"react\": \"^19.0.0\",\n    \"react-dom\": \"^19.0.0\",\n    \"react-error-boundary\": \"^6.0.0\",\n    \"rehype-autolink-headings\": \"^7.0.0\",\n    \"rehype-document\": \"^7.0.0\",\n    \"rehype-infer-description-meta\": \"^2.0.0\",\n    \"rehype-infer-reading-time-meta\": \"^2.0.0\",\n    \"rehype-infer-title-meta\": \"^2.0.0\",\n    \"rehype-katex\": \"^7.0.0\",\n    \"rehype-meta\": \"^4.0.0\",\n    \"rehype-minify-url\": \"^5.0.0\",\n    \"rehype-parse\": \"^9.0.0\",\n    \"rehype-preset-minify\": \"^7.0.0\",\n    \"rehype-raw\": \"^7.0.0\",\n    \"rehype-remove-comments\": \"^6.0.0\",\n    \"rehype-shift-heading\": \"^2.0.0\",\n    \"rehype-slug\": \"^6.0.0\",\n    \"rehype-starry-night\": \"^2.0.0\",\n    \"rehype-stringify\": \"^10.0.0\",\n    \"rehype-twoslash\": \"^1.0.0\",\n    \"remark-cli\": \"^12.0.0\",\n    \"remark-directive\": \"^4.0.0\",\n    \"remark-frontmatter\": \"^5.0.0\",\n    \"remark-gemoji\": \"^8.0.0\",\n    \"remark-gfm\": \"^4.0.0\",\n    \"remark-github\": \"^12.0.0\",\n    \"remark-math\": \"^6.0.0\",\n    \"remark-mdx-frontmatter\": \"^5.0.0\",\n    \"remark-parse\": \"^11.0.0\",\n    \"remark-preset-wooorm\": \"^11.0.0\",\n    \"remark-squeeze-paragraphs\": \"^6.0.0\",\n    \"remark-stringify\": \"^11.0.0\",\n    \"remark-strip-badges\": \"^7.0.0\",\n    \"remark-toc\": \"^9.0.0\",\n    \"rollup\": \"^4.0.0\",\n    \"type-coverage\": \"^2.0.0\",\n    \"typescript\": \"^5.0.0\",\n    \"unified\": \"^11.0.0\",\n    \"unist-util-remove-position\": \"^5.0.0\",\n    \"unist-util-visit\": \"^5.0.0\",\n    \"vfile\": \"^6.0.0\",\n    \"vfile-matter\": \"^5.0.0\",\n    \"vfile-message\": \"^4.0.0\",\n    \"vite\": \"^7.0.0\",\n    \"vue\": \"^3.0.0\",\n    \"webpack\": \"^5.0.0\",\n    \"xast-util-feed\": \"^2.0.0\",\n    \"xast-util-sitemap\": \"^2.0.0\",\n    \"xast-util-to-xml\": \"^4.0.0\",\n    \"xo\": \"^1.0.0\"\n  },\n  \"scripts\": {\n    \"build\": \"tsc --build --clean && tsc --build && type-coverage\",\n    \"docs\": \"npm run docs-prep && npm run docs-generate && npm run docs-post\",\n    \"docs-css\": \"postcss --output public/index.css docs/_asset/index.css\",\n    \"docs-deploy\": \"vercel && vercel alias $(pbpaste) mdxjs.com && vercel alias $(pbpaste) www.mdxjs.com\",\n    \"docs-generate\": \"node --no-warnings --loader ./script/jsx-loader.js website/generate.js\",\n    \"docs-js\": \"npm run docs-js-default && npm run docs-js-editor\",\n    \"docs-js-default\": \"esbuild --bundle --conditions=browser,production --define:process.env.NODE_ENV=\\\\\\\"production\\\\\\\" --log-level=warning --minify --outfile=public/index.js --target=es2020 docs/_asset/index.js\",\n    \"docs-js-editor\": \"esbuild --bundle --conditions=browser,production --define:process.env.NODE_ENV=\\\\\\\"production\\\\\\\" --log-level=warning --minify --outfile=public/editor.js --target=es2020 docs/_asset/editor.jsx\",\n    \"docs-post\": \"node website/post.js\",\n    \"docs-prep\": \"node website/prep.js && npm run docs-js && npm run docs-css\",\n    \"format\": \"remark --frail --output --quiet -- . && mdxlint --frail --output --quiet -- . && prettier . --log-level warn --write && xo --fix\",\n    \"test\": \"npm run build && npm run format && npm run test-coverage\",\n    \"test-api\": \"npm run test-api --workspaces --if-present\",\n    \"test-coverage\": \"npm run test-coverage --workspaces --if-present\"\n  },\n  \"browserslist\": [\n    \"last 2 versions\",\n    \"not dead\"\n  ],\n  \"postcss\": {\n    \"plugins\": {\n      \"autoprefixer\": true,\n      \"cssnano\": {\n        \"preset\": \"default\"\n      }\n    }\n  },\n  \"prettier\": {\n    \"bracketSpacing\": false,\n    \"singleQuote\": true,\n    \"semi\": false,\n    \"tabWidth\": 2,\n    \"trailingComma\": \"none\",\n    \"useTabs\": false\n  },\n  \"mdxlint\": {\n    \"plugins\": [\n      \"./docs/.remarkrc.js\"\n    ]\n  },\n  \"remarkConfig\": {\n    \"plugins\": [\n      \"remark-preset-wooorm\",\n      [\n        \"remark-lint-no-html\",\n        false\n      ]\n    ]\n  },\n  \"typeCoverage\": {\n    \"atLeast\": 100,\n    \"detail\": true,\n    \"ignoreCatch\": true,\n    \"strict\": true\n  },\n  \"xo\": [\n    {\n      \"files\": [\n        \"**/*.{cjs,jsx,js,ts}\"\n      ],\n      \"prettier\": true,\n      \"react\": true,\n      \"rules\": {\n        \"complexity\": \"off\",\n        \"import-x/no-extraneous-dependencies\": \"off\",\n        \"import-x/order\": \"off\",\n        \"logical-assignment-operators\": \"off\",\n        \"max-depth\": \"off\",\n        \"max-lines\": \"off\",\n        \"n/no-extraneous-import\": \"off\",\n        \"prefer-destructuring\": \"off\",\n        \"promise/prefer-await-to-then\": \"off\",\n        \"promise/prefer-catch\": \"off\",\n        \"unicorn/no-this-assignment\": \"off\",\n        \"unicorn/prefer-at\": \"off\",\n        \"unicorn/prefer-spread\": \"off\",\n        \"unicorn/prefer-string-raw\": \"off\",\n        \"react-hooks/rules-of-hooks\": \"off\",\n        \"react/jsx-no-bind\": \"off\"\n      },\n      \"space\": true\n    },\n    {\n      \"files\": [\n        \"docs/_asset/editor.jsx\",\n        \"docs/_asset/index.js\"\n      ],\n      \"languageOptions\": {\n        \"globals\": {\n          \"CSS\": \"readonly\",\n          \"HTMLButtonElement\": \"readonly\",\n          \"document\": \"readonly\",\n          \"window\": \"readonly\"\n        }\n      }\n    },\n    {\n      \"files\": [\n        \"**/*.jsx\",\n        \"docs/**/*.js\"\n      ],\n      \"rules\": {\n        \"react/react-in-jsx-scope\": \"off\"\n      }\n    },\n    {\n      \"files\": [\n        \"**/*.ts\"\n      ],\n      \"rules\": {\n        \"@typescript-eslint/array-type\": \"off\",\n        \"@typescript-eslint/no-restricted-types\": \"off\",\n        \"@typescript-eslint/consistent-type-definitions\": [\n          \"error\",\n          \"interface\"\n        ]\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/esbuild/index.js",
    "content": "/**\n * @typedef {import('./lib/index.js').Options} Options\n */\n\nexport {esbuild as default} from './lib/index.js'\n"
  },
  {
    "path": "packages/esbuild/lib/index.js",
    "content": "/**\n * @import {CompileOptions} from '@mdx-js/mdx'\n * @import {\n      Location,\n      Message,\n      OnLoadArgs,\n      OnLoadResult,\n      Plugin,\n      PluginBuild\n * } from 'esbuild'\n */\n\n/**\n * @typedef {Omit<OnLoadArgs, 'pluginData'> & LoadDataFields} LoadData\n *   Data passed to `onload`.\n *\n * @typedef LoadDataFields\n *   Extra fields given in `data` to `onload`.\n * @property {PluginData | null | undefined} [pluginData]\n *   Plugin data.\n *\n * @typedef {CompileOptions} Options\n *   Configuration.\n *\n *   Options are the same as `compile` from `@mdx-js/mdx`.\n *\n * @typedef PluginData\n *   Extra data passed.\n * @property {Buffer | string | null | undefined} [contents]\n *   File contents.\n *\n * @typedef State\n *   Info passed around.\n * @property {string} doc\n *   File value.\n * @property {string} name\n *   Plugin name.\n * @property {string} path\n *   File path.\n */\n\nimport assert from 'node:assert'\nimport {Buffer} from 'node:buffer'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {createFormatAwareProcessors} from '@mdx-js/mdx/internal-create-format-aware-processors'\nimport {extnamesToRegex} from '@mdx-js/mdx/internal-extnames-to-regex'\nimport {SourceMapGenerator} from 'source-map'\nimport {VFile} from 'vfile'\nimport {VFileMessage} from 'vfile-message'\n\nconst eol = /\\r\\n|\\r|\\n|\\u2028|\\u2029/g\n\nconst name = '@mdx-js/esbuild'\n\n/**\n * Create an esbuild plugin to compile MDX to JS.\n *\n * esbuild takes care of turning modern JavaScript features into syntax that\n * works wherever you want it to.\n * With other integrations you might need to use Babel for this, but with\n * esbuild that’s not needed.\n * See esbuild’s docs for more info.\n *\n * @param {Readonly<Options> | null | undefined} [options]\n *   Configuration (optional).\n * @return {Plugin}\n *   Plugin.\n */\nexport function esbuild(options) {\n  const settings = {...options, SourceMapGenerator}\n  const {extnames, process} = createFormatAwareProcessors(settings)\n\n  return {name, setup}\n\n  /**\n   * @param {PluginBuild} build\n   *   Build.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  function setup(build) {\n    build.onLoad({filter: extnamesToRegex(extnames)}, onload)\n\n    /**\n     * @param {LoadData} data\n     *   Data.\n     * @returns {Promise<OnLoadResult>}\n     *   Result.\n     */\n    async function onload(data) {\n      const document = String(\n        data.pluginData &&\n          data.pluginData.contents !== null &&\n          data.pluginData.contents !== undefined\n          ? data.pluginData.contents\n          : await fs.readFile(data.path)\n      )\n\n      /** @type {State} */\n      const state = {doc: document, name, path: data.path}\n      let file = new VFile({path: data.path, value: document})\n      /** @type {string | undefined} */\n      let value\n      /** @type {Array<VFileMessage>} */\n      let messages = []\n      /** @type {Array<Message>} */\n      const errors = []\n      /** @type {Array<Message>} */\n      const warnings = []\n\n      try {\n        file = await process(file)\n        value =\n          String(file.value) +\n          '\\n//# sourceMappingURL=data:application/json;base64,' +\n          Buffer.from(JSON.stringify(file.map)).toString('base64') +\n          '\\n'\n        messages = file.messages\n      } catch (error_) {\n        const cause = /** @type {VFileMessage | Error} */ (error_)\n        const message = new VFileMessage(\n          'Cannot process MDX file with esbuild',\n          {\n            cause,\n            place: 'reason' in cause ? cause.place : undefined,\n            ruleId: 'process-error',\n            source: '@mdx-js/esbuild'\n          }\n        )\n        message.fatal = true\n        messages.push(message)\n      }\n\n      for (const message of messages) {\n        const list = message.fatal ? errors : warnings\n        list.push(vfileMessageToEsbuild(state, message))\n      }\n\n      // Safety check: the file has a path, so there has to be a `dirname`.\n      assert.ok(file.dirname, 'expected `dirname` to be defined')\n\n      return {\n        contents: value || '',\n        errors,\n        loader: settings.jsx ? 'jsx' : 'js',\n        resolveDir: path.resolve(file.cwd, file.dirname),\n        warnings\n      }\n    }\n  }\n}\n\n/**\n * @param {Readonly<State>} state\n *   Info passed around.\n * @param {Readonly<VFileMessage>} message\n *   VFile message or error.\n * @returns {Message}\n *   ESBuild message.\n */\nfunction vfileMessageToEsbuild(state, message) {\n  /** @type {Location} */\n  const location = {\n    column: 0,\n    file: state.path,\n    length: 0,\n    line: 0,\n    lineText: '',\n    namespace: 'file',\n    suggestion: ''\n  }\n\n  const place = message.place\n  const start = place ? ('start' in place ? place.start : place) : undefined\n  if (start) {\n    location.column = start.column - 1\n    location.line = start.line\n    location.length = 1\n\n    const end = place && 'end' in place ? place.end : undefined\n    if (end) {\n      if (start.offset !== undefined && end.offset !== undefined) {\n        location.length = end.offset - start.offset\n      } else if (end.line === start.line) {\n        location.length = end.column - start.column\n      }\n    }\n\n    if (start.offset !== undefined) {\n      eol.lastIndex = start.offset\n      const match = eol.exec(state.doc)\n      const lineStart = start.offset - (start.column - 1)\n      const lineEnd = match ? match.index : state.doc.length\n      location.lineText = state.doc.slice(lineStart, lineEnd)\n      location.length = Math.min(location.length, lineEnd - (start.offset || 0))\n    }\n\n    const maxLength = state.doc.length - (start.offset || 0)\n    location.length = Math.min(location.length, maxLength)\n  }\n\n  let text = message.reason\n  if (message.cause) {\n    text = `${text}:\\n  ${message.cause}`\n  }\n\n  return {\n    detail: message,\n    id: '',\n    location,\n    notes: [],\n    pluginName: state.name,\n    text\n  }\n}\n"
  },
  {
    "path": "packages/esbuild/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2021 Titus Wormer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/esbuild/package.json",
    "content": "{\n  \"name\": \"@mdx-js/esbuild\",\n  \"version\": \"3.1.1\",\n  \"description\": \"esbuild plugin for MDX\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"esbuild\",\n    \"jsx\",\n    \"markdown\",\n    \"mdx\",\n    \"preact\",\n    \"react\",\n    \"remark\",\n    \"vue\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/esbuild/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\",\n  \"contributors\": [\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.js\",\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"@mdx-js/mdx\": \"^3.0.0\",\n    \"@types/unist\": \"^3.0.0\",\n    \"source-map\": \"^0.7.0\",\n    \"vfile\": \"^6.0.0\",\n    \"vfile-message\": \"^4.0.0\"\n  },\n  \"peerDependencies\": {\n    \"esbuild\": \">=0.14.0\"\n  },\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development --enable-source-maps test/index.js\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"prettier\": true,\n    \"rules\": {\n      \"n/file-extension-in-import\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/esbuild/readme.md",
    "content": "# `@mdx-js/esbuild`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nesbuild plugin for MDX.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`mdx(options?)`](#mdxoptions)\n  * [`Options`](#options)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is an esbuild plugin to support MDX.\n\n## When should I use this?\n\nThis integration is useful if you’re using [esbuild][] (or another tool that\nuses esbuild).\n\nIf you want to evaluate MDX code then the lower-level compiler (`@mdx-js/mdx`)\ncan be used.\nto support nonstandard JSX runtime (such as Vue), `@mdx-js/mdx` can also be\nused, or our webpack loader (`@mdx-js/loader`) or Rollup plugin\n(`@mdx-js/rollup`).\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/esbuild\n```\n\n## Use\n\nDo something like this with the esbuild API:\n\n```tsx\nimport mdx from '@mdx-js/esbuild'\nimport esbuild from 'esbuild'\n\nawait esbuild.build({\n  // Replace `index.js` with your entry point that imports MDX files:\n  entryPoints: ['index.js'],\n  format: 'esm',\n  outfile: 'output.js',\n  plugins: [mdx({/* jsxImportSource: …, otherOptions… */})]\n})\n```\n\n## API\n\nThis package exports no identifiers.\nThe default export is [`mdx`][api-mdx].\n\n### `mdx(options?)`\n\nCreate an esbuild plugin to compile MDX to JS.\n\nesbuild takes care of turning modern JavaScript features into syntax that works\nwherever you want it to.\nWith other integrations you might need to use Babel for this, but with\nesbuild that’s not needed.\nSee esbuild’s docs for more info.\n\n###### Parameters\n\n* `options` ([`Options`][api-options], optional)\n  — configuration\n\n###### Returns\n\nESBuild plugin ([`Plugin`][esbuild-plugin] from `esbuild`).\n\n### `Options`\n\nConfiguration (TypeScript type).\n\nOptions are the same as [`CompileOptions` from `@mdx-js/mdx`][compile-options].\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional type [`Options`][api-options].\nSee [§ Types][types] on our website for information.\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/esbuild@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © [Titus Wormer][author]\n\n[api-mdx]: #mdxoptions\n\n[api-options]: #options\n\n[author]: https://wooorm.com\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[compile-options]: https://mdxjs.com/packages/mdx/#compileoptions\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/esbuild\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/esbuild.svg\n\n[esbuild]: https://esbuild.github.io\n\n[esbuild-plugin]: https://esbuild.github.io/plugins/\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/esbuild/license\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[support]: https://mdxjs.com/community/support/\n\n[types]: https://mdxjs.com/getting-started/#types\n\n[typescript]: https://www.typescriptlang.org\n"
  },
  {
    "path": "packages/esbuild/test/index.js",
    "content": "/* eslint-disable unicorn/prefer-structured-clone */\n\n/**\n * @import {BuildFailure, Plugin} from 'esbuild'\n * @import {Root} from 'hast'\n * @import {MDXModule} from 'mdx/types.js'\n * @import {VFile} from 'vfile'\n * @import {} from 'remark-mdx'\n */\n\nimport assert from 'node:assert/strict'\nimport fs from 'node:fs/promises'\nimport {test} from 'node:test'\nimport {fileURLToPath} from 'node:url'\nimport esbuildMdx from '@mdx-js/esbuild'\nimport esbuild from 'esbuild'\nimport React from 'react'\nimport {renderToStaticMarkup} from 'react-dom/server'\n\ntest('@mdx-js/esbuild', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('@mdx-js/esbuild')).sort(), [\n      'default'\n    ])\n  })\n\n  await t.test('should compile MDX', async function () {\n    const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n\n    await fs.writeFile(\n      mdxUrl,\n      'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n    )\n\n    await esbuild.build({\n      bundle: true,\n      define: {'process.env.NODE_ENV': '\"development\"'},\n      entryPoints: [fileURLToPath(mdxUrl)],\n      format: 'esm',\n      outfile: fileURLToPath(jsUrl),\n      plugins: [esbuildMdx()]\n    })\n\n    /** @type {MDXModule} */\n    const result = await import(jsUrl.href + '#' + Math.random())\n    const Content = result.default\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(Content)),\n      '<h1>Hello, World!</h1>',\n      'should compile'\n    )\n\n    await fs.rm(mdxUrl)\n    await fs.rm(jsUrl)\n  })\n\n  await t.test('should support importing MDX in MDX', async function () {\n    const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n    const folderUrl = new URL('folder/', import.meta.url)\n    const folderMdxUrl = new URL('file.mdx', folderUrl)\n    const folderJsUrl = new URL('file.js', folderUrl)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n\n    await fs.writeFile(\n      mdxUrl,\n      'import Content from \"./folder/file.mdx\"\\n\\n<Content/>'\n    )\n    await fs.mkdir(folderUrl)\n    await fs.writeFile(folderMdxUrl, 'import {data} from \"./file.js\"\\n\\n{data}')\n    await fs.writeFile(folderJsUrl, 'export const data = 0.1')\n\n    await esbuild.build({\n      bundle: true,\n      define: {'process.env.NODE_ENV': '\"development\"'},\n      entryPoints: [fileURLToPath(mdxUrl)],\n      format: 'esm',\n      outfile: fileURLToPath(jsUrl),\n      plugins: [esbuildMdx()]\n    })\n\n    /** @type {MDXModule} */\n    const result = await import(jsUrl.href + '#' + Math.random())\n    const Content = result.default\n\n    assert.equal(renderToStaticMarkup(React.createElement(Content)), '0.1')\n\n    await fs.rm(mdxUrl)\n    await fs.rm(jsUrl)\n    await fs.rm(folderUrl, {force: true, recursive: true})\n  })\n\n  await t.test('should compile `.md`', async function () {\n    const mdUrl = new URL('esbuild.md', import.meta.url)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n\n    await fs.writeFile(mdUrl, '\\ta')\n\n    await esbuild.build({\n      bundle: true,\n      define: {'process.env.NODE_ENV': '\"development\"'},\n      entryPoints: [fileURLToPath(mdUrl)],\n      format: 'esm',\n      outfile: fileURLToPath(jsUrl),\n      plugins: [esbuildMdx()]\n    })\n\n    /** @type {MDXModule} */\n    const result = await import(jsUrl.href + '#' + Math.random())\n    const Content = result.default\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(Content)),\n      '<pre><code>a\\n</code></pre>'\n    )\n\n    await fs.rm(mdUrl)\n    await fs.rm(jsUrl)\n  })\n\n  await t.test(\n    'should compile `.md` as MDX w/ configuration',\n    async function () {\n      const mdUrl = new URL('esbuild.md', import.meta.url)\n      const jsUrl = new URL('esbuild.js', import.meta.url)\n\n      await fs.writeFile(mdUrl, '\\ta')\n\n      await esbuild.build({\n        bundle: true,\n        define: {'process.env.NODE_ENV': '\"development\"'},\n        entryPoints: [fileURLToPath(mdUrl)],\n        format: 'esm',\n        outfile: fileURLToPath(jsUrl),\n        plugins: [esbuildMdx({mdExtensions: [], mdxExtensions: ['.md']})]\n      })\n\n      /** @type {MDXModule} */\n      const result = await import(jsUrl.href + '#' + Math.random())\n      const Content = result.default\n\n      assert.equal(\n        renderToStaticMarkup(React.createElement(Content)),\n        '<p>a</p>'\n      )\n\n      await fs.rm(mdUrl)\n      await fs.rm(jsUrl)\n    }\n  )\n\n  await t.test(\n    'should not handle `.md` files w/ `format: mdx`',\n    async function () {\n      const mdUrl = new URL('esbuild.md', import.meta.url)\n      const jsUrl = new URL('esbuild.js', import.meta.url)\n\n      await fs.writeFile(mdUrl, 'a')\n\n      try {\n        await esbuild.build({\n          entryPoints: [fileURLToPath(mdUrl)],\n          logLevel: 'silent',\n          outfile: fileURLToPath(jsUrl),\n          plugins: [esbuildMdx({format: 'mdx'})]\n        })\n        assert.fail()\n      } catch (error) {\n        assert.match(String(error), /No loader is configured for \"\\.md\" files/)\n      }\n\n      await fs.rm(mdUrl)\n    }\n  )\n\n  await t.test(\n    'should not handle `.mdx` files w/ `format: md`',\n    async function () {\n      const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n      const jsUrl = new URL('esbuild.js', import.meta.url)\n\n      await fs.writeFile(mdxUrl, 'a')\n\n      try {\n        await esbuild.build({\n          entryPoints: [fileURLToPath(mdxUrl)],\n          logLevel: 'silent',\n          outfile: fileURLToPath(jsUrl),\n          plugins: [esbuildMdx({format: 'md'})]\n        })\n        assert.fail()\n      } catch (error) {\n        assert.match(String(error), /No loader is configured for \"\\.mdx\" files/)\n      }\n\n      await fs.rm(mdxUrl)\n    }\n  )\n\n  await t.test('should pass MDX error', async function () {\n    const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n\n    await fs.writeFile(mdxUrl, 'asd <https://example.com>?')\n\n    try {\n      await esbuild.build({\n        entryPoints: [fileURLToPath(mdxUrl)],\n        logLevel: 'silent',\n        outfile: fileURLToPath(jsUrl),\n        plugins: [esbuildMdx()]\n      })\n      assert.fail()\n    } catch (error) {\n      const exception = /** @type {BuildFailure} */ (error)\n      const message = exception.errors[0]\n\n      delete message.detail\n\n      assert.deepEqual(message, {\n        id: '',\n        location: {\n          column: 11,\n          file: 'test/esbuild.mdx',\n          length: 1,\n          line: 1,\n          lineText: 'asd <https://example.com>?',\n          namespace: 'file',\n          suggestion: ''\n        },\n        notes: [],\n        pluginName: '@mdx-js/esbuild',\n        text: 'Cannot process MDX file with esbuild:\\n  1:12: Unexpected character `/` (U+002F) before local name, expected a character that can start a name, such as a letter, `$`, or `_` (note: to create a link in MDX, use `[text](url)`)'\n      })\n    }\n\n    await fs.rm(mdxUrl)\n  })\n\n  await t.test('should pass warnings', async function () {\n    const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n\n    await fs.writeFile(\n      mdxUrl,\n      'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n    )\n\n    try {\n      await esbuild.build({\n        entryPoints: [fileURLToPath(mdxUrl)],\n        format: 'esm',\n        logLevel: 'silent',\n        outfile: fileURLToPath(jsUrl),\n        plugins: [esbuildMdx({rehypePlugins: [warn]})]\n      })\n      assert.fail()\n    } catch (error) {\n      /** @type {BuildFailure} */\n      const result = JSON.parse(JSON.stringify(error))\n\n      for (const message of [...result.errors, ...result.warnings]) {\n        delete message.detail\n      }\n\n      assert.deepEqual(result, {\n        errors: [\n          {\n            id: '',\n            location: {\n              column: 20,\n              file: 'test/esbuild.mdx',\n              length: 0,\n              line: 3,\n              lineText: '# Hello, <Message />',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: '7'\n          }\n        ],\n        warnings: [\n          {\n            id: '',\n            location: {\n              column: 0,\n              file: 'test/esbuild.mdx',\n              length: 0,\n              line: 0,\n              lineText: '',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: '1'\n          },\n          {\n            id: '',\n            location: {\n              column: 0,\n              file: 'test/esbuild.mdx',\n              length: 0,\n              line: 0,\n              lineText: '',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: '2'\n          },\n          {\n            id: '',\n            location: {\n              column: 0,\n              file: 'test/esbuild.mdx',\n              length: 48,\n              line: 1,\n              lineText: 'export function Message() { return <>World!</> }',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: '3'\n          },\n          {\n            id: '',\n            location: {\n              column: 0,\n              file: 'test/esbuild.mdx',\n              length: 48,\n              line: 1,\n              lineText: 'export function Message() { return <>World!</> }',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: '4'\n          },\n          {\n            id: '',\n            location: {\n              column: 2,\n              file: 'test/esbuild.mdx',\n              length: 7,\n              line: 3,\n              lineText: '# Hello, <Message />',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: '5'\n          },\n          {\n            id: '',\n            location: {\n              column: 9,\n              file: 'test/esbuild.mdx',\n              length: 11,\n              line: 3,\n              lineText: '',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: '6'\n          }\n        ]\n      })\n    }\n\n    await fs.rm(mdxUrl)\n\n    function warn() {\n      /**\n       * @param {Root} tree\n       *   Tree.\n       * @param {VFile} file\n       *   File.\n       * @returns {undefined}\n       *   Nothing.\n       */\n      return function (tree, file) {\n        const esm = tree.children[0] // Export\n        const eol = tree.children[1] // EOL between both, no position.\n        const head = tree.children[2] // Heading\n        assert.ok(esm)\n        assert.ok(esm.type === 'mdxjsEsm')\n        assert.ok(eol)\n        assert.ok(eol.type === 'text')\n        assert.ok(!eol.position)\n        assert.ok(head)\n        assert.ok(head.type === 'element')\n        assert.ok(head.position)\n\n        const text = head.children[0] // Text in heading\n        const jsx = head.children[1] // JSX in heading\n\n        assert.ok(text)\n        assert.ok(text.type === 'text')\n        assert.ok(jsx)\n        assert.ok(jsx.type === 'mdxJsxTextElement')\n\n        file.message('1')\n        file.message('2', eol)\n        file.message('3', tree)\n        file.message('4', esm)\n        file.message('5', text)\n        const m6 = file.message('6', jsx)\n        assert.ok(m6.place)\n        assert.ok('start' in m6.place)\n        delete m6.place.start.offset\n        file.message('7', head.position.end).fatal = true // End of heading\n      }\n    }\n  })\n\n  await t.test('should pass errors', async function () {\n    const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n\n    await fs.writeFile(mdxUrl, '# hi')\n\n    try {\n      await esbuild.build({\n        logLevel: 'silent',\n        entryPoints: [fileURLToPath(mdxUrl)],\n        outfile: fileURLToPath(jsUrl),\n        format: 'esm',\n        plugins: [esbuildMdx({rehypePlugins: [crash]})]\n      })\n      assert.fail()\n    } catch (error) {\n      /** @type {BuildFailure} */\n      const result = JSON.parse(JSON.stringify(error))\n\n      assert.deepEqual(result, {\n        errors: [\n          {\n            detail: {\n              cause: {},\n              fatal: true,\n              file: '',\n              message: 'Cannot process MDX file with esbuild',\n              name: '1:1',\n              reason: 'Cannot process MDX file with esbuild',\n              ruleId: 'process-error',\n              source: '@mdx-js/esbuild'\n            },\n            id: '',\n            location: {\n              column: 0,\n              file: 'test/esbuild.mdx',\n              length: 0,\n              line: 0,\n              lineText: '',\n              namespace: 'file',\n              suggestion: ''\n            },\n            notes: [],\n            pluginName: '@mdx-js/esbuild',\n            text: 'Cannot process MDX file with esbuild:\\n  Error: Something went wrong'\n          }\n        ],\n        warnings: []\n      })\n    }\n\n    await fs.rm(mdxUrl)\n\n    function crash() {\n      return function () {\n        throw new Error('Something went wrong')\n      }\n    }\n  })\n\n  await t.test('should compile from `pluginData.content`', async function () {\n    const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n\n    await esbuild.build({\n      entryPoints: [fileURLToPath(mdxUrl)],\n      outfile: fileURLToPath(jsUrl),\n      plugins: [inlinePlugin('# Test'), esbuildMdx()],\n      define: {'process.env.NODE_ENV': '\"development\"'},\n      format: 'esm',\n      bundle: true\n    })\n\n    /** @type {MDXModule} */\n    const result = await import(jsUrl.href + '#' + Math.random())\n    const Content = result.default\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(Content)),\n      '<h1>Test</h1>'\n    )\n\n    await fs.rm(jsUrl)\n  })\n\n  await t.test(\n    'should compile from `pluginData.content` when an empty string is passed',\n    async function () {\n      const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n      const jsUrl = new URL('esbuild.js', import.meta.url)\n\n      await esbuild.build({\n        entryPoints: [fileURLToPath(mdxUrl)],\n        outfile: fileURLToPath(jsUrl),\n        plugins: [inlinePlugin(''), esbuildMdx()],\n        define: {'process.env.NODE_ENV': '\"development\"'},\n        format: 'esm',\n        bundle: true\n      })\n\n      /** @type {MDXModule} */\n      const result = await import(jsUrl.href + '#' + Math.random())\n      const Content = result.default\n\n      assert.equal(renderToStaticMarkup(React.createElement(Content)), '')\n\n      await fs.rm(jsUrl)\n    }\n  )\n\n  await t.test('should support source maps', async () => {\n    const mdxUrl = new URL('crash.mdx', import.meta.url)\n    const jsUrl = new URL('crash.js', import.meta.url)\n    await fs.writeFile(\n      mdxUrl,\n      '<Throw />\\nexport function Throw() { throw new Error(\"Boom\") }\\n'\n    )\n\n    await esbuild.build({\n      entryPoints: [fileURLToPath(mdxUrl)],\n      outfile: fileURLToPath(jsUrl),\n      plugins: [esbuildMdx()],\n      define: {'process.env.NODE_ENV': '\"development\"'},\n      format: 'esm',\n      sourcemap: true,\n      bundle: true\n    })\n\n    /** @type {MDXModule} */\n    const result = await import(jsUrl.href)\n    const Content = result.default\n\n    assert.throws(\n      () => renderToStaticMarkup(React.createElement(Content)),\n      (error) => {\n        assert.ok(error instanceof Error)\n        assert.equal(error.message, 'Boom')\n        // Source maps are off.\n        // The column should be 26, not 8.\n        assert.ok(error.stack?.includes('crash.mdx:2:8)'))\n        return true\n      }\n    )\n\n    await fs.rm(mdxUrl)\n    await fs.rm(jsUrl)\n  })\n\n  await t.test('should use esbuild \"jsx\" loader for JSX output', async () => {\n    const mdxUrl = new URL('esbuild.mdx', import.meta.url)\n    const jsUrl = new URL('esbuild.js', import.meta.url)\n    await fs.writeFile(\n      mdxUrl,\n      'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n    )\n\n    await esbuild.build({\n      entryPoints: [fileURLToPath(mdxUrl)],\n      outfile: fileURLToPath(jsUrl),\n      plugins: [esbuildMdx({jsx: true})],\n      define: {'process.env.NODE_ENV': '\"development\"'},\n      format: 'esm',\n      bundle: true\n    })\n\n    /** @type {MDXModule} */\n    const result = await import(jsUrl.href + '#' + Math.random())\n    const Content = result.default\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(Content)),\n      '<h1>Hello, World!</h1>'\n    )\n\n    await fs.rm(mdxUrl)\n    await fs.rm(jsUrl)\n  })\n})\n\n/**\n * @param {string} contents\n *   Contents.\n * @returns {Plugin}\n *   Plugin.\n */\nfunction inlinePlugin(contents) {\n  return {\n    name: 'inline plugin',\n    setup(build) {\n      build.onResolve({filter: /esbuild\\.mdx/}, function () {\n        return {\n          path: fileURLToPath(new URL('esbuild.mdx', import.meta.url)),\n          pluginData: {contents}\n        }\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "packages/esbuild/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/loader/index.cjs",
    "content": "/**\n * @import {LoaderContext} from 'webpack'\n * @import {Options as Options_} from './lib/index.js' with {'resolution-mode': 'import'}\n */\n\n/**\n * @typedef {Options_} Options\n */\n\n'use strict'\n\n// Note: we can’t export immediately, as TS generates broken types.\n// See: mdx-js/mdx#2386.\nmodule.exports = loader\n\n/**\n * Webpack loader\n *\n * @todo once webpack supports ESM loaders, remove this wrapper.\n *\n * @this {LoaderContext<unknown>}\n *   Context.\n * @param {string} code\n *   Code.\n * @returns {undefined}\n *   Nothing.\n */\nfunction loader(code) {\n  const callback = this.async()\n  // Note that `import()` caches, so this should be fast enough.\n  import('./lib/index.js').then((module) => {\n    return module.loader.call(this, code, callback)\n  }, callback)\n}\n"
  },
  {
    "path": "packages/loader/lib/index.js",
    "content": "/**\n * @import {CompileOptions} from '@mdx-js/mdx'\n * @import {Compatible, VFile} from 'vfile'\n * @import {VFileMessage} from 'vfile-message'\n * @import {Compiler as WebpackCompiler, LoaderContext} from 'webpack'\n */\n\n/**\n * @typedef {Omit<CompileOptions, 'SourceMapGenerator' | 'development'>} Options\n *   Configuration (TypeScript type).\n *\n *   Options are the same as `compile` from `@mdx-js/mdx` with the exception\n *   that the `SourceMapGenerator` and `development` options are supported\n *   based on how you configure webpack.\n *   You cannot pass them manually.\n *\n * @callback Process\n *   Process.\n * @param {Compatible} vfileCompatible\n *   Input.\n * @returns {Promise<VFile>}\n *   File.\n */\n\nimport {Buffer} from 'node:buffer'\nimport {createHash} from 'node:crypto'\nimport path from 'node:path'\nimport {createFormatAwareProcessors} from '@mdx-js/mdx/internal-create-format-aware-processors'\nimport {SourceMapGenerator} from 'source-map'\n\n// Note: the cache is heavily inspired by:\n// <https://github.com/TypeStrong/ts-loader/blob/5c030bf/src/instance-cache.ts>\nconst marker = /** @type {WebpackCompiler} */ ({})\n/** @type {WeakMap<WebpackCompiler, Map<string, Process>>} */\nconst cache = new WeakMap()\n\n/**\n * A Webpack (5+) loader for MDX.\n * See `webpack.cjs`, which wraps this, because Webpack loaders must currently\n * be CommonJS.\n *\n * @this {LoaderContext<unknown>}\n *   Context.\n * @param {string} value\n *   Value.\n * @param {LoaderContext<unknown>['callback']} callback\n *   Callback.\n * @returns {undefined}\n *   Nothing.\n */\nexport function loader(value, callback) {\n  const options = /** @type {CompileOptions} */ (this.getOptions())\n  const hash = getOptionsHash(options)\n  const config = {\n    SourceMapGenerator: this.sourceMap ? SourceMapGenerator : undefined,\n    development: this.mode === 'development',\n    ...options\n  }\n  /* c8 ignore next -- some loaders set `undefined` (see `TypeStrong/ts-loader`). */\n  const compiler = this._compiler || marker\n\n  // To do: next major: remove.\n  if ('renderer' in config) {\n    callback(\n      new Error(\n        '`options.renderer` is no longer supported. Please see <https://mdxjs.com/migrating/v2/> for more information'\n      )\n    )\n    return\n  }\n\n  let map = cache.get(compiler)\n\n  if (!map) {\n    map = new Map()\n    cache.set(compiler, map)\n  }\n\n  let process = map.get(hash)\n\n  if (!process) {\n    process = createFormatAwareProcessors(config).process\n    map.set(hash, process)\n  }\n\n  const context = this.context\n  const filePath = this.resourcePath\n\n  process({value, path: filePath}).then(\n    function (file) {\n      callback(\n        undefined,\n        Buffer.from(file.value),\n        // @ts-expect-error: `webpack` is not compiled with `exactOptionalPropertyTypes`,\n        // so it does not allow `sourceRoot` in `file.map` to be `undefined` here.\n        file.map || undefined\n      )\n    },\n    /**\n     * @param {VFileMessage} error\n     *   Error.\n     * @returns {undefined}\n     *   Nothing.\n     */\n    function (error) {\n      const fpath = path.relative(context, filePath)\n      error.message = `${fpath}:${error.name}: ${error.message}`\n      callback(error)\n    }\n  )\n}\n\n/**\n * @param {Readonly<Options>} options\n *   Configuration.\n * @returns {string}\n *   Hash.\n */\nfunction getOptionsHash(options) {\n  const hash = createHash('sha256')\n  /** @type {keyof Options} */\n  let key\n\n  for (key in options) {\n    if (Object.hasOwn(options, key)) {\n      const value = options[key]\n\n      if (value !== undefined) {\n        const valueString = JSON.stringify(value)\n        hash.update(key + valueString)\n      }\n    }\n  }\n\n  return hash.digest('hex').slice(0, 16)\n}\n"
  },
  {
    "path": "packages/loader/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Compositor and Vercel, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/loader/package.json",
    "content": "{\n  \"name\": \"@mdx-js/loader\",\n  \"version\": \"3.1.1\",\n  \"description\": \"Webpack loader for MDX\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"jsx\",\n    \"markdown\",\n    \"mdx\",\n    \"preact\",\n    \"react\",\n    \"remark\",\n    \"vue\",\n    \"webpack\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/loader/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n  \"contributors\": [\n    \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n    \"Tim Neutkens <tim@vercel.com>\",\n    \"Matija Marohnić <matija.marohnic@gmail.com>\",\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\",\n    \"JounQin <admin@1stg.me> (https://www.1stg.me)\",\n    \"Christian Murphy <christian.murphy.42@gmail.com>\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.cjs\",\n  \"files\": [\n    \"lib/\",\n    \"index.cjs\",\n    \"index.d.cts.map\",\n    \"index.d.cts\"\n  ],\n  \"dependencies\": {\n    \"@mdx-js/mdx\": \"^3.0.0\",\n    \"source-map\": \"^0.7.0\"\n  },\n  \"peerDependencies\": {\n    \"webpack\": \">=5\"\n  },\n  \"peerDependenciesMeta\": {\n    \"webpack\": {\n      \"optional\": true\n    }\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development test/index.js\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"prettier\": true,\n    \"rules\": {\n      \"n/file-extension-in-import\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/loader/readme.md",
    "content": "# `@mdx-js/loader`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nwebpack loader for MDX.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`mdx`](#mdx)\n  * [`Options`](#options)\n* [Examples](#examples)\n  * [Combine with Babel](#combine-with-babel)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a webpack loader to support MDX.\n\n## When should I use this?\n\nThis integration is useful if you’re using webpack (or another tool that uses\nwebpack, such as Next.js or Rspack).\n\nThis integration can be combined with the Babel loader to compile modern\nJavaScript features to ones your users support.\n\nIf you want to evaluate MDX code then the lower-level compiler (`@mdx-js/mdx`)\ncan be used manually.\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/loader\n```\n\n## Use\n\nAdd something along these lines to your `webpack.config.js`:\n\n```tsx\n/**\n * @import {Options} from '@mdx-js/loader'\n * @import {Configuration} from 'webpack'\n */\n\n/** @type {Configuration} */\nconst webpackConfig = {\n  module: {\n    // …\n    rules: [\n      // …\n      {\n        test: /\\.mdx?$/,\n        use: [\n          {\n            loader: '@mdx-js/loader',\n            /** @type {Options} */\n            options: {/* jsxImportSource: …, otherOptions… */}\n          }\n        ]\n      }\n    ]\n  }\n}\n\nexport default webpackConfig\n```\n\nSee also [¶ Next.js][next] and [¶ Vue CLI][vue-cli], if you’re using webpack\nthrough them, for more info.\n\n## API\n\nThis package exports no identifiers.\nThe default export is [`mdx`][api-mdx].\n\n### `mdx`\n\nThis package exports a [webpack][] plugin as the default export.\nConfiguration (see [`Options`][api-options]) are passed separately through\nwebpack.\n\n### `Options`\n\nConfiguration (TypeScript type).\n\nOptions are the same as [`CompileOptions` from `@mdx-js/mdx`][compile-options]\nwith the exception that the `SourceMapGenerator` and `development` options are\nsupported based on how you configure webpack.\nYou cannot pass them manually.\n\n## Examples\n\n### Combine with Babel\n\nIf you use modern JavaScript features you might want to use Babel through\n[`babel-loader`][babel-loader] to compile to code that works in older browsers:\n\n```tsx\n/**\n * @import {Options} from '@mdx-js/loader'\n * @import {Configuration} from 'webpack'\n */\n\n/** @type {Configuration} */\nconst webpackConfig = {\n  module: {\n    // …\n    rules: [\n      // …\n      {\n        test: /\\.mdx?$/,\n        use: [\n          // Note that Webpack runs right-to-left: `@mdx-js/loader` is used first, then\n          // `babel-loader`.\n          {loader: 'babel-loader', options: {}},\n          {\n            loader: '@mdx-js/loader',\n            /** @type {Options} */\n            options: {}\n          }\n        ]\n      }\n    ]\n  }\n}\n\nexport default webpackConfig\n```\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional type [`Options`][api-options].\nSee [§ Types][types] on our website for information.\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/loader@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © Compositor and [Vercel][]\n\n[api-mdx]: #mdx\n\n[api-options]: #options\n\n[babel-loader]: https://webpack.js.org/loaders/babel-loader/\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[compile-options]: https://mdxjs.com/packages/mdx/#compileoptions\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/loader\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/loader.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/loader/license\n\n[next]: https://mdxjs.com/getting-started/#nextjs\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[support]: https://mdxjs.com/community/support/\n\n[types]: https://mdxjs.com/getting-started/#types\n\n[typescript]: https://www.typescriptlang.org\n\n[vercel]: https://vercel.com\n\n[vue-cli]: https://mdxjs.com/getting-started/#vue-cli\n\n[webpack]: https://webpack.js.org\n"
  },
  {
    "path": "packages/loader/test/index.js",
    "content": "/**\n * @import {MDXContent} from 'mdx/types.js'\n */\n\nimport assert from 'node:assert/strict'\nimport fs from 'node:fs/promises'\nimport {test} from 'node:test'\nimport {promisify} from 'node:util'\nimport {fileURLToPath} from 'node:url'\nimport React from 'react'\nimport {renderToStaticMarkup} from 'react-dom/server'\nimport webpackCallback from 'webpack'\n\nconst webpack = await promisify(webpackCallback)\n\ntest('@mdx-js/loader', async function (t) {\n  await t.test('should expose the public api', async function () {\n    const keys = Object.keys(await import('@mdx-js/loader'))\n      .sort()\n      // To do: when Node 23 is the lowest baseline,\n      // drop this.\n      .filter((key) => key !== 'module.exports')\n\n    assert.deepEqual(keys, ['default'])\n  })\n\n  await t.test('should work', async function () {\n    const folderUrl = new URL('./', import.meta.url)\n    const mdxUrl = new URL('webpack.mdx', import.meta.url)\n    const jsUrl = new URL('webpack.cjs', import.meta.url)\n\n    await fs.writeFile(\n      mdxUrl,\n      'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n    )\n\n    const result = await webpack({\n      // @ts-expect-error: webpack types do not include `context`, which does work.\n      context: fileURLToPath(folderUrl),\n      entry: './webpack.mdx',\n      mode: 'none',\n      module: {rules: [{test: /\\.mdx$/, use: ['@mdx-js/loader']}]},\n      output: {\n        filename: 'webpack.cjs',\n        libraryTarget: 'commonjs',\n        path: fileURLToPath(folderUrl)\n      }\n    })\n\n    assert.ok(result)\n    assert.ok(!result.hasErrors())\n\n    // One for ESM loading CJS, one for webpack.\n    const moduleResult = /** @type {{default: {default: MDXContent}}} */ (\n      await import(jsUrl.href + '#' + Math.random())\n    )\n    const Content = moduleResult.default.default\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(Content)),\n      '<h1>Hello, World!</h1>'\n    )\n\n    const output = String(await fs.readFile(jsUrl))\n\n    assert.doesNotMatch(\n      output,\n      /react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_\\d+__\\.jsxDEV/\n    )\n\n    assert.doesNotMatch(output, /\\/\\/# sourceMappingURL/)\n\n    await fs.rm(mdxUrl)\n    await fs.rm(jsUrl)\n  })\n\n  await t.test(\n    'should support source maps and development mode',\n    async function () {\n      const folderUrl = new URL('./', import.meta.url)\n      const mdxUrl = new URL('webpack.mdx', import.meta.url)\n      const jsUrl = new URL('webpack.cjs', import.meta.url)\n\n      await fs.writeFile(\n        mdxUrl,\n        'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n      )\n\n      const result = await webpack({\n        // @ts-expect-error: webpack types do not include `context`, which does work.\n        context: fileURLToPath(folderUrl),\n        devtool: 'inline-source-map',\n        entry: './webpack.mdx',\n        mode: 'development',\n        module: {rules: [{test: /\\.mdx$/, use: ['@mdx-js/loader']}]},\n        output: {\n          filename: 'webpack.cjs',\n          libraryTarget: 'commonjs',\n          path: fileURLToPath(folderUrl)\n        }\n      })\n\n      assert.ok(result)\n      assert.ok(!result.hasErrors())\n\n      const output = String(await fs.readFile(jsUrl))\n\n      assert.match(\n        output,\n        /react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_\\d+__\\.jsxDEV/\n      )\n\n      assert.match(output, /\\/\\/# sourceMappingURL/)\n\n      await fs.rm(mdxUrl)\n      await fs.rm(jsUrl)\n    }\n  )\n\n  await t.test('should emit an error', async function () {\n    const folderUrl = new URL('./', import.meta.url)\n    const mdxUrl = new URL('webpack.mdx', import.meta.url)\n\n    await fs.writeFile(mdxUrl, '# Hello, {<Message />')\n\n    const result = await webpack({\n      // @ts-expect-error: webpack types do not include `context`, which does work.\n      context: fileURLToPath(folderUrl),\n      entry: './webpack.mdx',\n      mode: 'none',\n      module: {rules: [{test: /\\.mdx$/, use: ['@mdx-js/loader']}]},\n      output: {\n        filename: 'webpack.cjs',\n        libraryTarget: 'commonjs',\n        path: fileURLToPath(folderUrl)\n      }\n    })\n\n    assert.ok(result)\n    const errors = result.toJson().errors || []\n    const error = errors[0]\n\n    assert.equal(\n      error.message,\n      `Module build failed (from ../index.cjs):\nwebpack.mdx:1:22: Unexpected end of file in expression, expected a corresponding closing brace for \\`{\\``,\n      'received expected error message'\n    )\n\n    await fs.rm(mdxUrl)\n    await fs.rm(new URL('webpack.cjs', folderUrl))\n  })\n\n  await t.test(\n    'should support source maps and development mode',\n    async function () {\n      const folderUrl = new URL('./', import.meta.url)\n      const mdxUrl = new URL('webpack.mdx', import.meta.url)\n      const jsUrl = new URL('webpack.cjs', import.meta.url)\n\n      await fs.writeFile(\n        mdxUrl,\n        'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n      )\n\n      const result = await webpack({\n        // @ts-expect-error: webpack types do not include `context`, which does work.\n        context: fileURLToPath(folderUrl),\n        devtool: 'inline-source-map',\n        entry: './webpack.mdx',\n        mode: 'development',\n        module: {rules: [{test: /\\.mdx$/, use: ['@mdx-js/loader']}]},\n        output: {\n          filename: 'webpack.cjs',\n          libraryTarget: 'commonjs',\n          path: fileURLToPath(folderUrl)\n        }\n      })\n\n      assert.ok(result)\n      assert.ok(!result.hasErrors())\n\n      const output = String(await fs.readFile(jsUrl))\n\n      assert.match(\n        output,\n        /react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_\\d+__\\.jsxDEV/\n      )\n\n      assert.match(output, /\\/\\/# sourceMappingURL/)\n\n      await fs.rm(mdxUrl)\n      await fs.rm(jsUrl)\n    }\n  )\n\n  await t.test('should throw for `renderer`', async function () {\n    const folderUrl = new URL('./', import.meta.url)\n    const mdxUrl = new URL('webpack.mdx', import.meta.url)\n\n    await fs.writeFile(mdxUrl, '\\ta')\n\n    const result = await webpack({\n      // @ts-expect-error: webpack types do not include `context`, which does work.\n      context: fileURLToPath(folderUrl),\n      entry: './webpack.mdx',\n      mode: 'none',\n      module: {\n        rules: [\n          {\n            test: /\\.mdx$/,\n            use: [{loader: '@mdx-js/loader', options: {renderer: '?'}}]\n          }\n        ]\n      },\n      output: {\n        filename: 'webpack.cjs',\n        libraryTarget: 'commonjs',\n        path: fileURLToPath(folderUrl)\n      }\n    })\n\n    assert.ok(result)\n    const errors = result.toJson().errors || []\n    const error = errors[0]\n\n    assert.match(error.message, /`options.renderer` is no longer supported/)\n\n    await fs.rm(mdxUrl)\n    await fs.rm(new URL('webpack.cjs', folderUrl))\n  })\n})\n"
  },
  {
    "path": "packages/loader/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/mdx/index.js",
    "content": "/**\n * @typedef {import('hast-util-to-jsx-runtime').Fragment} Fragment\n * @typedef {import('hast-util-to-jsx-runtime').Jsx} Jsx\n * @typedef {import('hast-util-to-jsx-runtime').JsxDev} JsxDev\n * @typedef {import('./lib/util/resolve-evaluate-options.js').UseMdxComponents} UseMdxComponents\n * @typedef {import('./lib/compile.js').CompileOptions} CompileOptions\n * @typedef {import('./lib/core.js').ProcessorOptions} ProcessorOptions\n * @typedef {import('./lib/util/resolve-evaluate-options.js').EvaluateOptions} EvaluateOptions\n * @typedef {import('./lib/util/resolve-evaluate-options.js').RunOptions} RunOptions\n */\n\nexport {compile, compileSync} from './lib/compile.js'\nexport {createProcessor} from './lib/core.js'\nexport {evaluate, evaluateSync} from './lib/evaluate.js'\nexport {nodeTypes} from './lib/node-types.js'\nexport {run, runSync} from './lib/run.js'\n"
  },
  {
    "path": "packages/mdx/lib/compile.js",
    "content": "/**\n * @import {Compatible, VFile} from 'vfile'\n * @import {ProcessorOptions} from './core.js'\n */\n\n/**\n * @typedef {Omit<ProcessorOptions, 'format'>} CoreProcessorOptions\n *   Core configuration.\n *\n * @typedef ExtraOptions\n *   Extra configuration.\n * @property {'detect' | 'md' | 'mdx' | null | undefined} [format='detect']\n *   Format of `file` (default: `'detect'`).\n *\n * @typedef {CoreProcessorOptions & ExtraOptions} CompileOptions\n *   Configuration for `compile`.\n *\n *   `CompileOptions` is the same as `ProcessorOptions` with the exception that\n *   the `format` option supports a `'detect'` value, which is the default.\n *   The `'detect'` format means to use `'md'` for files with an extension in\n *   `mdExtensions` and `'mdx'` otherwise.\n */\n\nimport {resolveFileAndOptions} from './util/resolve-file-and-options.js'\nimport {createProcessor} from './core.js'\n\n/**\n * Compile MDX to JS.\n *\n * @param {Readonly<Compatible>} vfileCompatible\n *   MDX document to parse.\n * @param {Readonly<CompileOptions> | null | undefined} [compileOptions]\n *   Compile configuration (optional).\n * @return {Promise<VFile>}\n *   Promise to compiled file.\n */\nexport function compile(vfileCompatible, compileOptions) {\n  const {file, options} = resolveFileAndOptions(vfileCompatible, compileOptions)\n  return createProcessor(options).process(file)\n}\n\n/**\n * Synchronously compile MDX to JS.\n *\n * When possible please use the async `compile`.\n *\n * @param {Readonly<Compatible>} vfileCompatible\n *   MDX document to parse.\n * @param {Readonly<CompileOptions> | null | undefined} [compileOptions]\n *   Compile configuration (optional).\n * @return {VFile}\n *   Compiled file.\n */\nexport function compileSync(vfileCompatible, compileOptions) {\n  const {file, options} = resolveFileAndOptions(vfileCompatible, compileOptions)\n  return createProcessor(options).processSync(file)\n}\n"
  },
  {
    "path": "packages/mdx/lib/core.js",
    "content": "/**\n * @import {Program} from 'estree-jsx'\n * @import {Root} from 'mdast'\n * @import {Options as RehypeRecmaOptions} from 'rehype-recma'\n * @import {Options as RemarkRehypeOptions} from 'remark-rehype'\n * @import {SourceMapGenerator} from 'source-map'\n * @import {PluggableList, Processor} from 'unified'\n */\n\n/**\n * @typedef ProcessorOptions\n *   Configuration for `createProcessor`.\n * @property {typeof SourceMapGenerator | null | undefined} [SourceMapGenerator]\n *   Add a source map (object form) as the `map` field on the resulting file\n *   (optional).\n * @property {URL | string | null | undefined} [baseUrl]\n *   Use this URL as `import.meta.url` and resolve `import` and `export … from`\n *   relative to it (optional, example: `import.meta.url`).\n * @property {boolean | null | undefined} [development=false]\n *   Whether to add extra info to error messages in generated code and use the\n *   development automatic JSX runtime (`Fragment` and `jsxDEV` from\n *   `/jsx-dev-runtime`) (default: `false`);\n *   when using the webpack loader (`@mdx-js/loader`) or the Rollup integration\n *   (`@mdx-js/rollup`) through Vite, this is automatically inferred from how\n *   you configure those tools.\n * @property {RehypeRecmaOptions['elementAttributeNameCase']} [elementAttributeNameCase='react']\n *   Casing to use for attribute names (default: `'react'`);\n *   HTML casing is for example `class`, `stroke-linecap`, `xml:lang`;\n *   React casing is for example `className`, `strokeLinecap`, `xmlLang`;\n *   for JSX components written in MDX, the author has to be aware of which\n *   framework they use and write code accordingly;\n *   for AST nodes generated by this project, this option configures it\n * @property {'md' | 'mdx' | null | undefined} [format='mdx']\n *   format of the file (default: `'mdx'`);\n *   `'md'` means treat as markdown and `'mdx'` means treat as MDX.\n * @property {boolean | null | undefined} [jsx=false]\n *   Whether to keep JSX (default: `false`);\n *   the default is to compile JSX away so that the resulting file is\n *   immediately runnable.\n * @property {string | null | undefined} [jsxImportSource='react']\n *   Place to import automatic JSX runtimes from (default: `'react'`);\n *   when in the `automatic` runtime, this is used to define an import for\n *   `Fragment`, `jsx`, `jsxDEV`, and `jsxs`.\n * @property {'automatic' | 'classic' | null | undefined} [jsxRuntime='automatic']\n *   JSX runtime to use (default: `'automatic'`);\n *   the automatic runtime compiles to `import _jsx from\n *   '$importSource/jsx-runtime'\\n_jsx('p')`;\n *   the classic runtime compiles to calls such as `h('p')`.\n *\n *   > 👉 **Note**: support for the classic runtime is deprecated and will\n *   > likely be removed in the next major version.\n * @property {ReadonlyArray<string> | null | undefined} [mdExtensions]\n *   List of markdown extensions, with dot (default: `['.md', '.markdown', …]`);\n *   affects integrations.\n * @property {ReadonlyArray<string> | null | undefined} [mdxExtensions]\n *   List of MDX extensions, with dot (default: `['.mdx']`);\n *   affects integrations.\n * @property {'function-body' | 'program' | null | undefined} [outputFormat='program']\n *   Output format to generate (default: `'program'`);\n *   in most cases `'program'` should be used, it results in a whole program;\n *   internally `evaluate` uses `'function-body'` to compile to\n *   code that can be passed to `run`;\n *   in some cases, you might want what `evaluate` does in separate steps, such\n *   as when compiling on the server and running on the client.\n * @property {string | null | undefined} [pragma='React.createElement']\n *   Pragma for JSX, used in the classic runtime as an identifier for function\n *   calls: `<x />` to `React.createElement('x')` (default:\n *   `'React.createElement'`);\n *   when changing this, you should also define `pragmaFrag` and\n *   `pragmaImportSource` too.\n *\n *   > 👉 **Note**: support for the classic runtime is deprecated and will\n *   > likely be removed in the next major version.\n * @property {string | null | undefined} [pragmaFrag='React.Fragment']\n *   Pragma for fragment symbol, used in the classic runtime as an identifier\n *   for unnamed calls: `<>` to `React.createElement(React.Fragment)` (default:\n *   `'React.Fragment'`);\n *   when changing this, you should also define `pragma` and\n *   `pragmaImportSource` too.\n *\n *   > 👉 **Note**: support for the classic runtime is deprecated and will\n *   > likely be removed in the next major version.\n * @property {string | null | undefined} [pragmaImportSource='react']\n *   Where to import the identifier of `pragma` from, used in the classic\n *   runtime (default: `'react'`);\n *   to illustrate, when `pragma` is `'a.b'` and `pragmaImportSource` is `'c'`\n *   the following will be generated: `import a from 'c'` and things such as\n *   `a.b('h1', {})`.\n *   when changing this, you should also define `pragma` and `pragmaFrag` too.\n *\n *   > 👉 **Note**: support for the classic runtime is deprecated and will\n *   > likely be removed in the next major version.\n * @property {string | null | undefined} [providerImportSource]\n *   Place to import a provider from (optional, example: `'@mdx-js/react'`);\n *   normally it’s used for runtimes that support context (React, Preact), but\n *   it can be used to inject components into the compiled code;\n *   the module must export and identifier `useMDXComponents` which is called\n *   without arguments to get an object of components (`MDXComponents` from\n *   `mdx/types.js`).\n * @property {PluggableList | null | undefined} [recmaPlugins]\n *   List of recma plugins (optional).\n * @property {PluggableList | null | undefined} [remarkPlugins]\n *   List of remark plugins (optional).\n * @property {PluggableList | null | undefined} [rehypePlugins]\n *   List of rehype plugins (optional).\n * @property {Readonly<RemarkRehypeOptions> | null | undefined} [remarkRehypeOptions]\n *   Options to pass to `remark-rehype` (optional);\n *   in particular, you might want to pass configuration for footnotes if your\n *   content is not in English;\n *   the option `allowDangerousHtml` will always be set to `true` and the MDX\n *   nodes (see `nodeTypes`) are passed through.\n * @property {RehypeRecmaOptions['stylePropertyNameCase']} [stylePropertyNameCase='dom']\n *   Casing to use for property names in `style` objects (default: `'dom'`);\n *   CSS casing is for example `background-color` and `-webkit-line-clamp`;\n *   DOM casing is for example `backgroundColor` and `WebkitLineClamp`;\n *   for JSX components written in MDX, the author has to be aware of which\n *   framework they use and write code accordingly;\n *   for AST nodes generated by this project, this option configures it\n * @property {boolean | null | undefined} [tableCellAlignToStyle=true]\n *   Turn obsolete `align` properties on `td` and `th` into CSS `style`\n *   properties (default: `true`).\n */\n\nimport {unreachable} from 'devlop'\nimport recmaBuildJsx from 'recma-build-jsx'\nimport recmaJsx from 'recma-jsx'\nimport recmaStringify from 'recma-stringify'\nimport rehypeRecma from 'rehype-recma'\nimport remarkMdx from 'remark-mdx'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport {unified} from 'unified'\nimport {recmaBuildJsxTransform} from './plugin/recma-build-jsx-transform.js'\nimport {recmaDocument} from './plugin/recma-document.js'\nimport {recmaJsxRewrite} from './plugin/recma-jsx-rewrite.js'\nimport {rehypeRemoveRaw} from './plugin/rehype-remove-raw.js'\nimport {remarkMarkAndUnravel} from './plugin/remark-mark-and-unravel.js'\nimport {nodeTypes} from './node-types.js'\n\nconst removedOptions = [\n  'compilers',\n  'filepath',\n  'hastPlugins',\n  'mdPlugins',\n  'skipExport',\n  'wrapExport'\n]\n\nlet warned = false\n\n/**\n * Create a processor to compile markdown or MDX to JavaScript.\n *\n * > **Note**: `format: 'detect'` is not allowed in `ProcessorOptions`.\n *\n * @param {Readonly<ProcessorOptions> | null | undefined} [options]\n *   Configuration (optional).\n * @return {Processor<Root, Program, Program, Program, string>}\n *   Processor.\n */\nexport function createProcessor(options) {\n  const settings = options || {}\n  let index = -1\n\n  while (++index < removedOptions.length) {\n    const key = removedOptions[index]\n    if (key in settings) {\n      unreachable(\n        'Unexpected removed option `' +\n          key +\n          '`; see <https://mdxjs.com/migrating/v2/> on how to migrate'\n      )\n    }\n  }\n\n  // @ts-expect-error: throw an error for a runtime value which is not allowed\n  // by the types.\n  if (settings.format === 'detect') {\n    unreachable(\n      \"Unexpected `format: 'detect'`, which is not supported by `createProcessor`, expected `'mdx'` or `'md'`\"\n    )\n  }\n\n  if (\n    (settings.jsxRuntime === 'classic' ||\n      settings.pragma ||\n      settings.pragmaFrag ||\n      settings.pragmaImportSource) &&\n    !warned\n  ) {\n    warned = true\n    console.warn(\n      \"Unexpected deprecated option `jsxRuntime: 'classic'`, `pragma`, `pragmaFrag`, or `pragmaImportSource`; see <https://mdxjs.com/migrating/v3/> on how to migrate\"\n    )\n  }\n\n  const pipeline = unified().use(remarkParse)\n\n  if (settings.format !== 'md') {\n    pipeline.use(remarkMdx)\n  }\n\n  const remarkRehypeOptions = settings.remarkRehypeOptions || {}\n\n  pipeline\n    .use(remarkMarkAndUnravel)\n    .use(settings.remarkPlugins || [])\n    .use(remarkRehype, {\n      ...remarkRehypeOptions,\n      allowDangerousHtml: true,\n      passThrough: [...(remarkRehypeOptions.passThrough || []), ...nodeTypes]\n    })\n    .use(settings.rehypePlugins || [])\n\n  if (settings.format === 'md') {\n    pipeline.use(rehypeRemoveRaw)\n  }\n\n  pipeline\n    // @ts-expect-error: `Program` is close enough to a `Node`,\n    // but type inference has trouble with it and bridges.\n    .use(rehypeRecma, settings)\n    .use(recmaDocument, settings)\n    .use(recmaJsxRewrite, settings)\n\n  if (!settings.jsx) {\n    pipeline.use(recmaBuildJsx, settings).use(recmaBuildJsxTransform, settings)\n  }\n\n  pipeline\n    .use(recmaJsx)\n    .use(recmaStringify, settings)\n    .use(settings.recmaPlugins || [])\n\n  // @ts-expect-error: TS doesn’t get the plugins we added with if-statements.\n  return pipeline\n}\n"
  },
  {
    "path": "packages/mdx/lib/evaluate.js",
    "content": "/**\n * @import {MDXModule} from 'mdx/types.js'\n * @import {Compatible} from 'vfile'\n * @import {EvaluateOptions} from './util/resolve-evaluate-options.js'\n */\n\nimport {resolveEvaluateOptions} from './util/resolve-evaluate-options.js'\nimport {compile, compileSync} from './compile.js'\nimport {run, runSync} from './run.js'\n\n/**\n * Compile and run MDX.\n *\n * When you trust your content, `evaluate` can work.\n * When possible, use `compile`, write to a file, and then run with Node or use\n * one of the integrations.\n *\n * > ☢️ **Danger**: it’s called **evaluate** because it `eval`s JavaScript.\n *\n * ###### Notes\n *\n * Compiling (and running) MDX takes time.\n *\n * If you are live-rendering a string of MDX that often changes using a virtual\n * DOM based framework (such as React), one performance improvement is to call\n * the `MDXContent` component yourself.\n * The reason is that the `evaluate` creates a new function each time, which\n * cannot be diffed:\n *\n * ```diff\n *  const {default: MDXContent} = await evaluate('…')\n *\n * -<MDXContent {...props} />\n * +MDXContent(props)\n * ```\n *\n * @param {Readonly<Compatible>} file\n *   MDX document to parse.\n * @param {Readonly<EvaluateOptions>} options\n *   Configuration (**required**).\n * @return {Promise<MDXModule>}\n *   Promise to a module;\n *   the result is an object with a `default` field set to the component;\n *   anything else that was exported is available too.\n\n */\nexport async function evaluate(file, options) {\n  const {compiletime, runtime} = resolveEvaluateOptions(options)\n  return run(await compile(file, compiletime), runtime)\n}\n\n/**\n * Compile and run MDX, synchronously.\n *\n * When possible please use the async `evaluate`.\n *\n * > ☢️ **Danger**: it’s called **evaluate** because it `eval`s JavaScript.\n *\n * @param {Readonly<Compatible>} file\n *   MDX document to parse.\n * @param {Readonly<EvaluateOptions>} options\n *   Configuration (**required**).\n * @return {MDXModule}\n *   Module.\n */\nexport function evaluateSync(file, options) {\n  const {compiletime, runtime} = resolveEvaluateOptions(options)\n  return runSync(compileSync(file, compiletime), runtime)\n}\n"
  },
  {
    "path": "packages/mdx/lib/node-types.js",
    "content": "/**\n * List of node types made by `mdast-util-mdx`, which have to be passed\n * through untouched from the mdast tree to the hast tree.\n */\nexport const nodeTypes = /** @type {const} */ ([\n  'mdxFlowExpression',\n  'mdxJsxFlowElement',\n  'mdxJsxTextElement',\n  'mdxTextExpression',\n  'mdxjsEsm'\n])\n"
  },
  {
    "path": "packages/mdx/lib/plugin/recma-build-jsx-transform.js",
    "content": "/**\n * @import {Program} from 'estree-jsx'\n */\n\n/**\n * @typedef Options\n *   Configuration for internal plugin `recma-build-jsx-transform`.\n * @property {'function-body' | 'program' | null | undefined} [outputFormat='program']\n *   Whether to keep the import of the automatic runtime or get it from\n *   `arguments[0]` instead (default: `'program'`).\n */\n\nimport {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'\nimport {toIdOrMemberExpression} from '../util/estree-util-to-id-or-member-expression.js'\n\n/**\n * Plugin to change the tree after compiling JSX away.\n *\n * @param {Readonly<Options> | null | undefined} [options]\n *   Configuration (optional).\n * @returns\n *   Transform.\n */\nexport function recmaBuildJsxTransform(options) {\n  /* c8 ignore next -- always given in `@mdx-js/mdx` */\n  const {outputFormat} = options || {}\n\n  /**\n   * @param {Program} tree\n   *   Tree.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree) {\n    // Remove the pragma comment that we injected ourselves as it is no longer\n    // needed.\n    if (tree.comments) {\n      tree.comments = tree.comments.filter(function (d) {\n        return !d.data?._mdxIsPragmaComment\n      })\n    }\n\n    // When compiling to a function body, replace the import that was just\n    // generated, and get `jsx`, `jsxs`, and `Fragment` from `arguments[0]`\n    // instead.\n    if (outputFormat === 'function-body') {\n      let index = 0\n\n      // Skip directives: JS currently only has `use strict`, but Acorn allows\n      // arbitrary ones.\n      // Practically things like `use client` could be used?\n      while (index < tree.body.length) {\n        const child = tree.body[index]\n        if ('directive' in child && child.directive) {\n          index++\n        } else {\n          break\n        }\n      }\n\n      const declaration = tree.body[index]\n\n      if (\n        declaration &&\n        declaration.type === 'ImportDeclaration' &&\n        typeof declaration.source.value === 'string' &&\n        /\\/jsx-(dev-)?runtime$/.test(declaration.source.value)\n      ) {\n        tree.body[index] = {\n          type: 'VariableDeclaration',\n          kind: 'const',\n          declarations: specifiersToDeclarations(\n            declaration.specifiers,\n            toIdOrMemberExpression(['arguments', 0])\n          )\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/mdx/lib/plugin/recma-document.js",
    "content": "/**\n * @import {\n      CallExpression,\n      Directive,\n      ExportAllDeclaration,\n      ExportDefaultDeclaration,\n      ExportNamedDeclaration,\n      ExportSpecifier,\n      Expression,\n      FunctionDeclaration,\n      Identifier,\n      ImportDeclaration,\n      ImportDefaultSpecifier,\n      ImportExpression,\n      ImportSpecifier,\n      JSXElement,\n      JSXFragment,\n      Literal,\n      ModuleDeclaration,\n      Node,\n      Program,\n      Property,\n      SimpleLiteral,\n      SpreadElement,\n      Statement,\n      VariableDeclarator\n * } from 'estree-jsx'\n * @import {VFile} from 'vfile'\n * @import {ProcessorOptions} from '../core.js'\n */\n\nimport {ok as assert} from 'devlop'\nimport {createVisitors} from 'estree-util-scope'\nimport {walk} from 'estree-walker'\nimport {positionFromEstree} from 'unist-util-position-from-estree'\nimport {stringifyPosition} from 'unist-util-stringify-position'\nimport {create} from '../util/estree-util-create.js'\nimport {declarationToExpression} from '../util/estree-util-declaration-to-expression.js'\nimport {isDeclaration} from '../util/estree-util-is-declaration.js'\nimport {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'\nimport {toIdOrMemberExpression} from '../util/estree-util-to-id-or-member-expression.js'\n\n/**\n * Wrap the estree in `MDXContent`.\n *\n * @param {Readonly<ProcessorOptions>} options\n *   Configuration.\n * @returns\n *   Transform.\n */\nexport function recmaDocument(options) {\n  const baseUrl = options.baseUrl || undefined\n  const baseHref = typeof baseUrl === 'object' ? baseUrl.href : baseUrl\n  const outputFormat = options.outputFormat || 'program'\n  const pragma =\n    options.pragma === undefined ? 'React.createElement' : options.pragma\n  const pragmaFrag =\n    options.pragmaFrag === undefined ? 'React.Fragment' : options.pragmaFrag\n  const pragmaImportSource = options.pragmaImportSource || 'react'\n  const jsxImportSource = options.jsxImportSource || 'react'\n  const jsxRuntime = options.jsxRuntime || 'automatic'\n\n  /**\n   * @param {Program} tree\n   *   Tree.\n   * @param {VFile} file\n   *   File.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree, file) {\n    /** @type {Array<[string, string] | string>} */\n    const exportedValues = []\n    /** @type {Array<Directive | ModuleDeclaration | Statement>} */\n    const replacement = []\n    let exportAllCount = 0\n    /** @type {ExportDefaultDeclaration | ExportSpecifier | undefined} */\n    let layout\n    /** @type {boolean | undefined} */\n    let content\n    /** @type {Node} */\n    let child\n\n    if (jsxRuntime === 'classic' && pragmaFrag) {\n      injectPragma(tree, '@jsxFrag', pragmaFrag)\n    }\n\n    if (jsxRuntime === 'classic' && pragma) {\n      injectPragma(tree, '@jsx', pragma)\n    }\n\n    if (jsxRuntime === 'automatic' && jsxImportSource) {\n      injectPragma(tree, '@jsxImportSource', jsxImportSource)\n    }\n\n    if (jsxRuntime) {\n      injectPragma(tree, '@jsxRuntime', jsxRuntime)\n    }\n\n    if (jsxRuntime === 'classic' && pragmaImportSource) {\n      if (!pragma) {\n        throw new Error(\n          'Missing `pragma` in classic runtime with `pragmaImportSource`'\n        )\n      }\n\n      handleEsm({\n        type: 'ImportDeclaration',\n        specifiers: [\n          {\n            type: 'ImportDefaultSpecifier',\n            local: {type: 'Identifier', name: pragma.split('.')[0]}\n          }\n        ],\n        attributes: [],\n        source: {type: 'Literal', value: pragmaImportSource}\n      })\n    }\n\n    // Find the `export default`, the JSX expression, and leave the rest\n    // (import/exports) as they are.\n    for (child of tree.body) {\n      // ```tsx\n      // export default properties => <>{properties.children}</>\n      // ```\n      //\n      // Treat it as an inline layout declaration.\n      if (child.type === 'ExportDefaultDeclaration') {\n        if (layout) {\n          file.fail(\n            'Unexpected duplicate layout, expected a single layout (previous: ' +\n              stringifyPosition(positionFromEstree(layout)) +\n              ')',\n            {\n              ancestors: [tree, child],\n              place: positionFromEstree(child),\n              ruleId: 'duplicate-layout',\n              source: 'recma-document'\n            }\n          )\n        }\n\n        layout = child\n        replacement.push({\n          type: 'VariableDeclaration',\n          kind: 'const',\n          declarations: [\n            {\n              type: 'VariableDeclarator',\n              id: {type: 'Identifier', name: 'MDXLayout'},\n              init: isDeclaration(child.declaration)\n                ? declarationToExpression(child.declaration)\n                : child.declaration\n            }\n          ]\n        })\n      }\n      // ```tsx\n      // export {a, b as c} from 'd'\n      // ```\n      else if (child.type === 'ExportNamedDeclaration' && child.source) {\n        // Cast because always simple.\n        const source = /** @type {SimpleLiteral} */ (child.source)\n\n        // Remove `default` or `as default`, but not `default as`, specifier.\n        child.specifiers = child.specifiers.filter(function (specifier) {\n          if (\n            specifier.exported.type === 'Identifier' &&\n            specifier.exported.name === 'default'\n          ) {\n            if (layout) {\n              file.fail(\n                'Unexpected duplicate layout, expected a single layout (previous: ' +\n                  stringifyPosition(positionFromEstree(layout)) +\n                  ')',\n                {\n                  ancestors: [tree, child, specifier],\n                  place: positionFromEstree(child),\n                  ruleId: 'duplicate-layout',\n                  source: 'recma-document'\n                }\n              )\n            }\n\n            layout = specifier\n\n            // Make it just an import: `import MDXLayout from '…'`.\n            /** @type {Array<ImportDefaultSpecifier | ImportSpecifier>} */\n            const specifiers = []\n\n            // Default as default / something else as default.\n            if (\n              specifier.local.type === 'Identifier' &&\n              specifier.local.name === 'default'\n            ) {\n              specifiers.push({\n                type: 'ImportDefaultSpecifier',\n                local: {type: 'Identifier', name: 'MDXLayout'}\n              })\n            } else {\n              /** @type {ImportSpecifier} */\n              const importSpecifier = {\n                type: 'ImportSpecifier',\n                imported: specifier.local,\n                local: {type: 'Identifier', name: 'MDXLayout'}\n              }\n              create(specifier.local, importSpecifier)\n              specifiers.push(importSpecifier)\n            }\n\n            /** @type {Literal} */\n            const from = {type: 'Literal', value: source.value}\n            create(source, from)\n\n            /** @type {ImportDeclaration} */\n            const declaration = {\n              type: 'ImportDeclaration',\n              specifiers,\n              attributes: [],\n              source: from\n            }\n            create(specifier, declaration)\n            handleEsm(declaration)\n\n            return false\n          }\n\n          return true\n        })\n\n        // If there are other things imported, keep it.\n        if (child.specifiers.length > 0) {\n          handleExport(child)\n        }\n      }\n      // ```tsx\n      // export {a, b as c}\n      // export * from 'a'\n      // ```\n      else if (\n        child.type === 'ExportNamedDeclaration' ||\n        child.type === 'ExportAllDeclaration'\n      ) {\n        handleExport(child)\n      } else if (child.type === 'ImportDeclaration') {\n        handleEsm(child)\n      } else if (\n        child.type === 'ExpressionStatement' &&\n        (child.expression.type === 'JSXElement' ||\n          child.expression.type === 'JSXFragment')\n      ) {\n        content = true\n        replacement.push(\n          ...createMdxContent(child.expression, outputFormat, Boolean(layout))\n        )\n      } else {\n        // This catch-all branch is because plugins might add other things.\n        // Normally, we only have import/export/jsx, but just add whatever’s\n        // there.\n        replacement.push(child)\n      }\n    }\n\n    // If there was no JSX content at all, add an empty function.\n    if (!content) {\n      replacement.push(\n        ...createMdxContent(undefined, outputFormat, Boolean(layout))\n      )\n    }\n\n    exportedValues.push(['MDXContent', 'default'])\n\n    if (outputFormat === 'function-body') {\n      replacement.push({\n        type: 'ReturnStatement',\n        argument: {\n          type: 'ObjectExpression',\n          properties: [\n            ...Array.from({length: exportAllCount}).map(\n              /**\n               * @param {undefined} _\n               *   Nothing.\n               * @param {number} index\n               *   Index.\n               * @returns {SpreadElement}\n               *   Node.\n               */\n              function (_, index) {\n                return {\n                  type: 'SpreadElement',\n                  argument: {\n                    type: 'Identifier',\n                    name: '_exportAll' + (index + 1)\n                  }\n                }\n              }\n            ),\n            ...exportedValues.map(function (d) {\n              /** @type {Property} */\n              const property = {\n                type: 'Property',\n                kind: 'init',\n                method: false,\n                computed: false,\n                shorthand: typeof d === 'string',\n                key: {\n                  type: 'Identifier',\n                  name: typeof d === 'string' ? d : d[1]\n                },\n                value: {\n                  type: 'Identifier',\n                  name: typeof d === 'string' ? d : d[0]\n                }\n              }\n\n              return property\n            })\n          ]\n        }\n      })\n    }\n\n    tree.body = replacement\n\n    let usesImportMetaUrlVariable = false\n    let usesResolveDynamicHelper = false\n\n    if (baseHref || outputFormat === 'function-body') {\n      walk(tree, {\n        enter(node) {\n          if (\n            (node.type === 'ExportAllDeclaration' ||\n              node.type === 'ExportNamedDeclaration' ||\n              node.type === 'ImportDeclaration') &&\n            node.source\n          ) {\n            // We never hit this branch when generating function bodies, as\n            // statements are already compiled away into import expressions.\n            assert(baseHref, 'unexpected missing `baseHref` in branch')\n\n            let value = node.source.value\n            // The literal source for statements can only be string.\n            assert(typeof value === 'string', 'expected string source')\n\n            // Resolve a specifier.\n            // This is the same as `_resolveDynamicMdxSpecifier`, which has to\n            // be injected to work with expressions at runtime, but as we have\n            // `baseHref` at compile time here and statements are static\n            // strings, we can do it now.\n            try {\n              // To do: next major: use `URL.canParse`.\n              // eslint-disable-next-line no-new\n              new URL(value)\n              // Fine: a full URL.\n            } catch {\n              if (\n                value.startsWith('/') ||\n                value.startsWith('./') ||\n                value.startsWith('../')\n              ) {\n                value = new URL(value, baseHref).href\n              } else {\n                // Fine: are bare specifier.\n              }\n            }\n\n            /** @type {SimpleLiteral} */\n            const replacement = {type: 'Literal', value}\n            create(node.source, replacement)\n            node.source = replacement\n            return\n          }\n\n          if (node.type === 'ImportExpression') {\n            usesResolveDynamicHelper = true\n            /** @type {CallExpression} */\n            const replacement = {\n              type: 'CallExpression',\n              callee: {type: 'Identifier', name: '_resolveDynamicMdxSpecifier'},\n              arguments: [node.source],\n              optional: false\n            }\n            node.source = replacement\n            return\n          }\n\n          // To do: add support for `import.meta.resolve`.\n\n          if (\n            node.type === 'MemberExpression' &&\n            'object' in node &&\n            node.object.type === 'MetaProperty' &&\n            node.property.type === 'Identifier' &&\n            node.object.meta.name === 'import' &&\n            node.object.property.name === 'meta' &&\n            node.property.name === 'url'\n          ) {\n            usesImportMetaUrlVariable = true\n            /** @type {Identifier} */\n            const replacement = {type: 'Identifier', name: '_importMetaUrl'}\n            create(node, replacement)\n            this.replace(replacement)\n          }\n        }\n      })\n    }\n\n    if (usesResolveDynamicHelper) {\n      if (!baseHref) {\n        usesImportMetaUrlVariable = true\n      }\n\n      tree.body.push(\n        resolveDynamicMdxSpecifier(\n          baseHref\n            ? {type: 'Literal', value: baseHref}\n            : {type: 'Identifier', name: '_importMetaUrl'}\n        )\n      )\n    }\n\n    if (usesImportMetaUrlVariable) {\n      assert(\n        outputFormat === 'function-body',\n        'expected `function-body` when using dynamic url injection'\n      )\n      tree.body.unshift(...createImportMetaUrlVariable())\n    }\n\n    /**\n     * @param {ExportAllDeclaration | ExportNamedDeclaration} node\n     *   Export node.\n     * @returns {undefined}\n     *   Nothing.\n     */\n    function handleExport(node) {\n      if (node.type === 'ExportNamedDeclaration') {\n        // ```tsx\n        // export function a() {}\n        // export class A {}\n        // export var a = 1\n        // ```\n        if (node.declaration) {\n          const visitors = createVisitors()\n          // Walk the top-level scope.\n          walk(node, {\n            enter(node) {\n              visitors.enter(node)\n\n              if (\n                node.type === 'ArrowFunctionExpression' ||\n                node.type === 'FunctionDeclaration' ||\n                node.type === 'FunctionExpression'\n              ) {\n                this.skip()\n                visitors.exit(node)\n              }\n            },\n            leave: visitors.exit\n          })\n          exportedValues.push(...visitors.scopes[0].defined)\n        }\n\n        // ```tsx\n        // export {a, b as c}\n        // export {a, b as c} from 'd'\n        // ```\n        for (child of node.specifiers) {\n          if (child.exported.type === 'Identifier') {\n            exportedValues.push(child.exported.name)\n            /* c8 ignore next 5 -- to do: <https://github.com/mdx-js/mdx/issues/2536> */\n          } else {\n            // Must be string.\n            assert(typeof child.exported.value === 'string')\n            exportedValues.push(child.exported.value)\n          }\n        }\n      }\n\n      handleEsm(node)\n    }\n\n    /**\n     * @param {ExportAllDeclaration | ExportNamedDeclaration | ImportDeclaration} node\n     *   Export or import node.\n     * @returns {undefined}\n     *   Nothing.\n     */\n    function handleEsm(node) {\n      /** @type {ModuleDeclaration | Statement | undefined} */\n      let replace\n      /** @type {Expression} */\n      let init\n\n      if (outputFormat === 'function-body') {\n        if (\n          // Always have a source:\n          node.type === 'ImportDeclaration' ||\n          node.type === 'ExportAllDeclaration' ||\n          // Source optional:\n          (node.type === 'ExportNamedDeclaration' && node.source)\n        ) {\n          // We always have a source, but types say they can be missing.\n          assert(node.source, 'expected `node.source` to be defined')\n\n          // ```\n          // import 'a'\n          // //=> await import('a')\n          // import a from 'b'\n          // //=> const {default: a} = await import('b')\n          // export {a, b as c} from 'd'\n          // //=> const {a, c: b} = await import('d')\n          // export * from 'a'\n          // //=> const _exportAll0 = await import('a')\n          // ```\n          /** @type {ImportExpression} */\n          const argument = {type: 'ImportExpression', source: node.source}\n          create(node, argument)\n          init = {type: 'AwaitExpression', argument}\n\n          if (\n            (node.type === 'ImportDeclaration' ||\n              node.type === 'ExportNamedDeclaration') &&\n            node.specifiers.length === 0\n          ) {\n            replace = {type: 'ExpressionStatement', expression: init}\n          } else {\n            replace = {\n              type: 'VariableDeclaration',\n              kind: 'const',\n              declarations:\n                node.type === 'ExportAllDeclaration'\n                  ? [\n                      {\n                        type: 'VariableDeclarator',\n                        id: {\n                          type: 'Identifier',\n                          name: '_exportAll' + ++exportAllCount\n                        },\n                        init\n                      }\n                    ]\n                  : specifiersToDeclarations(node.specifiers, init)\n            }\n          }\n        } else if (node.declaration) {\n          replace = node.declaration\n        } else {\n          /** @type {Array<VariableDeclarator>} */\n          const declarators = []\n\n          for (const specifier of node.specifiers) {\n            // `id` can only be an identifier,\n            // so we ignore literal.\n            if (\n              specifier.exported.type === 'Identifier' &&\n              specifier.local.type === 'Identifier' &&\n              specifier.local.name !== specifier.exported.name\n            ) {\n              declarators.push({\n                type: 'VariableDeclarator',\n                id: specifier.exported,\n                init: specifier.local\n              })\n            }\n          }\n\n          if (declarators.length > 0) {\n            replace = {\n              type: 'VariableDeclaration',\n              kind: 'const',\n              declarations: declarators\n            }\n          }\n        }\n      } else {\n        replace = node\n      }\n\n      if (replace) {\n        replacement.push(replace)\n      }\n    }\n  }\n\n  /**\n   * @param {Readonly<Expression> | undefined} content\n   *   Content.\n   * @param {'function-body' | 'program'} outputFormat\n   *   Output format.\n   * @param {boolean | undefined} [hasInternalLayout=false]\n   *   Whether there’s an internal layout (default: `false`).\n   * @returns {Array<ExportDefaultDeclaration | FunctionDeclaration>}\n   *   Functions.\n   */\n  function createMdxContent(content, outputFormat, hasInternalLayout) {\n    /** @type {JSXElement} */\n    const element = {\n      type: 'JSXElement',\n      openingElement: {\n        type: 'JSXOpeningElement',\n        name: {type: 'JSXIdentifier', name: 'MDXLayout'},\n        attributes: [\n          {\n            type: 'JSXSpreadAttribute',\n            argument: {type: 'Identifier', name: 'props'}\n          }\n        ],\n        selfClosing: false\n      },\n      closingElement: {\n        type: 'JSXClosingElement',\n        name: {type: 'JSXIdentifier', name: 'MDXLayout'}\n      },\n      children: [\n        {\n          type: 'JSXElement',\n          openingElement: {\n            type: 'JSXOpeningElement',\n            name: {type: 'JSXIdentifier', name: '_createMdxContent'},\n            attributes: [\n              {\n                type: 'JSXSpreadAttribute',\n                argument: {type: 'Identifier', name: 'props'}\n              }\n            ],\n            selfClosing: true\n          },\n          closingElement: null,\n          children: []\n        }\n      ]\n    }\n\n    let result = /** @type {Expression} */ (element)\n\n    if (!hasInternalLayout) {\n      result = {\n        type: 'ConditionalExpression',\n        test: {type: 'Identifier', name: 'MDXLayout'},\n        consequent: result,\n        alternate: {\n          type: 'CallExpression',\n          callee: {type: 'Identifier', name: '_createMdxContent'},\n          arguments: [{type: 'Identifier', name: 'props'}],\n          optional: false\n        }\n      }\n    }\n\n    let argument =\n      // Cast because TS otherwise does not think `JSXFragment`s are expressions.\n      /** @type {Readonly<Expression> | Readonly<JSXFragment>} */ (\n        content || {type: 'Identifier', name: 'undefined'}\n      )\n\n    // Unwrap a fragment of a single element.\n    if (\n      argument.type === 'JSXFragment' &&\n      argument.children.length === 1 &&\n      argument.children[0].type === 'JSXElement'\n    ) {\n      argument = argument.children[0]\n    }\n\n    let awaitExpression = false\n\n    walk(argument, {\n      enter(node) {\n        if (\n          node.type === 'ArrowFunctionExpression' ||\n          node.type === 'FunctionDeclaration' ||\n          node.type === 'FunctionExpression'\n        ) {\n          return this.skip()\n        }\n\n        if (\n          node.type === 'AwaitExpression' ||\n          /* c8 ignore next 2 -- can only occur in a function (which then can\n           * only be async, so skipped it) */\n          (node.type === 'ForOfStatement' && node.await)\n        ) {\n          awaitExpression = true\n        }\n      }\n    })\n\n    /** @type {FunctionDeclaration} */\n    const declaration = {\n      type: 'FunctionDeclaration',\n      id: {type: 'Identifier', name: 'MDXContent'},\n      params: [\n        {\n          type: 'AssignmentPattern',\n          left: {type: 'Identifier', name: 'props'},\n          right: {type: 'ObjectExpression', properties: []}\n        }\n      ],\n      body: {\n        type: 'BlockStatement',\n        body: [{type: 'ReturnStatement', argument: result}]\n      }\n    }\n\n    return [\n      {\n        type: 'FunctionDeclaration',\n        async: awaitExpression,\n        id: {type: 'Identifier', name: '_createMdxContent'},\n        params: [{type: 'Identifier', name: 'props'}],\n        body: {\n          type: 'BlockStatement',\n          body: [\n            {\n              type: 'ReturnStatement',\n              // Cast because TS doesn’t think `JSXFragment` is an expression.\n              argument: /** @type {Expression} */ (argument)\n            }\n          ]\n        }\n      },\n      outputFormat === 'program'\n        ? {type: 'ExportDefaultDeclaration', declaration}\n        : declaration\n    ]\n  }\n}\n\n/**\n * @param {Program} tree\n * @param {string} name\n * @param {string} value\n * @returns {undefined}\n */\nfunction injectPragma(tree, name, value) {\n  tree.comments?.unshift({\n    type: 'Block',\n    value: name + ' ' + value,\n    data: {_mdxIsPragmaComment: true}\n  })\n}\n\n/**\n * @param {Expression} importMetaUrl\n * @returns {FunctionDeclaration}\n */\nfunction resolveDynamicMdxSpecifier(importMetaUrl) {\n  return {\n    type: 'FunctionDeclaration',\n    id: {type: 'Identifier', name: '_resolveDynamicMdxSpecifier'},\n    generator: false,\n    async: false,\n    params: [{type: 'Identifier', name: 'd'}],\n    body: {\n      type: 'BlockStatement',\n      body: [\n        {\n          type: 'IfStatement',\n          test: {\n            type: 'BinaryExpression',\n            left: {\n              type: 'UnaryExpression',\n              operator: 'typeof',\n              prefix: true,\n              argument: {type: 'Identifier', name: 'd'}\n            },\n            operator: '!==',\n            right: {type: 'Literal', value: 'string'}\n          },\n          consequent: {\n            type: 'ReturnStatement',\n            argument: {type: 'Identifier', name: 'd'}\n          },\n          alternate: null\n        },\n        // To do: use `URL.canParse` when widely supported (see commented\n        // out code below).\n        {\n          type: 'TryStatement',\n          block: {\n            type: 'BlockStatement',\n            body: [\n              {\n                type: 'ExpressionStatement',\n                expression: {\n                  type: 'NewExpression',\n                  callee: {type: 'Identifier', name: 'URL'},\n                  arguments: [{type: 'Identifier', name: 'd'}]\n                }\n              },\n              {\n                type: 'ReturnStatement',\n                argument: {type: 'Identifier', name: 'd'}\n              }\n            ]\n          },\n          handler: {\n            type: 'CatchClause',\n            param: null,\n            body: {type: 'BlockStatement', body: []}\n          },\n          finalizer: null\n        },\n        // To do: use `URL.canParse` when widely supported.\n        // {\n        //   type: 'IfStatement',\n        //   test: {\n        //     type: 'CallExpression',\n        //     callee: toIdOrMemberExpression(['URL', 'canParse']),\n        //     arguments: [{type: 'Identifier', name: 'd'}],\n        //     optional: false\n        //   },\n        //   consequent: {\n        //     type: 'ReturnStatement',\n        //     argument: {type: 'Identifier', name: 'd'}\n        //   },\n        //   alternate: null\n        // },\n        {\n          type: 'IfStatement',\n          test: {\n            type: 'LogicalExpression',\n            left: {\n              type: 'LogicalExpression',\n              left: {\n                type: 'CallExpression',\n                callee: toIdOrMemberExpression(['d', 'startsWith']),\n                arguments: [{type: 'Literal', value: '/'}],\n                optional: false\n              },\n              operator: '||',\n              right: {\n                type: 'CallExpression',\n                callee: toIdOrMemberExpression(['d', 'startsWith']),\n                arguments: [{type: 'Literal', value: './'}],\n                optional: false\n              }\n            },\n            operator: '||',\n            right: {\n              type: 'CallExpression',\n              callee: toIdOrMemberExpression(['d', 'startsWith']),\n              arguments: [{type: 'Literal', value: '../'}],\n              optional: false\n            }\n          },\n          consequent: {\n            type: 'ReturnStatement',\n            argument: {\n              type: 'MemberExpression',\n              object: {\n                type: 'NewExpression',\n                callee: {type: 'Identifier', name: 'URL'},\n                arguments: [{type: 'Identifier', name: 'd'}, importMetaUrl]\n              },\n              property: {type: 'Identifier', name: 'href'},\n              computed: false,\n              optional: false\n            }\n          },\n          alternate: null\n        },\n        {\n          type: 'ReturnStatement',\n          argument: {type: 'Identifier', name: 'd'}\n        }\n      ]\n    }\n  }\n}\n\n/**\n * @returns {Array<Statement>}\n */\nfunction createImportMetaUrlVariable() {\n  return [\n    {\n      type: 'VariableDeclaration',\n      declarations: [\n        {\n          type: 'VariableDeclarator',\n          id: {type: 'Identifier', name: '_importMetaUrl'},\n          init: toIdOrMemberExpression(['arguments', 0, 'baseUrl'])\n        }\n      ],\n      kind: 'const'\n    },\n    {\n      type: 'IfStatement',\n      test: {\n        type: 'UnaryExpression',\n        operator: '!',\n        prefix: true,\n        argument: {type: 'Identifier', name: '_importMetaUrl'}\n      },\n      consequent: {\n        type: 'ThrowStatement',\n        argument: {\n          type: 'NewExpression',\n          callee: {type: 'Identifier', name: 'Error'},\n          arguments: [\n            {\n              type: 'Literal',\n              value:\n                'Unexpected missing `options.baseUrl` needed to support `export … from`, `import`, or `import.meta.url` when generating `function-body`'\n            }\n          ]\n        }\n      },\n      alternate: null\n    }\n  ]\n}\n"
  },
  {
    "path": "packages/mdx/lib/plugin/recma-jsx-rewrite.js",
    "content": "/**\n * @import {\n      Expression,\n      Function as EstreeFunction,\n      Identifier,\n      ImportSpecifier,\n      JSXElement,\n      ModuleDeclaration,\n      ObjectPattern,\n      Program,\n      Property,\n      SpreadElement,\n      Statement,\n      VariableDeclarator\n * } from 'estree-jsx'\n * @import {Scope} from 'estree-util-scope'\n * @import {VFile} from 'vfile'\n * @import {ProcessorOptions} from '../core.js'\n */\n\n/**\n * @typedef StackEntry\n *   Entry.\n * @property {Array<string>} components\n *   Used components.\n * @property {Map<string, string>} idToInvalidComponentName\n *   Map of JSX identifiers which cannot be used as JS identifiers, to valid JS identifiers.\n * @property {Readonly<EstreeFunction>} node\n *   Function.\n * @property {Array<string>} objects\n *   Identifiers of used objects (such as `x` in `x.y`).\n * @property {Record<string, {node: Readonly<JSXElement>, component: boolean}>} references\n *   Map of JSX identifiers for components and objects, to where they were first used.\n * @property {Array<string>} tags\n *   Tag names.\n */\n\nimport {name as isIdentifierName} from 'estree-util-is-identifier-name'\nimport {createVisitors} from 'estree-util-scope'\nimport {walk} from 'estree-walker'\nimport {stringifyPosition} from 'unist-util-stringify-position'\nimport {positionFromEstree} from 'unist-util-position-from-estree'\nimport {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'\nimport {toBinaryAddition} from '../util/estree-util-to-binary-addition.js'\nimport {\n  toIdOrMemberExpression,\n  toJsxIdOrMemberExpression\n} from '../util/estree-util-to-id-or-member-expression.js'\n\n/**\n * A plugin that rewrites JSX in functions to accept components as\n * `props.components` (when the function is called `_createMdxContent`), or from\n * a provider (if there is one).\n * It also makes sure that any undefined components are defined: either from\n * received components or as a function that throws an error.\n *\n * @param {Readonly<ProcessorOptions>} options\n *   Configuration (optional).\n * @returns\n *   Transform.\n */\nexport function recmaJsxRewrite(options) {\n  const {development, outputFormat, providerImportSource} = options\n\n  /**\n   * @param {Program} tree\n   *   Tree.\n   * @param {VFile} file\n   *   File.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree, file) {\n    const visitors = createVisitors()\n    /** @type {Array<StackEntry>} */\n    const functionStack = []\n    let importProvider = false\n    let createErrorHelper = false\n\n    walk(tree, {\n      enter(node) {\n        visitors.enter(node)\n\n        if (\n          node.type === 'FunctionDeclaration' ||\n          node.type === 'FunctionExpression' ||\n          node.type === 'ArrowFunctionExpression'\n        ) {\n          functionStack.push({\n            components: [],\n            idToInvalidComponentName: new Map(),\n            node,\n            objects: [],\n            references: {},\n            tags: []\n          })\n\n          // `MDXContent` only ever contains `MDXLayout`.\n          if (\n            isNamedFunction(node, 'MDXContent') &&\n            !inScope(visitors.scopes, 'MDXLayout')\n          ) {\n            functionStack[0].components.push('MDXLayout')\n          }\n        }\n\n        const functionInfo = functionStack[0]\n\n        if (\n          !functionInfo ||\n          (!isNamedFunction(functionInfo.node, '_createMdxContent') &&\n            !providerImportSource)\n        ) {\n          return\n        }\n\n        if (node.type === 'JSXElement') {\n          let name = node.openingElement.name\n\n          // `<x.y>`, `<Foo.Bar>`, `<x.y.z>`.\n          if (name.type === 'JSXMemberExpression') {\n            /** @type {Array<string>} */\n            const ids = []\n\n            // Find the left-most identifier.\n            while (name.type === 'JSXMemberExpression') {\n              ids.unshift(name.property.name)\n              name = name.object\n            }\n\n            ids.unshift(name.name)\n            const fullId = ids.join('.')\n            const id = name.name\n            const isInScope = inScope(visitors.scopes, id)\n\n            if (\n              !Object.hasOwn(functionInfo.references, fullId) &&\n              (!isInScope ||\n                // If the parent scope is `_createMdxContent`, then this\n                // references a component we can add a check statement for.\n                (functionStack.length === 1 &&\n                  functionStack[0].node.type === 'FunctionDeclaration' &&\n                  isNamedFunction(functionStack[0].node, '_createMdxContent')))\n            ) {\n              functionInfo.references[fullId] = {component: true, node}\n            }\n\n            if (!functionInfo.objects.includes(id) && !isInScope) {\n              functionInfo.objects.push(id)\n            }\n          }\n          // `<xml:thing>`.\n          else if (name.type === 'JSXNamespacedName') {\n            // Ignore namespaces.\n          }\n          // If the name is a valid ES identifier, and it doesn’t start with a\n          // lowercase letter, it’s a component.\n          // For example, `$foo`, `_bar`, `Baz` are all component names.\n          // But `foo` and `b-ar` are tag names.\n          else if (isIdentifierName(name.name) && !/^[a-z]/.test(name.name)) {\n            const id = name.name\n\n            if (!inScope(visitors.scopes, id)) {\n              // No need to add an error for an undefined layout — we use an\n              // `if` later.\n              if (\n                id !== 'MDXLayout' &&\n                !Object.hasOwn(functionInfo.references, id)\n              ) {\n                functionInfo.references[id] = {component: true, node}\n              }\n\n              if (!functionInfo.components.includes(id)) {\n                functionInfo.components.push(id)\n              }\n            }\n          } else if (node.data && node.data._mdxExplicitJsx) {\n            // Do not turn explicit JSX into components from `_components`.\n            // As in, a given `h1` component is used for `# heading` (next case),\n            // but not for `<h1>heading</h1>`.\n          } else {\n            const id = name.name\n\n            if (!functionInfo.tags.includes(id)) {\n              functionInfo.tags.push(id)\n            }\n\n            /** @type {Array<number | string>} */\n            let jsxIdExpression = ['_components', id]\n            if (isIdentifierName(id) === false) {\n              let invalidComponentName =\n                functionInfo.idToInvalidComponentName.get(id)\n              if (invalidComponentName === undefined) {\n                invalidComponentName = `_component${functionInfo.idToInvalidComponentName.size}`\n                functionInfo.idToInvalidComponentName.set(\n                  id,\n                  invalidComponentName\n                )\n              }\n\n              jsxIdExpression = [invalidComponentName]\n            }\n\n            node.openingElement.name =\n              toJsxIdOrMemberExpression(jsxIdExpression)\n\n            if (node.closingElement) {\n              node.closingElement.name =\n                toJsxIdOrMemberExpression(jsxIdExpression)\n            }\n          }\n        }\n      },\n      leave(node) {\n        visitors.exit(node)\n\n        /** @type {Array<Property | SpreadElement>} */\n        const defaults = []\n        /** @type {Array<string>} */\n        const actual = []\n        /** @type {Array<Expression>} */\n        const parameters = []\n        /** @type {Array<VariableDeclarator>} */\n        const declarations = []\n\n        if (\n          node.type === 'FunctionDeclaration' ||\n          node.type === 'FunctionExpression' ||\n          node.type === 'ArrowFunctionExpression'\n        ) {\n          const functionInfo = functionStack[functionStack.length - 1]\n\n          /** @type {string} */\n          let name\n\n          for (name of functionInfo.tags.sort()) {\n            defaults.push({\n              type: 'Property',\n              kind: 'init',\n              key: isIdentifierName(name)\n                ? {type: 'Identifier', name}\n                : {type: 'Literal', value: name},\n              value: {type: 'Literal', value: name},\n              method: false,\n              shorthand: false,\n              computed: false\n            })\n          }\n\n          actual.push(...functionInfo.components)\n\n          for (name of functionInfo.objects) {\n            // In some cases, a component is used directly (`<X>`) but it’s also\n            // used as an object (`<X.Y>`).\n            if (!actual.includes(name)) {\n              actual.push(name)\n            }\n          }\n\n          actual.sort()\n\n          /** @type {Array<Statement>} */\n          const statements = []\n\n          if (\n            defaults.length > 0 ||\n            actual.length > 0 ||\n            functionInfo.idToInvalidComponentName.size > 0\n          ) {\n            if (providerImportSource) {\n              importProvider = true\n              parameters.push({\n                type: 'CallExpression',\n                callee: {type: 'Identifier', name: '_provideComponents'},\n                arguments: [],\n                optional: false\n              })\n            }\n\n            // Accept `components` as a prop if this is the `MDXContent` or\n            // `_createMdxContent` function.\n            if (\n              isNamedFunction(functionInfo.node, 'MDXContent') ||\n              isNamedFunction(functionInfo.node, '_createMdxContent')\n            ) {\n              parameters.push(toIdOrMemberExpression(['props', 'components']))\n            }\n\n            if (defaults.length > 0 || parameters.length > 1) {\n              for (const parameter of parameters) {\n                defaults.push({type: 'SpreadElement', argument: parameter})\n              }\n            }\n\n            // If we’re getting components from several sources, merge them.\n            /** @type {Expression} */\n            let componentsInit =\n              defaults.length > 0\n                ? {type: 'ObjectExpression', properties: defaults}\n                : // If we’re only getting components from `props.components`,\n                  // make sure it’s defined.\n                  {\n                    type: 'LogicalExpression',\n                    operator: '||',\n                    left: parameters[0],\n                    right: {type: 'ObjectExpression', properties: []}\n                  }\n\n            /** @type {ObjectPattern | undefined} */\n            let componentsPattern\n\n            // Add components to scope.\n            // For `['MyComponent', 'MDXLayout']` this generates:\n            // ```tsx\n            // const {MyComponent, wrapper: MDXLayout} = _components\n            // ```\n            // Note that MDXLayout is special as it’s taken from\n            // `_components.wrapper`.\n            if (actual.length > 0) {\n              componentsPattern = {\n                type: 'ObjectPattern',\n                properties: actual.map(function (name) {\n                  return {\n                    type: 'Property',\n                    kind: 'init',\n                    key: {\n                      type: 'Identifier',\n                      name: name === 'MDXLayout' ? 'wrapper' : name\n                    },\n                    value: {type: 'Identifier', name},\n                    method: false,\n                    shorthand: name !== 'MDXLayout',\n                    computed: false\n                  }\n                })\n              }\n            }\n\n            if (functionInfo.tags.length > 0) {\n              declarations.push({\n                type: 'VariableDeclarator',\n                id: {type: 'Identifier', name: '_components'},\n                init: componentsInit\n              })\n              componentsInit = {type: 'Identifier', name: '_components'}\n            }\n\n            if (isNamedFunction(functionInfo.node, '_createMdxContent')) {\n              for (const [id, componentName] of [\n                ...functionInfo.idToInvalidComponentName\n              ].sort(function ([a], [b]) {\n                return a.localeCompare(b)\n              })) {\n                // For JSX IDs that can’t be represented as JavaScript IDs (as in,\n                // those with dashes, such as `custom-element`), generate a\n                // separate variable that is a valid JS ID (such as `_component0`),\n                // and takes it from components:\n                // `const _component0 = _components['custom-element']`\n                declarations.push({\n                  type: 'VariableDeclarator',\n                  id: {\n                    type: 'Identifier',\n                    name: componentName\n                  },\n                  init: {\n                    type: 'MemberExpression',\n                    object: {type: 'Identifier', name: '_components'},\n                    property: {type: 'Literal', value: id},\n                    computed: true,\n                    optional: false\n                  }\n                })\n              }\n            }\n\n            if (componentsPattern) {\n              declarations.push({\n                type: 'VariableDeclarator',\n                id: componentsPattern,\n                init: componentsInit\n              })\n            }\n\n            if (declarations.length > 0) {\n              statements.push({\n                type: 'VariableDeclaration',\n                kind: 'const',\n                declarations\n              })\n            }\n          }\n\n          /** @type {string} */\n          let key\n\n          // Add partials (so for `x.y.z` it’d generate `x` and `x.y` too).\n          for (key in functionInfo.references) {\n            if (Object.hasOwn(functionInfo.references, key)) {\n              const parts = key.split('.')\n              let index = 0\n              while (++index < parts.length) {\n                const partial = parts.slice(0, index).join('.')\n                if (!Object.hasOwn(functionInfo.references, partial)) {\n                  functionInfo.references[partial] = {\n                    component: false,\n                    node: functionInfo.references[key].node\n                  }\n                }\n              }\n            }\n          }\n\n          const references = Object.keys(functionInfo.references).sort()\n\n          let index = -1\n          while (++index < references.length) {\n            const id = references[index]\n            const info = functionInfo.references[id]\n            const place = stringifyPosition(positionFromEstree(info.node))\n            /** @type {Array<Expression>} */\n            const parameters = [\n              {type: 'Literal', value: id},\n              {type: 'Literal', value: info.component}\n            ]\n\n            createErrorHelper = true\n\n            if (development && place) {\n              parameters.push({type: 'Literal', value: place})\n            }\n\n            statements.push({\n              type: 'IfStatement',\n              test: {\n                type: 'UnaryExpression',\n                operator: '!',\n                prefix: true,\n                argument: toIdOrMemberExpression(id.split('.'))\n              },\n              consequent: {\n                type: 'ExpressionStatement',\n                expression: {\n                  type: 'CallExpression',\n                  callee: {type: 'Identifier', name: '_missingMdxReference'},\n                  arguments: parameters,\n                  optional: false\n                }\n              },\n              alternate: undefined\n            })\n          }\n\n          if (statements.length > 0) {\n            // Arrow functions with an implied return:\n            if (node.body.type !== 'BlockStatement') {\n              node.body = {\n                type: 'BlockStatement',\n                body: [{type: 'ReturnStatement', argument: node.body}]\n              }\n            }\n\n            node.body.body.unshift(...statements)\n          }\n\n          functionStack.pop()\n        }\n      }\n    })\n\n    // If a provider is used (and can be used), import it.\n    if (importProvider && providerImportSource) {\n      tree.body.unshift(\n        createImportProvider(providerImportSource, outputFormat)\n      )\n    }\n\n    // If potentially missing components are used.\n    if (createErrorHelper) {\n      /** @type {Array<Expression>} */\n      const message = [\n        {type: 'Literal', value: 'Expected '},\n        {\n          type: 'ConditionalExpression',\n          test: {type: 'Identifier', name: 'component'},\n          consequent: {type: 'Literal', value: 'component'},\n          alternate: {type: 'Literal', value: 'object'}\n        },\n        {type: 'Literal', value: ' `'},\n        {type: 'Identifier', name: 'id'},\n        {\n          type: 'Literal',\n          value:\n            '` to be defined: you likely forgot to import, pass, or provide it.'\n        }\n      ]\n\n      /** @type {Array<Identifier>} */\n      const parameters = [\n        {type: 'Identifier', name: 'id'},\n        {type: 'Identifier', name: 'component'}\n      ]\n\n      if (development) {\n        message.push({\n          type: 'ConditionalExpression',\n          test: {type: 'Identifier', name: 'place'},\n          consequent: toBinaryAddition([\n            {type: 'Literal', value: '\\nIt’s referenced in your code at `'},\n            {type: 'Identifier', name: 'place'},\n            {\n              type: 'Literal',\n              value: (file.path ? '` in `' + file.path : '') + '`'\n            }\n          ]),\n          alternate: {type: 'Literal', value: ''}\n        })\n\n        parameters.push({type: 'Identifier', name: 'place'})\n      }\n\n      tree.body.push({\n        type: 'FunctionDeclaration',\n        id: {type: 'Identifier', name: '_missingMdxReference'},\n        generator: false,\n        async: false,\n        params: parameters,\n        body: {\n          type: 'BlockStatement',\n          body: [\n            {\n              type: 'ThrowStatement',\n              argument: {\n                type: 'NewExpression',\n                callee: {type: 'Identifier', name: 'Error'},\n                arguments: [toBinaryAddition(message)]\n              }\n            }\n          ]\n        }\n      })\n    }\n\n    if (outputFormat === 'function-body') {\n      tree.body.unshift({\n        type: 'ExpressionStatement',\n        expression: {type: 'Literal', value: 'use strict'},\n        directive: 'use strict'\n      })\n    }\n  }\n}\n\n/**\n * @param {string} providerImportSource\n *   Provider source.\n * @param {'function-body' | 'program' | null | undefined} outputFormat\n *   Format.\n * @returns {ModuleDeclaration | Statement}\n *   Node.\n */\nfunction createImportProvider(providerImportSource, outputFormat) {\n  /** @type {Array<ImportSpecifier>} */\n  const specifiers = [\n    {\n      type: 'ImportSpecifier',\n      imported: {type: 'Identifier', name: 'useMDXComponents'},\n      local: {type: 'Identifier', name: '_provideComponents'}\n    }\n  ]\n\n  return outputFormat === 'function-body'\n    ? {\n        type: 'VariableDeclaration',\n        kind: 'const',\n        declarations: specifiersToDeclarations(\n          specifiers,\n          toIdOrMemberExpression(['arguments', 0])\n        )\n      }\n    : {\n        type: 'ImportDeclaration',\n        specifiers,\n        attributes: [],\n        source: {type: 'Literal', value: providerImportSource}\n      }\n}\n\n/**\n * @param {Readonly<EstreeFunction>} node\n *   Node.\n * @param {string} name\n *   Name.\n * @returns {boolean}\n *   Whether `node` is a named function with `name`.\n */\nfunction isNamedFunction(node, name) {\n  return Boolean(node && 'id' in node && node.id && node.id.name === name)\n}\n\n/**\n * @param {Array<Scope>} scopes\n *   Scope.\n * @param {string} id\n *   Identifier.\n * @returns {boolean}\n *   Whether `id` is in `scope`.\n */\nfunction inScope(scopes, id) {\n  let index = scopes.length\n\n  while (index--) {\n    const scope = scopes[index]\n\n    if (scope.defined.includes(id)) {\n      return true\n    }\n  }\n\n  return false\n}\n"
  },
  {
    "path": "packages/mdx/lib/plugin/rehype-remove-raw.js",
    "content": "/**\n * @import {Root} from 'hast'\n */\n\nimport {visit} from 'unist-util-visit'\n\n/**\n * A tiny plugin that removes raw HTML.\n *\n * This is needed if the format is `md` and `rehype-raw` was not used to parse\n * dangerous HTML into nodes.\n *\n * @returns\n *   Transform.\n */\nexport function rehypeRemoveRaw() {\n  /**\n   * @param {Root} tree\n   *   Tree.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree) {\n    visit(tree, 'raw', function (_, index, parent) {\n      if (parent && typeof index === 'number') {\n        parent.children.splice(index, 1)\n        return index\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "packages/mdx/lib/plugin/remark-mark-and-unravel.js",
    "content": "/**\n * @import {Root, RootContent} from 'mdast'\n */\n\nimport {collapseWhiteSpace} from 'collapse-white-space'\nimport {walk} from 'estree-walker'\nimport {visit} from 'unist-util-visit'\n\n/**\n * A tiny plugin that unravels `<p><h1>x</h1></p>` but also\n * `<p><Component /></p>` (so it has no knowledge of “HTML”).\n *\n * It also marks JSX as being explicitly JSX, so when a user passes a `h1`\n * component, it is used for `# heading` but not for `<h1>heading</h1>`.\n *\n * @returns\n *   Transform.\n */\nexport function remarkMarkAndUnravel() {\n  /**\n   * @param {Root} tree\n   *   Tree.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree) {\n    visit(tree, function (node, index, parent) {\n      let offset = -1\n      let all = true\n      let oneOrMore = false\n\n      if (parent && typeof index === 'number' && node.type === 'paragraph') {\n        const children = node.children\n\n        while (++offset < children.length) {\n          const child = children[offset]\n\n          if (\n            child.type === 'mdxJsxTextElement' ||\n            child.type === 'mdxTextExpression'\n          ) {\n            oneOrMore = true\n          } else if (\n            child.type === 'text' &&\n            collapseWhiteSpace(child.value, {style: 'html', trim: true}) === ''\n          ) {\n            // Empty.\n          } else {\n            all = false\n            break\n          }\n        }\n\n        if (all && oneOrMore) {\n          offset = -1\n\n          /** @type {Array<RootContent>} */\n          const newChildren = []\n\n          while (++offset < children.length) {\n            const child = children[offset]\n\n            if (child.type === 'mdxJsxTextElement') {\n              // @ts-expect-error: mutate because it is faster; content model is fine.\n              child.type = 'mdxJsxFlowElement'\n            }\n\n            if (child.type === 'mdxTextExpression') {\n              // @ts-expect-error: mutate because it is faster; content model is fine.\n              child.type = 'mdxFlowExpression'\n            }\n\n            if (\n              child.type === 'text' &&\n              /^[\\t\\r\\n ]+$/.test(String(child.value))\n            ) {\n              // Empty.\n            } else {\n              newChildren.push(child)\n            }\n          }\n\n          parent.children.splice(index, 1, ...newChildren)\n          return index\n        }\n      }\n\n      if (\n        node.type === 'mdxJsxFlowElement' ||\n        node.type === 'mdxJsxTextElement'\n      ) {\n        const data = node.data || (node.data = {})\n        data._mdxExplicitJsx = true\n      }\n\n      if (\n        (node.type === 'mdxFlowExpression' ||\n          node.type === 'mdxTextExpression' ||\n          node.type === 'mdxjsEsm') &&\n        node.data &&\n        node.data.estree\n      ) {\n        walk(node.data.estree, {\n          enter(node) {\n            if (node.type === 'JSXElement') {\n              const data = node.data || (node.data = {})\n              data._mdxExplicitJsx = true\n            }\n          }\n        })\n      }\n    })\n  }\n}\n"
  },
  {
    "path": "packages/mdx/lib/run.js",
    "content": "/**\n * @import {MDXModule} from 'mdx/types.js'\n * @import {RunOptions} from './util/resolve-evaluate-options.js'\n */\n\n/** @type {new (code: string, ...args: Array<unknown>) => Function} **/\nconst AsyncFunction = Object.getPrototypeOf(run).constructor\n\n/**\n * Run code compiled with `outputFormat: 'function-body'`.\n *\n * > ☢️ **Danger**: this `eval`s JavaScript.\n *\n * @param {{toString(): string}} code\n *   JavaScript function body to run.\n * @param {RunOptions} options\n *   Configuration (**required**).\n * @return {Promise<MDXModule>}\n *   Promise to a module;\n *   the result is an object with a `default` field set to the component;\n *   anything else that was exported is available too.\n */\nexport async function run(code, options) {\n  return new AsyncFunction(String(code))(options)\n}\n\n/**\n * Run code, synchronously.\n *\n * When possible please use the async `run`.\n *\n * > ☢️ **Danger**: this `eval`s JavaScript.\n *\n * @param {{toString(): string}} code\n *   JavaScript function body to run.\n * @param {RunOptions} options\n *   Configuration (**required**).\n * @return {MDXModule}\n *   Module.\n */\nexport function runSync(code, options) {\n  // eslint-disable-next-line no-new-func\n  return new Function(String(code))(options)\n}\n"
  },
  {
    "path": "packages/mdx/lib/types.d.ts",
    "content": "import type {Program as EstreeProgram} from 'estree'\nimport type {Data as UnistData} from 'unist'\n\ninterface EsastData extends UnistData {\n  /**\n   * Whether a node was authored as explicit JSX (`<h1>`) or as implicitly\n   * turned into JSX (`# hi`).\n   *\n   * Registered by `@mdx-js/mdx/lib/types.d.ts`.\n   */\n  _mdxExplicitJsx?: boolean | null | undefined\n}\n\ninterface EsastCommentData extends EsastData {\n  /**\n   * Whether a node (only used on comments) was generated by us to include the\n   * JSX pragmas, so that when we compile JSX away, we can remove it.\n   *\n   * Registered by `@mdx-js/mdx/lib/types.d.ts`.\n   */\n  _mdxIsPragmaComment?: boolean | null | undefined\n}\n\n// Register data on `estree`.\ndeclare module 'estree' {\n  interface BaseNode {\n    /**\n     * Extra unist data passed through from mdast through hast to esast.\n     *\n     * Registered by `@mdx-js/mdx/lib/types.d.ts`.\n     */\n    data?: EsastData | undefined\n  }\n\n  interface Comment {\n    /**\n     * Extra unist data added by `recma-document`.\n     *\n     * Registered by `@mdx-js/mdx/lib/types.d.ts`.\n     */\n    data?: EsastCommentData | undefined\n  }\n}\n\n// Register data on `mdast`.\ndeclare module 'mdast-util-mdx-jsx' {\n  interface MdxJsxFlowElementData {\n    /**\n     * Whether a node was authored as explicit JSX (`<h1>`) or as implicitly\n     * turned into JSX (`# hi`).\n     *\n     * Registered by `@mdx-js/mdx/lib/types.d.ts`.\n     */\n    _mdxExplicitJsx?: boolean | null | undefined\n  }\n\n  interface MdxJsxTextElementData {\n    /**\n     * Whether a node was authored as explicit JSX (`<h1>`) or as implicitly\n     * turned into JSX (`# hi`).\n     *\n     * Registered by `@mdx-js/mdx/lib/types.d.ts`.\n     */\n    _mdxExplicitJsx?: boolean | null | undefined\n  }\n}\n\ndeclare module 'unified' {\n  interface CompileResultMap {\n    EstreeProgram: EstreeProgram\n  }\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/create-format-aware-processors.js",
    "content": "/**\n * @import {Program} from 'estree-jsx'\n * @import {Root} from 'mdast'\n * @import {Processor} from 'unified'\n * @import {Compatible, VFile} from 'vfile'\n * @import {CompileOptions} from '../compile.js'\n */\n\n/**\n * @typedef FormatAwareProcessors\n *   Result.\n * @property {ReadonlyArray<string>} extnames\n *   Extensions to use.\n * @property {Process} process\n *   Smart processor, async.\n *\n * @callback Process\n *   Smart processor.\n * @param {Compatible} vfileCompatible\n *   MDX or markdown document.\n * @return {Promise<VFile>}\n *   File.\n */\n\nimport {createProcessor} from '../core.js'\nimport {md, mdx} from './extnames.js'\nimport {resolveFileAndOptions} from './resolve-file-and-options.js'\n\n/**\n * Create smart processors to handle different formats.\n *\n * @param {Readonly<CompileOptions> | null | undefined} [compileOptions]\n *   Configuration (optional).\n * @return {FormatAwareProcessors}\n *   Smart processor.\n */\nexport function createFormatAwareProcessors(compileOptions) {\n  const compileOptions_ = compileOptions || {}\n  const mdExtensions = compileOptions_.mdExtensions || md\n  const mdxExtensions = compileOptions_.mdxExtensions || mdx\n  /** @type {Processor<Root, Program, Program, Program, string>} */\n  let cachedMarkdown\n  /** @type {Processor<Root, Program, Program, Program, string>} */\n  let cachedMdx\n\n  return {\n    extnames:\n      compileOptions_.format === 'md'\n        ? mdExtensions\n        : compileOptions_.format === 'mdx'\n          ? mdxExtensions\n          : [...mdExtensions, ...mdxExtensions],\n    process\n  }\n\n  /**\n   * Smart processor.\n   *\n   * @type {Process}\n   */\n  function process(vfileCompatible) {\n    const {file, processor} = split(vfileCompatible)\n    return processor.process(file)\n  }\n\n  /**\n   * Make a full vfile from what’s given, and figure out which processor\n   * should be used for it.\n   * This caches processors (one for markdown and one for MDX) so that they do\n   * not have to be reconstructed for each file.\n   *\n   * @param {Compatible} vfileCompatible\n   *   MDX or markdown document.\n   * @return {{file: VFile, processor: Processor<Root, Program, Program, Program, string>}}\n   *   File and corresponding processor.\n   */\n  function split(vfileCompatible) {\n    const {file, options} = resolveFileAndOptions(\n      vfileCompatible,\n      compileOptions_\n    )\n    const processor =\n      options.format === 'md'\n        ? cachedMarkdown || (cachedMarkdown = createProcessor(options))\n        : cachedMdx || (cachedMdx = createProcessor(options))\n    return {file, processor}\n  }\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/estree-util-create.js",
    "content": "/**\n * @import {Node} from 'estree-jsx'\n */\n\n// Fix to show references to above types in VS Code.\n''\n\n/**\n * @param {Readonly<Node>} from\n *   Node to take from.\n * @param {Node} to\n *   Node to add to.\n * @returns {undefined}\n *   Nothing.\n */\nexport function create(from, to) {\n  /** @type {Array<keyof Node>} */\n  const fields = ['start', 'end', 'loc', 'range']\n  let index = -1\n\n  while (++index < fields.length) {\n    const field = fields[index]\n\n    if (field in from) {\n      // @ts-expect-error: assume they’re settable.\n      to[field] = from[field]\n    }\n  }\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/estree-util-declaration-to-expression.js",
    "content": "/**\n * @import {\n      Declaration,\n      Expression,\n      MaybeNamedClassDeclaration,\n      MaybeNamedFunctionDeclaration\n * } from 'estree-jsx'\n */\n\nimport {ok as assert} from 'devlop'\n\n/**\n * Turn a declaration into an expression.\n *\n * Doesn’t work for variable declarations, but that’s fine for our use case\n * because currently we’re using this utility for export default declarations,\n * which can’t contain variable declarations.\n *\n * @param {Readonly<Declaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration>} declaration\n *   Declaration.\n * @returns {Expression}\n *   Expression.\n */\nexport function declarationToExpression(declaration) {\n  if (declaration.type === 'FunctionDeclaration') {\n    return {...declaration, type: 'FunctionExpression'}\n  }\n\n  // This is currently an internal utility so the next shouldn’t happen or a\n  // maintainer is making a mistake.\n  assert(declaration.type === 'ClassDeclaration', 'unexpected node type')\n  return {...declaration, type: 'ClassExpression'}\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/estree-util-is-declaration.js",
    "content": "/**\n * @import {\n      Declaration,\n      MaybeNamedClassDeclaration,\n      MaybeNamedFunctionDeclaration,\n      Node\n * } from 'estree-jsx'\n */\n\n// Fix to show references to above types in VS Code.\n''\n\n/**\n * Check if `node` is a declaration.\n *\n * @param {Readonly<MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration | Node>} node\n *   Node to check.\n * @returns {node is Declaration | MaybeNamedClassDeclaration | MaybeNamedFunctionDeclaration}\n *   Whether `node` is a declaration.\n */\nexport function isDeclaration(node) {\n  return Boolean(\n    node.type === 'FunctionDeclaration' ||\n      node.type === 'ClassDeclaration' ||\n      node.type === 'VariableDeclaration'\n  )\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/estree-util-specifiers-to-declarations.js",
    "content": "/**\n * @import {\n      AssignmentProperty,\n      ExportSpecifier,\n      Expression,\n      Identifier,\n      ImportDefaultSpecifier,\n      ImportNamespaceSpecifier,\n      ImportSpecifier,\n      Literal,\n      VariableDeclarator\n * } from 'estree-jsx'\n */\n\nimport {ok as assert} from 'devlop'\nimport {create} from './estree-util-create.js'\n\n/**\n * @param {ReadonlyArray<Readonly<ExportSpecifier> | Readonly<ImportDefaultSpecifier> | Readonly<ImportNamespaceSpecifier> | Readonly<ImportSpecifier>>} specifiers\n *   Specifiers.\n * @param {Readonly<Expression>} init\n *   Initializer.\n * @returns {Array<VariableDeclarator>}\n *   Declarations.\n */\nexport function specifiersToDeclarations(specifiers, init) {\n  let index = -1\n  /** @type {Array<VariableDeclarator>} */\n  const declarations = []\n  /** @type {Array<ExportSpecifier | ImportDefaultSpecifier | ImportSpecifier>} */\n  const otherSpecifiers = []\n  // Can only be one according to JS syntax.\n  /** @type {ImportNamespaceSpecifier | undefined} */\n  let importNamespaceSpecifier\n\n  while (++index < specifiers.length) {\n    const specifier = specifiers[index]\n\n    if (specifier.type === 'ImportNamespaceSpecifier') {\n      importNamespaceSpecifier = specifier\n    } else {\n      otherSpecifiers.push(specifier)\n    }\n  }\n\n  if (importNamespaceSpecifier) {\n    /** @type {VariableDeclarator} */\n    const declarator = {\n      type: 'VariableDeclarator',\n      id: importNamespaceSpecifier.local,\n      init\n    }\n    create(importNamespaceSpecifier, declarator)\n    declarations.push(declarator)\n  }\n\n  declarations.push({\n    type: 'VariableDeclarator',\n    id: {\n      type: 'ObjectPattern',\n      properties: otherSpecifiers.map(function (specifier) {\n        /** @type {Identifier | Literal} */\n        let key =\n          specifier.type === 'ImportSpecifier'\n            ? specifier.imported\n            : specifier.type === 'ExportSpecifier'\n              ? specifier.exported\n              : {type: 'Identifier', name: 'default'}\n        let value = specifier.local\n\n        // Switch them around if we’re exporting.\n        if (specifier.type === 'ExportSpecifier') {\n          value = key\n          key = specifier.local\n        }\n\n        // To do: what to do about literals?\n        // `const { a: 'b' } = c()` does not work?\n        assert(value.type === 'Identifier')\n\n        /** @type {AssignmentProperty} */\n        const property = {\n          type: 'Property',\n          kind: 'init',\n          shorthand:\n            key.type === 'Identifier' &&\n            value.type === 'Identifier' &&\n            key.name === value.name,\n          method: false,\n          computed: false,\n          key,\n          value\n        }\n        create(specifier, property)\n        return property\n      })\n    },\n    init: importNamespaceSpecifier\n      ? {type: 'Identifier', name: importNamespaceSpecifier.local.name}\n      : init\n  })\n\n  return declarations\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/estree-util-to-binary-addition.js",
    "content": "/**\n * @import {Expression} from 'estree-jsx'\n */\n\nimport {ok as assert} from 'devlop'\n\n/**\n * @param {ReadonlyArray<Expression>} expressions\n *   Expressions.\n * @returns {Expression}\n *   Addition.\n */\nexport function toBinaryAddition(expressions) {\n  let index = -1\n  /** @type {Expression | undefined} */\n  let left\n\n  while (++index < expressions.length) {\n    const right = expressions[index]\n    left = left ? {type: 'BinaryExpression', left, operator: '+', right} : right\n  }\n\n  assert(left, 'expected non-empty `expressions` to be passed')\n  return left\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/estree-util-to-id-or-member-expression.js",
    "content": "/**\n * @import {\n      Identifier,\n      JSXIdentifier,\n      JSXMemberExpression,\n      Literal,\n      MemberExpression\n * } from 'estree-jsx'\n */\n\nimport {ok as assert} from 'devlop'\nimport {name as isIdentifierName} from 'estree-util-is-identifier-name'\n\n/**\n * @param {ReadonlyArray<number | string>} ids\n *   Identifiers (example: `['list', 0]).\n * @returns {Identifier | MemberExpression}\n *   Identifier or member expression.\n */\nexport function toIdOrMemberExpression(ids) {\n  let index = -1\n  /** @type {Identifier | Literal | MemberExpression | undefined} */\n  let object\n\n  while (++index < ids.length) {\n    const name = ids[index]\n    /** @type {Identifier | Literal} */\n    const id =\n      typeof name === 'string' && isIdentifierName(name)\n        ? {type: 'Identifier', name}\n        : {type: 'Literal', value: name}\n    object = object\n      ? {\n          type: 'MemberExpression',\n          object,\n          property: id,\n          computed: id.type === 'Literal',\n          optional: false\n        }\n      : id\n  }\n\n  assert(object, 'expected non-empty `ids` to be passed')\n  assert(object.type !== 'Literal', 'expected identifier as left-most value')\n  return object\n}\n\n/**\n * @param {ReadonlyArray<number | string>} ids\n *   Identifiers (example: `['list', 0]).\n * @returns {JSXIdentifier | JSXMemberExpression}\n *   Identifier or member expression.\n */\nexport function toJsxIdOrMemberExpression(ids) {\n  let index = -1\n  /** @type {JSXIdentifier | JSXMemberExpression | undefined} */\n  let object\n\n  while (++index < ids.length) {\n    const name = ids[index]\n    assert(\n      typeof name === 'string' && isIdentifierName(name, {jsx: true}),\n      'expected valid jsx identifier, not `' + name + '`'\n    )\n\n    /** @type {JSXIdentifier} */\n    const id = {type: 'JSXIdentifier', name}\n    object = object ? {type: 'JSXMemberExpression', object, property: id} : id\n  }\n\n  assert(object, 'expected non-empty `ids` to be passed')\n  return object\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/extnames-to-regex.js",
    "content": "/**\n * Turn a list of extnames (*with* dots) into an expression.\n *\n * @param {ReadonlyArray<string>} extnames\n *   List of extnames.\n * @returns {RegExp}\n *   Regex matching them.\n */\nexport function extnamesToRegex(extnames) {\n  return new RegExp(\n    '\\\\.(' +\n      extnames\n        .map(function (d) {\n          return d.slice(1)\n        })\n        .join('|') +\n      ')([?#]|$)'\n  )\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/extnames.js",
    "content": "import markdownExtensions from 'markdown-extensions'\n\nexport const md = markdownExtensions.map(function (d) {\n  return '.' + d\n})\nexport const mdx = ['.mdx']\n"
  },
  {
    "path": "packages/mdx/lib/util/resolve-evaluate-options.js",
    "content": "/**\n * @import {Fragment, Jsx, JsxDev} from 'hast-util-to-jsx-runtime'\n * @import {MDXComponents} from 'mdx/types.js'\n * @import {CompileOptions} from '../compile.js'\n */\n\n/**\n * @typedef {EvaluateProcessorOptions & RunOptions} EvaluateOptions\n *   Configuration for `evaluate`.\n *\n * @typedef {Omit<CompileOptions, 'baseUrl' | 'jsx' | 'jsxImportSource' | 'jsxRuntime' | 'outputFormat' | 'pragma' | 'pragmaFrag' | 'pragmaImportSource' | 'providerImportSource'> } EvaluateProcessorOptions\n *   Compile configuration without JSX options for evaluation.\n *\n * @typedef RunOptions\n *   Configuration to run compiled code.\n *\n *   `Fragment`, `jsx`, and `jsxs` are used when the code is compiled in\n *   production mode (`development: false`).\n *   `Fragment` and `jsxDEV` are used when compiled in development mode\n *   (`development: true`).\n *   `useMDXComponents` is used when the code is compiled with\n *   `providerImportSource: '#'` (the exact value of this compile option\n *   doesn’t matter).\n * @property {URL | string | null | undefined} [baseUrl]\n *   Use this URL as `import.meta.url` and resolve `import` and `export … from`\n *   relative to it (optional, example: `import.meta.url`);\n *   this option can also be given at compile time in `CompileOptions`;\n *   you should pass this (likely at runtime), as you might get runtime errors\n *   when using `import.meta.url` / `import` / `export … from ` otherwise.\n * @property {Fragment} Fragment\n *   Symbol to use for fragments (**required**).\n * @property {Jsx | null | undefined} [jsx]\n *   Function to generate an element with static children in production mode.\n * @property {JsxDev | null | undefined} [jsxDEV]\n *   Function to generate an element in development mode.\n * @property {Jsx | null | undefined} [jsxs]\n *   Function to generate an element with dynamic children in production mode.\n * @property {UseMdxComponents | null | undefined} [useMDXComponents]\n *   Function to get components from context.\n *\n * @callback UseMdxComponents\n *   Get components from context.\n * @returns {MDXComponents}\n *   Current components.\n */\n\n// Fix to show references to above types in VS Code.\n''\n\n/**\n * Split compiletime options from runtime options.\n *\n * @param {Readonly<EvaluateOptions> | null | undefined} options\n *   Configuration.\n * @returns {{compiletime: CompileOptions, runtime: RunOptions}}\n *   Split options.\n */\nexport function resolveEvaluateOptions(options) {\n  const {\n    Fragment,\n    baseUrl,\n    development,\n    jsx,\n    jsxDEV,\n    jsxs,\n    useMDXComponents,\n    ...rest\n  } = options || {}\n\n  if (!Fragment) throw new Error('Expected `Fragment` given to `evaluate`')\n  if (development) {\n    if (!jsxDEV) throw new Error('Expected `jsxDEV` given to `evaluate`')\n  } else {\n    if (!jsx) throw new Error('Expected `jsx` given to `evaluate`')\n    if (!jsxs) throw new Error('Expected `jsxs` given to `evaluate`')\n  }\n\n  return {\n    compiletime: {\n      ...rest,\n      development,\n      outputFormat: 'function-body',\n      providerImportSource: useMDXComponents ? '#' : undefined\n    },\n    runtime: {Fragment, baseUrl, jsx, jsxDEV, jsxs, useMDXComponents}\n  }\n}\n"
  },
  {
    "path": "packages/mdx/lib/util/resolve-file-and-options.js",
    "content": "/**\n * @import {Compatible} from 'vfile'\n * @import {CompileOptions} from '../compile.js'\n * @import {ProcessorOptions} from '../core.js'\n */\n\nimport {VFile} from 'vfile'\nimport {md} from './extnames.js'\n\n/**\n * Create a file and options from a given `vfileCompatible` and options that\n * might contain `format: 'detect'`.\n *\n * @param {Readonly<Compatible>} vfileCompatible\n *   File.\n * @param {Readonly<CompileOptions> | null | undefined} [options]\n *   Configuration (optional).\n * @returns {{file: VFile, options: ProcessorOptions}}\n *   File and options.\n */\nexport function resolveFileAndOptions(vfileCompatible, options) {\n  const file = looksLikeAVFile(vfileCompatible)\n    ? vfileCompatible\n    : new VFile(vfileCompatible)\n  const {format, ...rest} = options || {}\n  return {\n    file,\n    options: {\n      format:\n        format === 'md' || format === 'mdx'\n          ? format\n          : file.extname && (rest.mdExtensions || md).includes(file.extname)\n            ? 'md'\n            : 'mdx',\n      ...rest\n    }\n  }\n}\n\n/**\n * @param {Readonly<Compatible> | null | undefined} [value]\n *   Thing.\n * @returns {value is VFile}\n *   Check.\n */\nfunction looksLikeAVFile(value) {\n  return Boolean(\n    value &&\n      typeof value === 'object' &&\n      'message' in value &&\n      'messages' in value\n  )\n}\n"
  },
  {
    "path": "packages/mdx/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Compositor, Inc. and Vercel, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/mdx/package.json",
    "content": "{\n  \"name\": \"@mdx-js/mdx\",\n  \"version\": \"3.1.1\",\n  \"description\": \"MDX compiler\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"jsx\",\n    \"markdown\",\n    \"mdx\",\n    \"remark\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/mdx/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n  \"contributors\": [\n    \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n    \"Tim Neutkens <tim@vercel.com>\",\n    \"Matija Marohnić <matija.marohnic@gmail.com>\",\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\",\n    \"JounQin <admin@1stg.me> (https://www.1stg.me)\",\n    \"Christian Murphy <christian.murphy.42@gmail.com>\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": {\n    \".\": \"./index.js\",\n    \"./internal-create-format-aware-processors\": \"./lib/util/create-format-aware-processors.js\",\n    \"./internal-extnames-to-regex\": \"./lib/util/extnames-to-regex.js\"\n  },\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"@types/estree\": \"^1.0.0\",\n    \"@types/estree-jsx\": \"^1.0.0\",\n    \"@types/hast\": \"^3.0.0\",\n    \"@types/mdx\": \"^2.0.0\",\n    \"acorn\": \"^8.0.0\",\n    \"collapse-white-space\": \"^2.0.0\",\n    \"devlop\": \"^1.0.0\",\n    \"estree-util-is-identifier-name\": \"^3.0.0\",\n    \"estree-util-scope\": \"^1.0.0\",\n    \"estree-walker\": \"^3.0.0\",\n    \"hast-util-to-jsx-runtime\": \"^2.0.0\",\n    \"markdown-extensions\": \"^2.0.0\",\n    \"recma-build-jsx\": \"^1.0.0\",\n    \"recma-jsx\": \"^1.0.0\",\n    \"recma-stringify\": \"^1.0.0\",\n    \"rehype-recma\": \"^1.0.0\",\n    \"remark-mdx\": \"^3.0.0\",\n    \"remark-parse\": \"^11.0.0\",\n    \"remark-rehype\": \"^11.0.0\",\n    \"source-map\": \"^0.7.0\",\n    \"unified\": \"^11.0.0\",\n    \"unist-util-position-from-estree\": \"^2.0.0\",\n    \"unist-util-stringify-position\": \"^4.0.0\",\n    \"unist-util-visit\": \"^5.0.0\",\n    \"vfile\": \"^6.0.0\"\n  },\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development --enable-source-maps test/index.js\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"overrides\": [\n      {\n        \"files\": [\n          \"test/**/*.js\"\n        ],\n        \"rules\": {\n          \"no-restricted-globals\": \"off\"\n        }\n      },\n      {\n        \"files\": [\n          \"**/*.ts\"\n        ],\n        \"rules\": {\n          \"@typescript-eslint/array-type\": \"off\",\n          \"@typescript-eslint/ban-types\": \"off\",\n          \"@typescript-eslint/consistent-type-definitions\": \"off\"\n        }\n      }\n    ],\n    \"prettier\": true,\n    \"rules\": {\n      \"complexity\": \"off\",\n      \"logical-assignment-operators\": \"off\",\n      \"max-depth\": \"off\",\n      \"n/file-extension-in-import\": \"off\",\n      \"unicorn/prefer-at\": \"off\",\n      \"unicorn/prefer-code-point\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/mdx/readme.md",
    "content": "# `@mdx-js/mdx`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Size][size-badge]][size]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nMDX compiler.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`compile(file, options?)`](#compilefile-options)\n  * [`compileSync(file, options?)`](#compilesyncfile-options)\n  * [`createProcessor(options?)`](#createprocessoroptions)\n  * [`evaluate(file, options)`](#evaluatefile-options)\n  * [`evaluateSync(file, options)`](#evaluatesyncfile-options)\n  * [`nodeTypes`](#nodetypes)\n  * [`run(code, options)`](#runcode-options)\n  * [`runSync(code, options)`](#runsynccode-options)\n  * [`CompileOptions`](#compileoptions)\n  * [`EvaluateOptions`](#evaluateoptions)\n  * [`Fragment`](#fragment)\n  * [`Jsx`](#jsx)\n  * [`JsxDev`](#jsxdev)\n  * [`ProcessorOptions`](#processoroptions)\n  * [`RunOptions`](#runoptions)\n  * [`UseMdxComponents`](#usemdxcomponents)\n* [Types](#types)\n* [Architecture](#architecture)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a compiler that turns MDX into JavaScript.\nIt can also evaluate MDX code.\n\n## When should I use this?\n\nThis is the core compiler for turning MDX into JavaScript which gives you the\nmost control.\nIf you’re using a bundler (Rollup, esbuild, webpack), a site builder (Next.js),\nor build system (Vite) which comes with a bundler, you’re better off using an\nintegration: see [§ Integrations][integrations].\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/mdx\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```tsx\nimport {compile} from 'https://esm.sh/@mdx-js/mdx@3'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n<script type=\"module\">\n  import {compile} from 'https://esm.sh/@mdx-js/mdx@3?bundle'\n</script>\n```\n\n## Use\n\nSay we have an MDX document, `example.mdx`:\n\n```mdx\nexport function Thing() {\n  return <>World!</>\n}\n\n# Hello, <Thing />\n```\n\n…and some code in `example.js` to compile `example.mdx` to JavaScript:\n\n```tsx\nimport fs from 'node:fs/promises'\nimport {compile} from '@mdx-js/mdx'\n\nconst compiled = await compile(await fs.readFile('example.mdx'))\n\nconsole.log(String(compiled))\n```\n\nYields roughly:\n\n```tsx\nimport {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n\nexport function Thing() {\n  return _jsx(_Fragment, {children: 'World!'})\n}\n\nfunction _createMdxContent(props) {\n  const _components = {h1: 'h1', ...props.components}\n  return _jsxs(_components.h1, {children: ['Hello, ', _jsx(Thing, {})]})\n}\n\nexport default function MDXContent(props = {}) {\n  const {wrapper: MDXLayout} = props.components || {}\n  return MDXLayout\n    ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {...props})})\n    : _createMdxContent(props)\n}\n```\n\nSee [§ Using MDX][using-mdx] for more on how MDX work and how to use the result.\n\n## API\n\nThis package exports the following identifiers:\n[`compile`][api-compile],\n[`compileSync`][api-compile-sync],\n[`createProcessor`][api-create-processor],\n[`evaluate`][api-evaluate],\n[`evaluateSync`][api-evaluate-sync],\n[`nodeTypes`][api-node-types],\n[`run`][api-run], and\n[`runSync`][api-run-sync].\nThere is no default export.\n\n### `compile(file, options?)`\n\nCompile MDX to JS.\n\n###### Parameters\n\n* `file` ([`Compatible` from `vfile`][vfile-compatible])\n  — MDX document to parse\n* `options` ([`CompileOptions`][api-compile-options], optional)\n  — compile configuration\n\n###### Returns\n\nPromise to compiled file ([`Promise<VFile>`][vfile]).\n\n###### Examples\n\nThe input value for `file` can be many different things.\nYou can pass a `string`, `Uint8Array` in UTF-8, [`VFile`][vfile], or anything\nthat can be given to `new VFile`.\n\n```tsx\nimport {compile} from '@mdx-js/mdx'\nimport {VFile} from 'vfile'\n\nawait compile(':)')\nawait compile(Buffer.from(':-)'))\nawait compile({path: 'path/to/file.mdx', value: '🥳'})\nawait compile(new VFile({path: 'path/to/file.mdx', value: '🤭'}))\n```\n\nThe output `VFile` can be used to access more than the generated code:\n\n```tsx\nimport {compile} from '@mdx-js/mdx'\nimport remarkPresetLintConsistent from 'remark-preset-lint-consistent' // Lint rules to check for consistent markdown.\nimport {reporter} from 'vfile-reporter'\n\nconst file = await compile('*like this* or _like this_?', {remarkPlugins: [remarkPresetLintConsistent]})\n\nconsole.error(reporter(file))\n```\n\nYields:\n\n```text\n  1:16-1:27  warning  Emphasis should use `*` as a marker  emphasis-marker  remark-lint\n\n⚠ 1 warning\n```\n\n### `compileSync(file, options?)`\n\nSynchronously compile MDX to JS.\n\nWhen possible please use the async [`compile`][api-compile].\n\n###### Parameters\n\n* `file` ([`Compatible` from `vfile`][vfile-compatible])\n  — MDX document to parse\n* `options` ([`CompileOptions`][api-compile-options], optional)\n  — compile configuration\n\n###### Returns\n\nCompiled file ([`VFile`][vfile]).\n\n### `createProcessor(options?)`\n\nCreate a processor to compile markdown or MDX to JavaScript.\n\n> **Note**: `format: 'detect'` is not allowed in `ProcessorOptions`.\n\n###### Parameters\n\n* `options` ([`ProcessorOptions`][api-processor-options], optional)\n  — process configuration\n\n###### Returns\n\nProcessor ([`Processor` from `unified`][unified-processor]).\n\n### `evaluate(file, options)`\n\n[Compile][api-compile] and [run][api-run] MDX.\n\nWhen you trust your content, `evaluate` can work.\nWhen possible, use [`compile`][api-compile], write to a file, and then run with\nNode or use one of the [§ Integrations][integrations].\n\n> ☢️ **Danger**: it’s called **evaluate** because it `eval`s JavaScript.\n\n###### Parameters\n\n* `file` ([`Compatible` from `vfile`][vfile-compatible])\n  — MDX document to parse\n* `options` ([`EvaluateOptions`][api-evaluate-options], **required**)\n  — configuration\n\n###### Returns\n\nPromise to a module ([`Promise<MDXModule>` from\n`mdx/types.js`][mdx-types-module]).\n\nThe result is an object with a `default` field set to the component;\nanything else that was exported is available too.\nFor example, assuming the contents of `example.mdx` from [§ Use][use] was in\n`file`, then:\n\n```tsx\nimport {evaluate} from '@mdx-js/mdx'\nimport * as runtime from 'react/jsx-runtime'\n\nconsole.log(await evaluate(file, runtime))\n```\n\n…yields:\n\n```tsx\n{Thing: [Function: Thing], default: [Function: MDXContent]}\n```\n\n###### Notes\n\nCompiling (and running) MDX takes time.\n\nIf you are live-rendering a string of MDX that often changes using a virtual DOM\nbased framework (such as React), one performance improvement is to call the\n`MDXContent` component yourself.\nThe reason is that the `evaluate` creates a new function each time, which cannot\nbe diffed:\n\n```diff\n const {default: MDXContent} = await evaluate('…')\n\n-<MDXContent {...props} />\n+MDXContent(props)\n```\n\n### `evaluateSync(file, options)`\n\nCompile and run MDX, synchronously.\n\nWhen possible please use the async [`evaluate`][api-evaluate].\n\n> ☢️ **Danger**: it’s called **evaluate** because it `eval`s JavaScript.\n\n###### Parameters\n\n* `file` ([`Compatible` from `vfile`][vfile-compatible])\n  — MDX document to parse\n* `options` ([`EvaluateOptions`][api-evaluate-options], **required**)\n  — configuration\n\n###### Returns\n\nModule ([`MDXModule` from `mdx/types.js`][mdx-types-module]).\n\n### `nodeTypes`\n\nList of node types made by `mdast-util-mdx`, which have to be passed\nthrough untouched from the mdast tree to the hast tree (`Array<string>`).\n\n### `run(code, options)`\n\nRun code compiled with `outputFormat: 'function-body'`.\n\n> ☢️ **Danger**: this `eval`s JavaScript.\n\n###### Parameters\n\n* `code` ([`VFile`][vfile] or `string`)\n  — JavaScript function body to run\n* `options` ([`RunOptions`][api-run-options], **required**)\n  — configuration\n\n###### Returns\n\nPromise to a module ([`Promise<MDXModule>` from\n`mdx/types.js`][mdx-types-module]);\nthe result is an object with a `default` field set to the component;\nanything else that was exported is available too.\n\n###### Example\n\nOn the server:\n\n```tsx\nimport {compile} from '@mdx-js/mdx'\n\nconst code = String(await compile('# hi', {outputFormat: 'function-body'}))\n// To do: send `code` to the client somehow.\n```\n\nOn the client:\n\n```tsx\nimport {run} from '@mdx-js/mdx'\nimport * as runtime from 'react/jsx-runtime'\n\nconst code = '' // To do: get `code` from server somehow.\n\nconst {default: Content} = await run(code, {...runtime, baseUrl: import.meta.url})\n\nconsole.log(Content)\n```\n\n…yields:\n\n```tsx\n[Function: MDXContent]\n```\n\n### `runSync(code, options)`\n\nRun code, synchronously.\n\nWhen possible please use the async [`run`][api-run].\n\n> ☢️ **Danger**: this `eval`s JavaScript.\n\n###### Parameters\n\n* `code` ([`VFile`][vfile] or `string`)\n  — JavaScript function body to run\n* `options` ([`RunOptions`][api-run-options], **required**)\n  — configuration\n\n###### Returns\n\nModule ([`MDXModule` from `mdx/types.js`][mdx-types-module]).\n\n### `CompileOptions`\n\nConfiguration for `compile` (TypeScript type).\n\n`CompileOptions` is the same as [`ProcessorOptions`][api-processor-options]\nwith the exception that the `format` option supports a `'detect'` value,\nwhich is the default.\nThe `'detect'` format means to use `'md'` for files with an extension in\n`mdExtensions` and `'mdx'` otherwise.\n\n###### Type\n\n```tsx\n/**\n * Configuration for `compile`\n */\ntype CompileOptions = Omit<ProcessorOptions, 'format'> & {\n  /**\n   * Format of `file` (default: `'detect'`).\n   */\n  format?: 'detect' | 'md' | 'mdx' | null | undefined\n}\n```\n\n### `EvaluateOptions`\n\nConfiguration for `evaluate` (TypeScript type).\n\n`EvaluateOptions` is the same as [`CompileOptions`][api-compile-options],\nexcept that the options `baseUrl`, `jsx`, `jsxImportSource`, `jsxRuntime`,\n`outputFormat`, `pragma`, `pragmaFrag`, `pragmaImportSource`, and\n`providerImportSource` are not allowed, and that\n[`RunOptions`][api-run-options] are also used.\n\n###### Type\n\n```tsx\n/**\n * Configuration for `evaluate`.\n */\ntype EvaluateOptions = Omit<\n  CompileOptions,\n  | 'baseUrl' // Note that this is also in `RunOptions`.\n  | 'jsx'\n  | 'jsxImportSource'\n  | 'jsxRuntime'\n  | 'outputFormat'\n  | 'pragma'\n  | 'pragmaFrag'\n  | 'pragmaImportSource'\n  | 'providerImportSource'\n> &\n  RunOptions\n```\n\n### `Fragment`\n\nRepresent the children, typically a symbol (TypeScript type).\n\n###### Type\n\n```ts\ntype Fragment = unknown\n```\n\n### `Jsx`\n\nCreate a production element (TypeScript type).\n\n###### Parameters\n\n* `type` (`unknown`)\n  — element type: `Fragment` symbol, tag name (`string`), component\n* `properties` (`Properties`)\n  — element properties and `children`\n* `key` (`string` or `undefined`)\n  — key to use\n\n###### Returns\n\nElement from your framework (`JSX.Element`).\n\n### `JsxDev`\n\nCreate a development element (TypeScript type).\n\n###### Parameters\n\n* `type` (`unknown`)\n  — element type: `Fragment` symbol, tag name (`string`), component\n* `properties` (`Properties`)\n  — element properties and `children`\n* `key` (`string` or `undefined`)\n  — key to use\n* `isStaticChildren` (`boolean`)\n  — whether two or more children are passed (in an array), which is whether\n  `jsxs` or `jsx` would be used\n* `source` (`Source`)\n  — info about source\n* `self` (`unknown`)\n  — context object (`this`)\n\n### `ProcessorOptions`\n\nConfiguration for `createProcessor` (TypeScript type).\n\n###### Fields\n\n* `SourceMapGenerator` (`SourceMapGenerator` from [`source-map`][source-map],\n  optional)\n  — add a source map (object form) as the `map` field on the resulting file\n\n  <details><summary>Expand example</summary>\n\n  Assuming `example.mdx` from [§ Use][use] exists, then:\n\n  ```tsx\n  import fs from 'node:fs/promises'\n  import {compile} from '@mdx-js/mdx'\n  import {SourceMapGenerator} from 'source-map'\n\n  const file = await compile(\n    {path: 'example.mdx', value: await fs.readFile('example.mdx')},\n    {SourceMapGenerator}\n  )\n\n  console.log(file.map)\n  ```\n\n  …yields:\n\n  ```tsx\n  {\n    file: 'example.mdx',\n    mappings: ';;aAAaA,QAAQ;YAAQ;;;;;;;;iBAE3B',\n    names: ['Thing'],\n    sources: ['example.mdx'],\n    version: 3\n  }\n  ```\n\n  </details>\n\n* `baseUrl` (`URL` or `string`, optional, example: `import.meta.url`)\n  — use this URL as `import.meta.url` and resolve `import` and\n  `export … from` relative to it\n\n  <details><summary>Expand example</summary>\n\n  Say we have a module `example.js`:\n\n  ```tsx\n  import {compile} from '@mdx-js/mdx'\n\n  const code = 'export {number} from \"./data.js\"\\n\\n# hi'\n  const baseUrl = 'https://a.full/url' // Typically `import.meta.url`\n\n  console.log(String(await compile(code, {baseUrl})))\n  ```\n\n  …now running `node example.js` yields:\n\n  ```tsx\n  import {jsx as _jsx} from 'react/jsx-runtime'\n  export {number} from 'https://a.full/data.js'\n  function _createMdxContent(props) { /* … */ }\n  export default function MDXContent(props = {}) { /* … */ }\n  ```\n\n  </details>\n\n* `development` (`boolean`, default: `false`)\n  — whether to add extra info to error messages in generated code and use the\n  development automatic JSX runtime (`Fragment` and `jsxDEV` from\n  `/jsx-dev-runtime`);\n  when using the webpack loader (`@mdx-js/loader`) or the Rollup integration\n  (`@mdx-js/rollup`) through Vite, this is automatically inferred from how\n  you configure those tools\n\n  <details><summary>Expand example</summary>\n\n  Say we had some MDX that references a component that can be passed or\n  provided at runtime:\n\n  ```mdx\n  **Note**<NoteIcon />: some stuff.\n  ```\n\n  And a module to evaluate that:\n\n  ```tsx\n  import fs from 'node:fs/promises'\n  import {evaluate} from '@mdx-js/mdx'\n  import * as runtime from 'react/jsx-runtime'\n\n  const path = 'example.mdx'\n  const value = await fs.readFile(path)\n  const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default\n\n  console.log(MDXContent({}))\n  ```\n\n  …running that would normally (production) yield:\n\n  ```text\n  Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.\n      at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)\n      at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)\n      at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)\n      at main (…/example.js:11:15)\n  ```\n\n  …but if we add `development: true` to our example:\n\n  ```diff\n  @@ -7,6 +7,6 @@\n  import fs from 'node:fs/promises'\n  -import * as runtime from 'react/jsx-runtime'\n  +import * as runtime from 'react/jsx-dev-runtime'\n  import {evaluate} from '@mdx-js/mdx'\n\n  const path = 'example.mdx'\n  const value = await fs.readFile(path)\n  -const MDXContent = (await evaluate({path, value}, {...runtime, baseUrl: import.meta.url})).default\n  +const MDXContent = (await evaluate({path, value}, {development: true, ...runtime, baseUrl: import.meta.url})).default\n\n  console.log(MDXContent({}))\n  ```\n\n  …and we’d run it again, we’d get:\n\n  ```text\n  Error: Expected component `NoteIcon` to be defined: you likely forgot to import, pass, or provide it.\n  It’s referenced in your code at `1:9-1:21` in `example.mdx`\n  provide it.\n      at _missingMdxReference (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:27:9)\n      at _createMdxContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:15:20)\n      at MDXContent (eval at run (…/@mdx-js/mdx/lib/run.js:18:10), <anonymous>:9:9)\n      at main (…/example.js:11:15)\n  ```\n\n  </details>\n\n* `elementAttributeNameCase` (`'html'` or `'react`, default: `'react'`)\n  — casing to use for attribute names;\n  HTML casing is for example `class`, `stroke-linecap`, `xml:lang`;\n  React casing is for example `className`, `strokeLinecap`, `xmlLang`;\n  for JSX components written in MDX, the author has to be aware of which\n  framework they use and write code accordingly;\n  for AST nodes generated by this project, this option configures it\n\n* `format` (`'md'` or `'mdx'`, default: `'mdx'`)\n  — format of the file;\n  `'md'` means treat as markdown and `'mdx'` means treat as [MDX][mdx-syntax]\n\n  <details><summary>Expand example</summary>\n\n  ```tsx\n  compile('…') // Seen as MDX.\n  compile('…', {format: 'mdx'}) // Seen as MDX.\n  compile('…', {format: 'md'}) // Seen as markdown.\n  ```\n\n  </details>\n\n* `jsx` (`boolean`, default: `false`)\n  — whether to keep JSX;\n  the default is to compile JSX away so that the resulting file is\n  immediately runnable.\n\n  <details><summary>Expand example</summary>\n\n  If `file` is the contents of `example.mdx` from [§ Use][use], then:\n\n  ```tsx\n  compile(file, {jsx: true})\n  ```\n\n  …yields this difference:\n\n  ```diff\n  -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n  +/*@jsxRuntime automatic*/\n  +/*@jsxImportSource react*/\n\n  export function Thing() {\n  -  return _jsx(_Fragment, {children: 'World'})\n  +  return <>World!</>\n  }\n\n  function _createMdxContent(props) {\n    const _components = {\n      h1: 'h1',\n      ...props.components\n    }\n  -  return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})\n  +  return <_components.h1>{\"Hello \"}<Thing /></_components.h1>\n  }\n\n  export default function MDXContent(props = {}) {\n    const {wrapper: MDXLayout} = props.components || {}\n    return MDXLayout\n  -    ? _jsx(MDXLayout, {\n  -        ...props,\n  -        children: _jsx(_createMdxContent, props)\n  -      })\n  +    ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout>\n      : _createMdxContent(props)\n  }\n  }\n  ```\n\n  </details>\n\n* `jsxImportSource` (`string`, default: `'react'`)\n  — place to import automatic JSX runtimes from;\n  when in the `automatic` runtime, this is used to define an import for\n  `Fragment`, `jsx`, `jsxDEV`, and `jsxs`\n\n  <details><summary>Expand example</summary>\n\n  If `file` is the contents of `example.mdx` from [§ Use][use], then:\n\n  ```tsx\n  compile(file, {jsxImportSource: 'preact'})\n  ```\n\n  …yields this difference:\n\n  ```diff\n  -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n  +import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from 'preact/jsx-runtime'\n  ```\n\n  </details>\n\n* `jsxRuntime` (`'automatic'` or `'classic'`, default: `'automatic'`)\n  — JSX runtime to use;\n  the automatic runtime compiles to `import _jsx from\n  '$importSource/jsx-runtime'\\n_jsx('p')`;\n  the classic runtime compiles to calls such as `h('p')`\n\n  > 👉 **Note**: support for the classic runtime is deprecated and will\n  > likely be removed in the next major version.\n\n  <details><summary>Expand example</summary>\n\n  If `file` is the contents of `example.mdx` from [§ Use][use], then:\n\n  ```tsx\n  compile(file, {jsxRuntime: 'classic'})\n  ```\n\n  …yields this difference:\n\n  ```diff\n  -import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n  +import React from 'react'\n\n  export function Thing() {\n  -  return _jsx(_Fragment, {children: 'World'})\n  +  return React.createElement(React.Fragment, null, 'World!')\n  }\n  …\n  ```\n\n  </details>\n\n* `outputFormat` (`'function-body'` or `'program'`, default: `'program'`)\n  — output format to generate;\n  in most cases `'program'` should be used, it results in a whole program;\n  internally [`evaluate`][api-evaluate] uses `'function-body'` to compile to\n  code that can be passed to [`run`][api-run];\n  in some cases, you might want what `evaluate` does in separate steps, such\n  as when compiling on the server and running on the client.\n\n  <details><summary>Expand example</summary>\n\n  With a module `example.js`:\n\n  ```tsx\n  import {compile} from '@mdx-js/mdx'\n\n  const code = 'export const no = 3.14\\n\\n# hi {no}'\n\n  console.log(String(await compile(code, {outputFormat: 'program'}))) // Default.\n  console.log(String(await compile(code, {outputFormat: 'function-body'})))\n  ```\n\n  …yields:\n\n  ```tsx\n  import {jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n  export const no = 3.14\n  function _createMdxContent(props) { /* … */ }\n  export default function MDXContent(props = {}) { /* … */ }\n  ```\n\n  ```tsx\n  'use strict'\n  const {Fragment: _Fragment, jsx: _jsx} = arguments[0]\n  const no = 3.14\n  function _createMdxContent(props) { /* … */ }\n  function MDXContent(props = {}) { /* … */ }\n  return {no, default: MDXContent}\n  ```\n\n  The `'program'` format will use import statements to import the runtime (and\n  optionally provider) and use an export statement to yield the `MDXContent`\n  component.\n\n  The `'function-body'` format will get the runtime (and optionally provider)\n  from `arguments[0]`, rewrite export statements, and use a return statement to\n  yield what was exported.\n\n  </details>\n\n* `mdExtensions` (`Array<string>`, default: `['.md', '.markdown', '.mdown',\n  '.mkdn', '.mkd', '.mdwn', '.mkdown', '.ron']`)\n  — list of markdown extensions, with dot\n  affects [§ Integrations][integrations]\n\n* `mdxExtensions` (`Array<string>`, default: `['.mdx']`)\n  — list of MDX extensions, with dot;\n  affects [§ Integrations][integrations]\n\n* `pragma` (`string`, default: `'React.createElement'`)\n  — pragma for JSX, used in the classic runtime as an identifier for function\n  calls: `<x />` to `React.createElement('x')`;\n  when changing this, you should also define `pragmaFrag` and\n  `pragmaImportSource` too\n\n  > 👉 **Note**: support for the classic runtime is deprecated and will\n  > likely be removed in the next major version.\n\n  <details><summary>Expand example</summary>\n\n  If `file` is the contents of `example.mdx` from [§ Use][use], then:\n\n  ```tsx\n  compile(file, {\n    jsxRuntime: 'classic',\n    pragma: 'preact.createElement',\n    pragmaFrag: 'preact.Fragment',\n    pragmaImportSource: 'preact/compat'\n  })\n  ```\n\n  …yields this difference:\n\n  ```diff\n  -import React from 'react'\n  +import preact from 'preact/compat'\n\n  export function Thing() {\n  -  return React.createElement(React.Fragment, null, 'World!')\n  +  return preact.createElement(preact.Fragment, null, 'World!')\n  }\n  …\n  ```\n\n  </details>\n\n* `pragmaFrag` (`string`, default: `'React.Fragment'`)\n  — pragma for fragment symbol, used in the classic runtime as an identifier\n  for unnamed calls: `<>` to `React.createElement(React.Fragment)`;\n  when changing this, you should also define `pragma` and `pragmaImportSource`\n  too\n\n  > 👉 **Note**: support for the classic runtime is deprecated and will\n  > likely be removed in the next major version.\n\n* `pragmaImportSource` (`string`, default: `'react'`)\n  — where to import the identifier of `pragma` from, used in the classic\n  runtime;\n  to illustrate, when `pragma` is `'a.b'` and `pragmaImportSource` is `'c'`\n  the following will be generated: `import a from 'c'` and things such as\n  `a.b('h1', {})`;\n  when changing this, you should also define `pragma` and `pragmaFrag` too\n\n  > 👉 **Note**: support for the classic runtime is deprecated and will\n  > likely be removed in the next major version.\n\n* `providerImportSource` (`string`, optional, example: `'@mdx-js/react'`)\n  — place to import a provider from;\n  normally it’s used for runtimes that support context (React, Preact), but\n  it can be used to inject components into the compiled code;\n  the module must export and identifier `useMDXComponents` which is called\n  without arguments to get an object of components (see\n  [`UseMdxComponents`][api-use-mdx-components])\n\n  <details><summary>Expand example</summary>\n\n  If `file` is the contents of `example.mdx` from [§ Use][use], then:\n\n  ```tsx\n  compile(file, {providerImportSource: '@mdx-js/react'})\n  ```\n\n  …yields this difference:\n\n  ```diff\n  import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from 'react/jsx-runtime'\n  +import {useMDXComponents as _provideComponents} from '@mdx-js/react'\n\n  export function Thing() {\n    return _jsx(_Fragment, {children: 'World'})\n  }\n\n  function _createMdxContent(props) {\n    const _components = {\n      h1: 'h1',\n  +    ..._provideComponents(),\n      ...props.components\n    }\n    return _jsxs(_components.h1, {children: ['Hello ', _jsx(Thing, {})]})\n  }\n\n  export default function MDXContent(props = {}) {\n  -  const {wrapper: MDXLayout} = props.components || {}\n  +  const {wrapper: MDXLayout} = {\n  +    ..._provideComponents(),\n  +    ...props.components\n  +  }\n\n    return MDXLayout\n      ? _jsx(MDXLayout, {...props, children: _jsx(_createMdxContent, {})})\n      : _createMdxContent()\n  ```\n\n  </details>\n\n* `recmaPlugins` ([`PluggableList` from `unified`][unified-pluggable-list],\n  optional)\n  — list of [recma plugins][recma-plugins]\n\n  <details><summary>Expand example</summary>\n\n  ```tsx\n  import recmaMdxIsMdxComponent from 'recma-mdx-is-mdx-component'\n\n  await compile(file, {recmaPlugins: [recmaMdxIsMdxComponent]})\n  ```\n\n  </details>\n\n* `rehypePlugins` ([`PluggableList` from `unified`][unified-pluggable-list],\n  optional)\n  — list of [rehype plugins][rehype-plugins]\n\n  <details><summary>Expand example</summary>\n\n  ```tsx\n  import rehypeKatex from 'rehype-katex' // Render math with KaTeX.\n  import remarkMath from 'remark-math' // Support math like `$so$`.\n\n  await compile(file, {rehypePlugins: [rehypeKatex], remarkPlugins: [remarkMath]})\n\n  await compile(file, {\n    // A plugin with options:\n    rehypePlugins: [[rehypeKatex, {strict: true, throwOnError: true}]],\n    remarkPlugins: [remarkMath]\n  })\n  ```\n\n  </details>\n\n* `remarkPlugins` ([`PluggableList` from `unified`][unified-pluggable-list],\n  optional)\n  — list of [remark plugins][remark-plugins]\n\n  <details><summary>Expand example</summary>\n\n  ```tsx\n  import remarkFrontmatter from 'remark-frontmatter' // YAML and such.\n  import remarkGfm from 'remark-gfm' // Tables, footnotes, strikethrough, task lists, literal URLs.\n\n  await compile(file, {remarkPlugins: [remarkGfm]}) // One plugin.\n  await compile(file, {remarkPlugins: [[remarkFrontmatter, 'toml']]}) // A plugin with options.\n  await compile(file, {remarkPlugins: [remarkGfm, remarkFrontmatter]}) // Two plugins.\n  await compile(file, {remarkPlugins: [[remarkGfm, {singleTilde: false}], remarkFrontmatter]}) // Two plugins, first w/ options.\n  ```\n\n  </details>\n\n* `remarkRehypeOptions` ([`Options` from\n  `remark-rehype`][remark-rehype-options], optional)\n  — options to pass through to `remark-rehype`;\n  in particular, you might want to pass configuration for footnotes if your\n  content is not in English;\n  the option `allowDangerousHtml` will always be set to `true` and the MDX\n  nodes (see [`nodeTypes`][api-node-types]) are passed through.\n\n  <details><summary>Expand example</summary>\n\n  ```tsx\n  compile({value: '…'}, {remarkRehypeOptions: {clobberPrefix: 'comment-1'}})\n  ```\n\n  </details>\n\n* `stylePropertyNameCase` (`'css'` or `'dom`, default: `'dom'`)\n  — casing to use for property names in `style` objects;\n  CSS casing is for example `background-color` and `-webkit-line-clamp`;\n  DOM casing is for example `backgroundColor` and `WebkitLineClamp`;\n  for JSX components written in MDX, the author has to be aware of which\n  framework they use and write code accordingly;\n  for AST nodes generated by this project, this option configures it\n\n* `tableCellAlignToStyle` (`boolean`, default: `true`)\n  — turn obsolete `align` properties on `td` and `th` into CSS `style`\n  properties\n\n### `RunOptions`\n\nConfiguration to run compiled code (TypeScript type).\n\n`Fragment`, `jsx`, and `jsxs` are used when the code is compiled in production\nmode (`development: false`).\n`Fragment` and `jsxDEV` are used when compiled in development mode\n(`development: true`).\n`useMDXComponents` is used when the code is compiled with\n`providerImportSource: '#'` (the exact value of this compile option doesn’t\nmatter).\n\n###### Fields\n\n* `Fragment` ([`Fragment`][api-fragment], **required**)\n  — symbol to use for fragments\n* `baseUrl` (`URL` or `string`, optional, example: `import.meta.url`)\n  — use this URL as `import.meta.url` and resolve `import` and\n  `export … from` relative to it;\n  this option can also be given at compile time in `CompileOptions`;\n  you should pass this (likely at runtime), as you might get runtime errors\n  when using `import.meta.url` / `import` / `export … from ` otherwise\n* `jsx` ([`Jsx`][api-jsx], optional)\n  — function to generate an element with static children in production mode\n* `jsxDEV` ([`JsxDev`][api-jsx-dev], optional)\n  — function to generate an element in development mode\n* `jsxs` ([`Jsx`][api-jsx], optional)\n  — function to generate an element with dynamic children in production mode\n* `useMDXComponents` ([`UseMdxComponents`][api-use-mdx-components], optional)\n  — function to get components to use\n\n###### Examples\n\nA `/jsx-runtime` module will expose `Fragment`, `jsx`, and `jsxs`:\n\n```tsx\nimport * as runtime from 'react/jsx-runtime'\n\nconst {default: Content} = await evaluate('# hi', {...runtime, baseUrl: import.meta.url, ...otherOptions})\n\n```\n\nA `/jsx-dev-runtime` module will expose `Fragment` and `jsxDEV`:\n\n```tsx\nimport * as runtime from 'react/jsx-dev-runtime'\n\nconst {default: Content} = await evaluate('# hi', {development: true, baseUrl: import.meta.url, ...runtime, ...otherOptions})\n```\n\nOur providers will expose `useMDXComponents`:\n\n```tsx\nimport * as provider from '@mdx-js/react'\nimport * as runtime from 'react/jsx-runtime'\n\nconst {default: Content} = await evaluate('# hi', {...provider, ...runtime, baseUrl: import.meta.url, ...otherOptions})\n```\n\n### `UseMdxComponents`\n\nGet components (TypeScript type).\n\n###### Parameters\n\nThere are no parameters.\n\n###### Returns\n\nComponents ([`MDXComponents` from `mdx/types.js`][mdx-types-components]).\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional types\n[`CompileOptions`][api-compile-options],\n[`EvaluateOptions`][api-evaluate-options],\n[`Fragment`][api-fragment],\n[`Jsx`][api-jsx],\n[`JsxDev`][api-jsx-dev],\n[`ProcessorOptions`][api-processor-options],\n[`RunOptions`][api-run-options], and\n[`UseMdxComponents`][api-use-mdx-components].\n\nFor types of evaluated MDX to work, make sure the TypeScript `JSX` namespace is\ntyped.\nThis is done by installing and using the types of your framework, such as\n[`@types/react`](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).\nSee [§ Types][types] on our website for information.\n\n## Architecture\n\nTo understand what this project does, it’s very important to first understand\nwhat unified does: please read through the [`unifiedjs/unified`][unified] readme\n(the part until you hit the API section is required reading).\n\n`@mdx-js/mdx` is a unified pipeline — wrapped so that most folks don’t need to\nknow about unified.\nThe processor goes through these steps:\n\n1. parse MDX (serialized markdown with embedded JSX, ESM, and expressions)\n   to mdast (markdown syntax tree)\n2. transform through remark (markdown ecosystem)\n3. transform mdast to hast (HTML syntax tree)\n4. transform through rehype (HTML ecosystem)\n5. transform hast to esast (JS syntax tree)\n6. do the work needed to get a component\n7. transform through recma (JS ecosystem)\n8. serialize esast as JavaScript\n\nThe *input* is MDX.\nThat’s serialized markdown with embedded JSX, ESM, and expressions.\nIn the case of JSX,\nthe tags are *intertwined* with markdown.\nThe markdown is parsed with [`micromark/micromark`][micromark] and the embedded\nJS with one of its extensions\n[`micromark/micromark-extension-mdxjs`][micromark-extension-mdxjs] (which in\nturn uses [acorn][]).\nThen [`syntax-tree/mdast-util-from-markdown`][mdast-util-from-markdown] and its\nextension [`syntax-tree/mdast-util-mdx`][mdast-util-mdx] are used to turn the\nresults from the parser into a syntax tree: [mdast][].\n\nMarkdown is closest to the source format.\nThis is where [remark plugins][remark-plugins] come in.\nTypically, there shouldn’t be much going on here.\nBut perhaps you want to support GFM (tables and such) or frontmatter?\nThen you can add a plugin here: `remark-gfm` or `remark-frontmatter`,\nrespectively.\n\nAfter markdown, we go to [hast][] (HTML).\nThis transformation is done by\n[`syntax-tree/mdast-util-to-hast`][mdast-util-to-hast].\nWait, what, why is HTML needed?\nPart of the reason is that we care about HTML semantics: we want to know that\nsomething is an `<a>`, not whether it’s a link with a resource (`[text](url)`)\nor a reference to a defined link definition (`[text][id]\\n\\n[id]: url`).\nSo an HTML AST is *closer* to where we want to go.\nAnother reason is that there are many things folks need when they go MDX -> JS,\nmarkdown -> HTML, or even folks who only process their HTML -> HTML: use cases\nother than MDX.\nBy having a single AST in these cases and writing a plugin that works on that\nAST, that plugin can supports *all* these use cases (for example,\n[`rehypejs/rehype-highlight`][rehype-highlight] for syntax highlighting or\n[`rehypejs/rehype-katex`][rehype-katex] for math).\nSo, this is where [rehype plugins][rehype-plugins] come in: most of the plugins,\nprobably.\n\nThen we go to JavaScript: [esast][] (JS; an\nAST which is compatible with estree but looks a bit more like other unist ASTs).\nThis transformation is done by\n[`rehype-recma`][rehype-recma].\nThis is a newer ecosystem.\nThere are some [recma plugins][recma-plugins] already.\nIt’s where `@mdx-js/mdx` does its thing: where it adds imports/exports,\nwhere it compiles JSX away into `_jsx()` calls, and where it does the other cool\nthings that it provides.\n\nFinally, The output is serialized JavaScript.\nThat final step is done by [astring][], a\nsmall and fast JS generator.\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/mdx@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © Compositor and [Vercel][]\n\n[acorn]: https://github.com/acornjs/acorn\n\n[api-compile]: #compilefile-options\n\n[api-compile-options]: #compileoptions\n\n[api-compile-sync]: #compilesyncfile-options\n\n[api-create-processor]: #createprocessoroptions\n\n[api-evaluate]: #evaluatefile-options\n\n[api-evaluate-options]: #evaluateoptions\n\n[api-evaluate-sync]: #evaluatesyncfile-options\n\n[api-fragment]: #fragment\n\n[api-jsx]: #jsx\n\n[api-jsx-dev]: #jsxdev\n\n[api-node-types]: #nodetypes\n\n[api-processor-options]: #processoroptions\n\n[api-run]: #runcode-options\n\n[api-run-options]: #runoptions\n\n[api-run-sync]: #runsynccode-options\n\n[api-use-mdx-components]: #usemdxcomponents\n\n[astring]: https://github.com/davidbonnet/astring\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/mdx\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/mdx.svg\n\n[esast]: https://github.com/syntax-tree/esast\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[esmsh]: https://esm.sh\n\n[hast]: https://github.com/syntax-tree/hast\n\n[integrations]: https://mdxjs.com/getting-started/#integrations\n\n[mdast]: https://github.com/syntax-tree/mdast\n\n[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown\n\n[mdast-util-mdx]: https://github.com/syntax-tree/mdast-util-mdx\n\n[mdast-util-to-hast]: https://github.com/syntax-tree/mdast-util-to-hast\n\n[mdx-syntax]: https://mdxjs.com/docs/what-is-mdx/#mdx-syntax\n\n[mdx-types-components]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/mdx/types.d.ts#L65\n\n[mdx-types-module]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/mdx/types.d.ts#L101\n\n[micromark]: https://github.com/micromark/micromark\n\n[micromark-extension-mdxjs]: https://github.com/micromark/micromark-extension-mdxjs\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/mdx/license\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[recma-plugins]: https://github.com/mdx-js/recma/blob/main/doc/plugins.md#list-of-plugins\n\n[rehype-highlight]: https://github.com/rehypejs/rehype-highlight\n\n[rehype-katex]: https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex\n\n[rehype-plugins]: https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins\n\n[rehype-recma]: https://github.com/mdx-js/recma/tree/main/packages/rehype-recma\n\n[remark-plugins]: https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins\n\n[remark-rehype-options]: https://github.com/remarkjs/remark-rehype#options\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[size]: https://bundlejs.com/?q=@mdx-js/mdx\n\n[size-badge]: https://img.shields.io/bundlejs/size/@mdx-js/mdx\n\n[source-map]: https://github.com/mozilla/source-map\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[support]: https://mdxjs.com/community/support/\n\n[types]: https://mdxjs.com/getting-started/#types\n\n[typescript]: https://www.typescriptlang.org\n\n[unified]: https://github.com/unifiedjs/unified\n\n[unified-pluggable-list]: https://github.com/unifiedjs/unified#pluggablelist\n\n[unified-processor]: https://github.com/unifiedjs/unified#processor\n\n[use]: #use\n\n[using-mdx]: https://mdxjs.com/docs/using-mdx/\n\n[vercel]: https://vercel.com\n\n[vfile]: https://github.com/vfile/vfile\n\n[vfile-compatible]: https://github.com/vfile/vfile#compatible\n"
  },
  {
    "path": "packages/mdx/test/compile.js",
    "content": "/**\n * @import {Doctype, Element, Root} from 'hast'\n * @import {Root as MdastRoot} from 'mdast'\n * @import {MDXComponents, MDXModule} from 'mdx/types.js'\n * @import {ComponentProps, ReactNode} from 'react'\n */\n\nimport assert from 'node:assert/strict'\nimport fs from 'node:fs/promises'\nimport {test} from 'node:test'\nimport {compile, compileSync, createProcessor, nodeTypes} from '@mdx-js/mdx'\nimport {MDXProvider} from '@mdx-js/react'\nimport React from 'react'\nimport {renderToStaticMarkup} from 'react-dom/server'\nimport rehypeRaw from 'rehype-raw'\nimport remarkGfm from 'remark-gfm'\nimport {SourceMapGenerator} from 'source-map'\nimport {VFile} from 'vfile'\nimport {run, runWhole} from './context/run.js'\n\ntest('@mdx-js/mdx: compile', async function (t) {\n  await t.test(\n    'should throw when a removed option is passed',\n    async function () {\n      try {\n        // @ts-expect-error: check how the runtime handles a removed option.\n        await compile('# hi!', {filepath: 'example.mdx'})\n      } catch (error) {\n        assert.match(String(error), /Unexpected removed option `filepath`/)\n      }\n    }\n  )\n\n  await t.test(\n    'should warn about the deprecated classic runtime',\n    async function () {\n      const warn = console.warn\n      /** @type {Array<unknown> | undefined} */\n      let messages\n\n      console.warn = capture\n\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile('# hi!', {jsxRuntime: 'classic'}))\n          )\n        ),\n        '<h1>hi!</h1>'\n      )\n\n      assert.deepEqual(messages, [\n        \"Unexpected deprecated option `jsxRuntime: 'classic'`, `pragma`, `pragmaFrag`, or `pragmaImportSource`; see <https://mdxjs.com/migrating/v3/> on how to migrate\"\n      ])\n\n      console.warn = warn\n\n      /**\n       * @param  {...unknown} parameters\n       */\n      function capture(...parameters) {\n        messages = parameters\n      }\n    }\n  )\n\n  await t.test('should compile', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('# hi!')))\n      ),\n      '<h1>hi!</h1>'\n    )\n  })\n\n  await t.test('should compile a vfile', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile(new VFile('# hi?'))))\n      ),\n      '<h1>hi?</h1>'\n    )\n  })\n\n  await t.test(\n    'should compile (sync)',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(compileSync('# hi!')))\n        ),\n        '<h1>hi!</h1>'\n      )\n    }\n  )\n\n  await t.test(\n    'should compile an empty document',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(React.createElement(await run(await compile('')))),\n        ''\n      )\n    }\n  )\n\n  await t.test('should compile an empty document (remark)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await compile('x', {remarkPlugins: [plugin]}))\n        )\n      ),\n      ''\n    )\n\n    function plugin() {\n      /**\n       * @returns {MdastRoot}\n       *   New tree.\n       */\n      return function () {\n        return {type: 'root', children: []}\n      }\n    }\n  })\n\n  await t.test('should compile an empty document (rehype)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('y', {\n              rehypePlugins: [plugin]\n            })\n          )\n        )\n      ),\n      ''\n    )\n\n    function plugin() {\n      /**\n       * @returns {Root}\n       *   New tree.\n       */\n      return function () {\n        return {type: 'root', children: []}\n      }\n    }\n  })\n\n  await t.test(\n    'should compile a document (rehype, non-representable)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('y', {\n                rehypePlugins: [plugin]\n              })\n            )\n          )\n        ),\n        ''\n      )\n\n      function plugin() {\n        /**\n         * @returns {Doctype}\n         *   New tree.\n         */\n        return function () {\n          return {type: 'doctype'}\n        }\n      }\n    }\n  )\n\n  await t.test(\n    'should compile a non-element document (rehype, single element)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('y', {\n                rehypePlugins: [plugin]\n              })\n            )\n          )\n        ),\n        '<x></x>'\n      )\n\n      function plugin() {\n        /**\n         * @returns {Element}\n         *   New tree.\n         */\n        return function () {\n          return {type: 'element', tagName: 'x', properties: {}, children: []}\n        }\n      }\n    }\n  )\n\n  await t.test('should compile custom elements', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('y', {\n              rehypePlugins: [plugin]\n            })\n          )\n        )\n      ),\n      '<a-b><b-c></b-c></a-b>'\n    )\n\n    function plugin() {\n      /**\n       * @returns {Element}\n       *   New tree.\n       */\n      return function () {\n        return {\n          type: 'element',\n          tagName: 'a-b',\n          properties: {},\n          children: [\n            {type: 'element', tagName: 'b-c', properties: {}, children: []}\n          ]\n        }\n      }\n    }\n  })\n\n  await t.test(\n    'should support the automatic runtime (`@jsxRuntime`)',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile('!', {jsxRuntime: 'automatic'}))\n          )\n        ),\n        '<p>!</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support an import source (`@jsxImportSource`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile('?', {jsxImportSource: 'react'}))\n          )\n        ),\n        '<p>?</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support `pragma`, `pragmaFrag`',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('<>%</>', {\n                jsxRuntime: 'classic',\n                pragma: 'React.createElement',\n                pragmaFrag: 'React.Fragment',\n                pragmaImportSource: 'react'\n              })\n            )\n          )\n        ),\n        '%'\n      )\n    }\n  )\n\n  await t.test(\n    'should *not* support `jsxClassicImportSource` w/o `pragma`',\n    async function () {\n      try {\n        await compile('import React from \"react\"\\n\\n.', {\n          jsxRuntime: 'classic',\n          pragmaImportSource: 'react',\n          pragma: ''\n        })\n        assert.fail()\n      } catch (error) {\n        assert.match(\n          String(error),\n          /Missing `pragma` in classic runtime with `pragmaImportSource`/\n        )\n      }\n    }\n  )\n\n  await t.test(\n    'should support passing in `components` to `MDXContent`',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('<X />')), {\n            components: {\n              /**\n               * @param {ComponentProps<'span'>} properties\n               *   Properties.\n               */\n              X(properties) {\n                return React.createElement('span', properties, '!')\n              }\n            }\n          })\n        ),\n        '<span>!</span>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support passing in `components` (for members) to `MDXContent`',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('<x.y />')), {\n            components: {\n              // @ts-expect-error: something up after `react@19`.\n              x: {\n                /**\n                 * @param {ComponentProps<'span'>} properties\n                 *   Properties.\n                 */\n                y(properties) {\n                  return React.createElement('span', properties, '?')\n                }\n              }\n            }\n          })\n        ),\n        '<span>?</span>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support passing in `components` directly and as an object w/ members',\n\n    async function () {\n      X.Y = Y\n\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('<X /> and <X.Y />')), {\n            components: {X}\n          })\n        ),\n        '<p><span>!</span> and <span>?</span></p>'\n      )\n\n      /**\n       * @param {ComponentProps<'span'>} properties\n       *   Properties.\n       * @returns {ReactNode}\n       *   Element.\n       */\n      function X(properties) {\n        return React.createElement('span', properties, '!')\n      }\n\n      /**\n       * @param {ComponentProps<'span'>} properties\n       *   Properties.\n       * @returns {ReactNode}\n       *   Element.\n       */\n      function Y(properties) {\n        return React.createElement('span', properties, '?')\n      }\n    }\n  )\n\n  await t.test(\n    'should support overwriting components by passing them to `MDXContent`',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('*a*')), {\n            components: {\n              em(properties) {\n                return React.createElement('i', properties)\n              }\n            }\n          })\n        ),\n        '<p><i>a</i></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should *not* support overwriting components in exports',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile(\n                'export function X() { return <em>a</em> }\\n\\n*a*, <X>b</X>'\n              )\n            ),\n            {\n              components: {\n                em(properties) {\n                  return React.createElement('i', properties)\n                }\n              }\n            }\n          )\n        ),\n        '<p><i>a</i>, <em>a</em></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should throw on missing components in exported components',\n    async function () {\n      await assert.rejects(async function () {\n        return renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('export function X() { return <Y /> }\\n\\n<X />')\n            )\n          )\n        )\n      }, /Y is not defined/)\n    }\n  )\n\n  await t.test(\n    'should support provided components in exported components',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            MDXProvider,\n            {\n              components: {\n                Y() {\n                  return React.createElement('span', {}, '!')\n                }\n              }\n            },\n            React.createElement(\n              await run(\n                await compile('export function X() { return <Y /> }\\n\\n<X />', {\n                  providerImportSource: '@mdx-js/react'\n                })\n              )\n            )\n          )\n        ),\n        '<span>!</span>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support provided components in exported components (arrow function)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            MDXProvider,\n            {\n              components: {\n                Y() {\n                  return React.createElement('span', {}, '!')\n                }\n              }\n            },\n            React.createElement(\n              await run(\n                await compile('export const X = () => <Y />\\n\\n<X />', {\n                  providerImportSource: '@mdx-js/react'\n                })\n              )\n            )\n          )\n        ),\n        '<span>!</span>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support custom components in exported components',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile(\n                'export function Foo({Box = \"div\"}) { return <Box>a</Box>; }\\n\\n<Foo />'\n              )\n            )\n          )\n        ),\n        '<div>a</div>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support provided component objects in exported components',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            MDXProvider,\n            {\n              components: {\n                // @ts-expect-error: something up after `react@19`.\n                y: {\n                  z() {\n                    return React.createElement('span', {}, '!')\n                  }\n                }\n              }\n            },\n            React.createElement(\n              await run(\n                await compile(\n                  'export function X() { return <y.z /> }\\n\\n<X />',\n                  {\n                    providerImportSource: '@mdx-js/react'\n                  }\n                )\n              )\n            )\n          )\n        ),\n        '<span>!</span>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support setting the layout by passing it (as `wrapper`) to `MDXContent`',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('a')), {\n            components: {\n              /**\n               * @param {ComponentProps<'div'> & {components: MDXComponents}} properties\n               *   Properties.\n               */\n              wrapper(properties) {\n                const {components, ...rest} = properties\n                return React.createElement('div', rest)\n              }\n            }\n          })\n        ),\n        '<div><p>a</p></div>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support setting the layout through a class component',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile(\n                'import React from \"react\"\\nexport default class extends React.Component { render() { return this.props.children } }\\n\\na'\n              )\n            )\n          )\n        ),\n        '<p>a</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should *not* support overwriting the layout by passing one (as `wrapper`) to `MDXContent`',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile(\n                'export default function Layout({components, ...properties}) { return <section {...properties} /> }\\n\\na'\n              )\n            ),\n            {\n              components: {\n                /**\n                 * @param {ComponentProps<'article'> & {components: MDXComponents}} properties\n                 *   Properties.\n                 */\n                wrapper(properties) {\n                  const {components, ...rest} = properties\n                  return React.createElement('article', rest)\n                }\n              }\n            }\n          )\n        ),\n        '<section><p>a</p></section>'\n      )\n    }\n  )\n\n  await t.test('should *not* support multiple layouts (1)', async function () {\n    try {\n      await compile(\n        'export default function a() {}\\n\\nexport default function b() {}\\n\\n.'\n      )\n      assert.fail()\n    } catch (error) {\n      assert.match(\n        String(error),\n        /Unexpected duplicate layout, expected a single layout \\(previous: 1:1-1:31\\)/\n      )\n    }\n  })\n\n  await t.test('should *not* support multiple layouts (2)', async function () {\n    try {\n      await compile(\n        'export default function a() {}\\n\\nexport {Layout as default} from \"./components.js\"\\n\\n.'\n      )\n      assert.fail()\n    } catch (error) {\n      assert.match(\n        String(error),\n        /Unexpected duplicate layout, expected a single layout \\(previous: 1:1-1:31\\)/\n      )\n    }\n  })\n\n  await t.test(\n    'should support an identifier as an export default',\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('export default a')))\n        )\n      }, new ReferenceError('a is not defined'))\n    }\n  )\n\n  await t.test(\n    'should throw if a required component is not passed',\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('<X />')))\n        )\n      }, /Expected component `X` to be defined/)\n    }\n  )\n\n  await t.test(\n    'should throw if a required member is not passed',\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('<a.b />')))\n        )\n      }, /Expected object `a` to be defined/)\n    }\n  )\n\n  await t.test(\n    'should throw if a used member is not defined locally',\n\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile('export const a = {}\\n\\n<a.b />'))\n          )\n        )\n      }, /Expected component `a.b` to be defined/)\n    }\n  )\n\n  await t.test(\n    'should throw if a used member is not defined locally (JSX in a function)',\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('<a render={function () { return <x.y /> }} />')\n            )\n          )\n        )\n      }, /Expected object `x` to be defined/)\n    }\n  )\n\n  await t.test(\n    'should render if a used member is defined locally (JSX in a function)',\n    async function () {\n      const Content = await run(\n        await compile('<a render={function (x) { return <x.y /> }} />')\n      )\n\n      console.log('note: the following warning is expected!')\n      const result = renderToStaticMarkup(React.createElement(Content))\n      console.log('note: the preceding warning is expected!')\n\n      assert.equal(result, '<a></a>')\n    }\n  )\n\n  await t.test(\n    'should expose source information in the automatic jsx dev runtime',\n    async function () {\n      const file = await compile(\n        {value: '<div />', path: 'path/to/file.js'},\n        {development: true}\n      )\n\n      ;(await run(file))({})\n\n      // To do: React 19 removes this, figure out a way to test if this still works?\n      // assert.deepEqual(developmentSourceNode._source, {\n      //   fileName: 'path/to/file.js',\n      //   lineNumber: 1,\n      //   columnNumber: 1\n      // })\n    }\n  )\n\n  await t.test(\n    'should pass more info to errors w/ `development: true`',\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile('<X />', {development: true}))\n          )\n        )\n      }, /It’s referenced in your code at `1:1-1:6/)\n    }\n  )\n\n  await t.test(\n    'should show what file contains the error w/ `development: true`, and `path`',\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile(\n                {value: 'asd <a.b />', path: 'folder/example.mdx'},\n                {development: true}\n              )\n            )\n          )\n        )\n      }, /It’s referenced in your code at `1:5-1:12` in `folder\\/example.mdx`/)\n    }\n  )\n\n  await t.test(\n    'should support setting components through context with a `providerImportSource`',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            MDXProvider,\n            {\n              components: {\n                em(properties) {\n                  return React.createElement('i', properties)\n                }\n              }\n            },\n            React.createElement(\n              await run(\n                await compile('*z*', {providerImportSource: '@mdx-js/react'})\n              )\n            )\n          )\n        ),\n        '<p><i>z</i></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should throw if a required component is not passed or given to `MDXProvider`',\n    async function () {\n      await assert.rejects(async function () {\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('<X />', {providerImportSource: '@mdx-js/react'})\n            )\n          )\n        )\n      }, /Expected component `X` to be defined/)\n    }\n  )\n\n  await t.test(\n    'should detect as `mdx` by default',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile({value: '\\tx'})))\n        ),\n        '<p>x</p>'\n      )\n    }\n  )\n\n  await t.test('should detect `.md` as `md`', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await compile({value: '\\tx', path: 'y.md'}))\n        )\n      ),\n      '<pre><code>x\\n</code></pre>'\n    )\n  })\n\n  await t.test('should detect `.mdx` as `mdx`', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await compile({value: '\\tx', path: 'y.mdx'}))\n        )\n      ),\n      '<p>x</p>'\n    )\n  })\n\n  await t.test('should not “detect” `.md` w/ `format: mdx`', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile({value: '\\tx', path: 'y.md'}, {format: 'mdx'})\n          )\n        )\n      ),\n      '<p>x</p>'\n    )\n  })\n\n  await t.test('should not “detect” `.mdx` w/ `format: md`', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile({value: '\\tx', path: 'y.mdx'}, {format: 'md'})\n          )\n        )\n      ),\n      '<pre><code>x\\n</code></pre>'\n    )\n  })\n\n  await t.test(\n    'should not support HTML in markdown by default',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile({value: '<q>r</q>', path: 's.md'}))\n          )\n        ),\n        '<p>r</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support HTML in markdown w/ `rehype-raw`',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile(\n                {value: '<q>r</q>', path: 's.md'},\n                {rehypePlugins: [rehypeRaw]}\n              )\n            )\n          )\n        ),\n        '<p><q>r</q></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support injected MDX nodes w/ `rehype-raw`',\n\n    async function () {\n      assert.match(\n        String(\n          await compile('a', {\n            format: 'md',\n            remarkPlugins: [plugin],\n            rehypePlugins: [[rehypeRaw, {passThrough: nodeTypes}]]\n          })\n        ),\n        /var a = 1/\n      )\n\n      function plugin() {\n        /**\n         * @param {MdastRoot} tree\n         *   Tree.\n         * @returns {undefined}\n         *   Nothing.\n         */\n        return function (tree) {\n          tree.children.unshift({\n            type: 'mdxjsEsm',\n            value: '',\n            data: {\n              estree: {\n                type: 'Program',\n                comments: [],\n                sourceType: 'module',\n                body: [\n                  {\n                    type: 'VariableDeclaration',\n                    kind: 'var',\n                    declarations: [\n                      {\n                        type: 'VariableDeclarator',\n                        id: {type: 'Identifier', name: 'a'},\n                        init: {type: 'Literal', value: 1}\n                      }\n                    ]\n                  }\n                ]\n              }\n            }\n          })\n        }\n      }\n    }\n  )\n\n  await t.test(\n    'should support tag names that are not valid JavaScript identifiers with layouts (GH-2112)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('export default function () {}', {\n                rehypePlugins: [plugin]\n              })\n            )\n          )\n        ),\n        ''\n      )\n\n      function plugin() {\n        /**\n         * @param {Root} tree\n         *   Tree.\n         * @returns {undefined}\n         *   Nothing.\n         */\n\n        return function (tree) {\n          tree.children.push({\n            type: 'element',\n            tagName: 'custom-element',\n            properties: {},\n            children: []\n          })\n        }\n      }\n    }\n  )\n\n  await t.test(\n    'should support an `await` expression in content (GH-2242)',\n    async function () {\n      const element = React.createElement(\n        await run(await compile('{await Promise.resolve(42)}'))\n      )\n\n      try {\n        // Not supported yet by React, so it throws.\n        renderToStaticMarkup(element)\n        assert.fail()\n      } catch (error) {\n        assert.match(\n          String(error),\n          /A component suspended while responding to synchronous input/\n        )\n      }\n    }\n  )\n\n  await t.test(\n    'should not detect `await` inside functions (GH-2242)',\n    async function () {\n      const value = `{(function () {\n  return 21\n\n  async function unused() {\n    await Promise.resolve(42)\n  }\n})()}`\n      const element = React.createElement(await run(await compile(value)))\n\n      assert.equal(renderToStaticMarkup(element), '21')\n    }\n  )\n\n  await t.test('should support source maps', async function () {\n    const base = new URL('context/', import.meta.url)\n    const url = new URL('sourcemap.js', base)\n    const file = await compile(\n      'export function Component() {\\n  a()\\n}\\n\\n<Component />',\n      {SourceMapGenerator}\n    )\n\n    file.value +=\n      '\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,' +\n      // eslint-disable-next-line no-restricted-globals\n      btoa(JSON.stringify(file.map)) +\n      '\\n'\n\n    await fs.writeFile(url, String(file))\n\n    /** @type {MDXModule} */\n    const result = await import(url.href + '#' + Math.random())\n    const Content = result.default\n\n    // Note: is this test not working?\n    // Make sure to run tests w/ `--enable-source-maps`.\n    // Or run `npm run test-api`.\n    assert.throws(\n      function () {\n        renderToStaticMarkup(React.createElement(Content))\n      },\n      function (error) {\n        const exception = /** @type {Error} */ (error)\n        const match = /at Component \\(([^)]+)\\)/.exec(String(exception.stack))\n        const actual = match?.[1].split(/\\\\|\\//g).join('/') || ''\n        return (base.pathname + 'unknown.js:2:3').endsWith(actual)\n      }\n    )\n\n    await fs.unlink(url)\n  })\n\n  await t.test(\n    'should leave bare specifiers untouched w/ `baseUrl`',\n    async function () {\n      const dlv = await import('dlv')\n      const result = await runWhole(\n        await compile('import dlv from \"dlv\"\\nexport {dlv}', {\n          baseUrl: 'https://example.com'\n        })\n      )\n\n      assert.equal(result.dlv, dlv.default)\n    }\n  )\n\n  await t.test(\n    'should leave URLs as specifiers untouched w/ `baseUrl`',\n    async function () {\n      const result = await runWhole(\n        await compile('import fs from \"node:fs/promises\"\\nexport {fs}', {\n          baseUrl: 'https://example.com'\n        })\n      )\n\n      assert.equal(result.fs, fs)\n    }\n  )\n\n  await t.test(\n    'should resolve relative specifiers w/ `baseUrl`',\n    async function () {\n      // Note: this is run inside `context/`, so it would normally have to be `./data.js`.\n      // But because we rewrite relative to this file `compile.js`, it’s `./context/data.js`.\n      const result = await runWhole(\n        await compile('import num from \"./context/data.js\"\\nexport {num}', {\n          baseUrl: import.meta.url\n        })\n      )\n\n      assert.equal(result.num, 6.28)\n    }\n  )\n\n  await t.test('should support `baseUrl` as a URL', async function () {\n    // Same as above but uses a URL.\n    const result = await runWhole(\n      await compile('import num from \"./context/data.js\"\\nexport {num}', {\n        baseUrl: new URL(import.meta.url)\n      })\n    )\n\n    assert.equal(result.num, 6.28)\n  })\n\n  await t.test(\n    'should support importing dynamic expressions',\n    async function () {\n      // Same as above but uses a URL.\n      const result = await runWhole(\n        await compile(\n          'export async function get() {\\n  const mod = await import(\"./context/data.js\");\\n  return mod.number\\n}',\n          {\n            baseUrl: new URL(import.meta.url)\n          }\n        )\n      )\n\n      const get = result.get\n      assert.ok(typeof get === 'function')\n      assert.equal(await get(), 3.14)\n    }\n  )\n})\n\ntest('@mdx-js/mdx: compile (JSX)', async function (t) {\n  await t.test('should serialize JSX w/ `jsx: true`', async function () {\n    assert.equal(\n      String(await compile('*a*', {jsx: true})),\n      [\n        '/*@jsxRuntime automatic*/',\n        '/*@jsxImportSource react*/',\n        'function _createMdxContent(props) {',\n        '  const _components = {',\n        '    em: \"em\",',\n        '    p: \"p\",',\n        '    ...props.components',\n        '  };',\n        '  return <_components.p><_components.em>{\"a\"}</_components.em></_components.p>;',\n        '}',\n        'export default function MDXContent(props = {}) {',\n        '  const {wrapper: MDXLayout} = props.components || ({});',\n        '  return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',\n        '}',\n        ''\n      ].join('\\n')\n    )\n  })\n\n  await t.test('should serialize props', async function () {\n    assert.equal(\n      String(await compile('<a {...b} c d=\"1\" e={1} />', {jsx: true})),\n      [\n        '/*@jsxRuntime automatic*/',\n        '/*@jsxImportSource react*/',\n        'function _createMdxContent(props) {',\n        '  return <a {...b} c d=\"1\" e={1} />;',\n        '}',\n        'export default function MDXContent(props = {}) {',\n        '  const {wrapper: MDXLayout} = props.components || ({});',\n        '  return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',\n        '}',\n        ''\n      ].join('\\n')\n    )\n  })\n\n  await t.test(\n    'should serialize fragments, namespaces, members',\n    async function () {\n      assert.equal(\n        String(await compile('<><a:b /><c.d/></>', {jsx: true})),\n        [\n          '/*@jsxRuntime automatic*/',\n          '/*@jsxImportSource react*/',\n          'function _createMdxContent(props) {',\n          '  const {c} = props.components || ({});',\n          '  if (!c) _missingMdxReference(\"c\", false);',\n          '  if (!c.d) _missingMdxReference(\"c.d\", true);',\n          '  return <><><a:b /><c.d /></></>;',\n          '}',\n          'export default function MDXContent(props = {}) {',\n          '  const {wrapper: MDXLayout} = props.components || ({});',\n          '  return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',\n          '}',\n          'function _missingMdxReference(id, component) {',\n          '  throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\");',\n          '}',\n          ''\n        ].join('\\n')\n      )\n    }\n  )\n\n  await t.test('should serialize fragments, expressions', async function () {\n    assert.equal(\n      String(await compile('<>a {/* 1 */} b</>', {jsx: true})),\n      [\n        '/*@jsxRuntime automatic*/',\n        '/*@jsxImportSource react*/',\n        '/*1*/',\n        'function _createMdxContent(props) {',\n        '  return <><>{\"a \"}{}{\" b\"}</></>;',\n        '}',\n        'export default function MDXContent(props = {}) {',\n        '  const {wrapper: MDXLayout} = props.components || ({});',\n        '  return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',\n        '}',\n        ''\n      ].join('\\n')\n    )\n  })\n\n  await t.test(\n    'should serialize custom elements inside expressions',\n    async function () {\n      assert.equal(\n        String(await compile('{<a-b></a-b>}', {jsx: true})),\n        [\n          '/*@jsxRuntime automatic*/',\n          '/*@jsxImportSource react*/',\n          'function _createMdxContent(props) {',\n          '  return <>{<a-b></a-b>}</>;',\n          '}',\n          'export default function MDXContent(props = {}) {',\n          '  const {wrapper: MDXLayout} = props.components || ({});',\n          '  return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',\n          '}',\n          ''\n        ].join('\\n')\n      )\n    }\n  )\n\n  await t.test('should support using props', async function () {\n    assert.equal(\n      String(await compile('Hello {props.name}', {jsx: true})),\n      [\n        '/*@jsxRuntime automatic*/',\n        '/*@jsxImportSource react*/',\n        'function _createMdxContent(props) {',\n        '  const _components = {',\n        '    p: \"p\",',\n        '    ...props.components',\n        '  };',\n        '  return <_components.p>{\"Hello \"}{props.name}</_components.p>;',\n        '}',\n        'export default function MDXContent(props = {}) {',\n        '  const {wrapper: MDXLayout} = props.components || ({});',\n        '  return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',\n        '}',\n        ''\n      ].join('\\n')\n    )\n  })\n\n  await t.test(\n    'should not have a conditional expression for `MDXLayout` when there is an internal layout',\n    async function () {\n      assert.equal(\n        String(\n          await compile(\n            'export default function Layout({components, ...props}) { return <section {...props} /> }\\n\\na',\n            {jsx: true}\n          )\n        ),\n        [\n          '/*@jsxRuntime automatic*/',\n          '/*@jsxImportSource react*/',\n          'const MDXLayout = function Layout({components, ...props}) {',\n          '  return <section {...props} />;',\n          '};',\n          'function _createMdxContent(props) {',\n          '  const _components = {',\n          '    p: \"p\",',\n          '    ...props.components',\n          '  };',\n          '  return <_components.p>{\"a\"}</_components.p>;',\n          '}',\n          'export default function MDXContent(props = {}) {',\n          '  return <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout>;',\n          '}',\n          ''\n        ].join('\\n')\n      )\n    }\n  )\n\n  await t.test(\n    'should combine passing `components` w/ props and a provider',\n    async function () {\n      assert.equal(\n        String(\n          await compile('a', {\n            jsx: true,\n            providerImportSource: '@mdx-js/react'\n          })\n        ),\n        [\n          '/*@jsxRuntime automatic*/',\n          '/*@jsxImportSource react*/',\n          'import {useMDXComponents as _provideComponents} from \"@mdx-js/react\";',\n          'function _createMdxContent(props) {',\n          '  const _components = {',\n          '    p: \"p\",',\n          '    ..._provideComponents(),',\n          '    ...props.components',\n          '  };',\n          '  return <_components.p>{\"a\"}</_components.p>;',\n          '}',\n          'export default function MDXContent(props = {}) {',\n          '  const {wrapper: MDXLayout} = {',\n          '    ..._provideComponents(),',\n          '    ...props.components',\n          '  };',\n          '  return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);',\n          '}',\n          ''\n        ].join('\\n')\n      )\n    }\n  )\n\n  await t.test(\n    'should not inject a provider for JSX in ESM',\n    async function () {\n      assert.equal(\n        String(\n          await compile(\n            'export function A() { return <span /> }\\n\\nexport class B { render() { return <div /> } }',\n            {providerImportSource: '@mdx-js/react'}\n          )\n        ),\n        [\n          'import {Fragment as _Fragment, jsx as _jsx} from \"react/jsx-runtime\";',\n          'import {useMDXComponents as _provideComponents} from \"@mdx-js/react\";',\n          'export function A() {',\n          '  return _jsx(\"span\", {});',\n          '}',\n          'export class B {',\n          '  render() {',\n          '    return _jsx(\"div\", {});',\n          '  }',\n          '}',\n          'function _createMdxContent(props) {',\n          '  return _jsx(_Fragment, {});',\n          '}',\n          'export default function MDXContent(props = {}) {',\n          '  const {wrapper: MDXLayout} = {',\n          '    ..._provideComponents(),',\n          '    ...props.components',\n          '  };',\n          '  return MDXLayout ? _jsx(MDXLayout, {',\n          '    ...props,',\n          '    children: _jsx(_createMdxContent, {',\n          '      ...props',\n          '    })',\n          '  }) : _createMdxContent(props);',\n          '}',\n          ''\n        ].join('\\n')\n      )\n    }\n  )\n\n  await t.test(\n    'should not inject a provider for JSX in expressions',\n    async function () {\n      assert.equal(\n        String(\n          await compile('{ <span /> }\\n\\nAnd also { <div /> }.', {\n            providerImportSource: '@mdx-js/react'\n          })\n        ),\n        [\n          'import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from \"react/jsx-runtime\";',\n          'import {useMDXComponents as _provideComponents} from \"@mdx-js/react\";',\n          'function _createMdxContent(props) {',\n          '  const _components = {',\n          '    p: \"p\",',\n          '    ..._provideComponents(),',\n          '    ...props.components',\n          '  };',\n          '  return _jsxs(_Fragment, {',\n          '    children: [_jsx(\"span\", {}), \"\\\\n\", _jsxs(_components.p, {',\n          '      children: [\"And also \", _jsx(\"div\", {}), \".\"]',\n          '    })]',\n          '  });',\n          '}',\n          'export default function MDXContent(props = {}) {',\n          '  const {wrapper: MDXLayout} = {',\n          '    ..._provideComponents(),',\n          '    ...props.components',\n          '  };',\n          '  return MDXLayout ? _jsx(MDXLayout, {',\n          '    ...props,',\n          '    children: _jsx(_createMdxContent, {',\n          '      ...props',\n          '    })',\n          '  }) : _createMdxContent(props);',\n          '}',\n          ''\n        ].join('\\n')\n      )\n    }\n  )\n\n  await t.test(\n    'should serialize double quotes in attribute values',\n    async function () {\n      assert.match(\n        String(await compile(\"{<w x='y \\\" z' />}\", {jsx: true})),\n        /x=\"y &quot; z\"/\n      )\n    }\n  )\n\n  await t.test(\n    'should serialize `<` and `{` in JSX text',\n\n    async function () {\n      assert.match(\n        String(await compile('{<>a &amp; b &#123; c &lt; d</>}', {jsx: true})),\n        /a & b &#123; c &lt; d/\n      )\n    }\n  )\n\n  await t.test(\n    'should use React props and DOM styles by default',\n    async function () {\n      assert.match(\n        String(\n          await compile('', {\n            rehypePlugins: [plugin],\n            jsx: true\n          })\n        ),\n        /className=\"b\"/\n      )\n\n      function plugin() {\n        /**\n         * @param {Root} tree\n         *   Tree.\n         * @returns {undefined}\n         *   Nothing.\n         */\n        return function (tree) {\n          tree.children.push({\n            type: 'element',\n            tagName: 'a',\n            properties: {\n              className: 'b',\n              style: '-webkit-box-shadow: 0 0 1px 0 red'\n            },\n            children: []\n          })\n        }\n      }\n    }\n  )\n\n  await t.test(\n    'should support `elementAttributeNameCase` and `stylePropertyNameCase`',\n    async function () {\n      assert.match(\n        String(\n          await compile('', {\n            rehypePlugins: [plugin],\n            elementAttributeNameCase: 'html',\n            stylePropertyNameCase: 'css',\n            jsx: true\n          })\n        ),\n        /class=\"b\"/\n      )\n\n      function plugin() {\n        /**\n         * @param {Root} tree\n         *   Tree.\n         * @returns {undefined}\n         *   Nothing.\n         */\n        return function (tree) {\n          tree.children.push({\n            type: 'element',\n            tagName: 'a',\n            properties: {\n              className: 'b',\n              style: '-webkit-box-shadow: 0 0 1px 0 red'\n            },\n            children: []\n          })\n        }\n      }\n    }\n  )\n\n  await t.test('should support `tableCellAlignToStyle`', async function () {\n    assert.match(\n      String(\n        await compile('| a |\\n| :- |', {\n          remarkPlugins: [remarkGfm],\n          tableCellAlignToStyle: true,\n          jsx: true\n        })\n      ),\n      /textAlign: \"left\"/\n    )\n\n    assert.match(\n      String(\n        await compile('| a |\\n| :- |', {\n          remarkPlugins: [remarkGfm],\n          tableCellAlignToStyle: false,\n          jsx: true\n        })\n      ),\n      /align=\"left\"/\n    )\n  })\n})\n\ntest('@mdx-js/mdx: createProcessor', async function (t) {\n  await t.test(\n    'should support `createProcessor`',\n\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await createProcessor().process('x')))\n        ),\n        '<p>x</p>'\n      )\n    }\n  )\n\n  await t.test('should support `format: md`', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await createProcessor({format: 'md'}).process('\\tx'))\n        )\n      ),\n      '<pre><code>x\\n</code></pre>'\n    )\n  })\n\n  await t.test('should support `format: mdx`', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await createProcessor({format: 'mdx'}).process('\\tx'))\n        )\n      ),\n      '<p>x</p>'\n    )\n  })\n\n  await t.test('should not support `format: detect`', async function () {\n    assert.throws(function () {\n      // @ts-expect-error: check how runtime handles an incorrect `format: 'detect'`.\n      createProcessor({format: 'detect'})\n    }, /Unexpected `format: 'detect'`/)\n  })\n})\n"
  },
  {
    "path": "packages/mdx/test/context/components.js",
    "content": "/**\n * @import {ComponentProps} from 'react'\n */\n\nimport React from 'react'\n\n/**\n * @param {Readonly<ComponentProps<'span'>>} properties\n *   Properties.\n * @returns\n *   `span` element.\n */\nexport function Pill(properties) {\n  return React.createElement('span', {...properties, style: {color: 'red'}})\n}\n\n/**\n * @param {Readonly<ComponentProps<'div'>>} properties\n *   Properties.\n * @returns\n *   `div` element.\n */\nexport function Layout(properties) {\n  return React.createElement('div', {...properties, style: {color: 'red'}})\n}\n\nexport default Layout\n"
  },
  {
    "path": "packages/mdx/test/context/data.js",
    "content": "/**\n * Number.\n */\nexport const number = 3.14\n\n/**\n * Object.\n */\nexport const object = {a: 1, b: 2}\n\n/**\n * Array.\n */\nexport const array = [1, 2]\n\n/**\n * Number.\n */\nexport default 2 * number\n"
  },
  {
    "path": "packages/mdx/test/context/run.js",
    "content": "/**\n * @import {MDXContent, MDXModule} from 'mdx/types.js'\n * @import {Compatible} from 'vfile'\n */\n\nimport fs from 'node:fs/promises'\n\n/**\n * @param {Readonly<Compatible>} input\n *   MDX document.\n * @return {Promise<MDXContent>}\n *   MDX content.\n */\nexport async function run(input) {\n  const result = await runWhole(input)\n  return result.default\n}\n\n/**\n *\n * @param {Readonly<Compatible>} input\n *   MDX document.\n * @return {Promise<MDXModule>}\n *   MDX module.\n */\nexport async function runWhole(input) {\n  const fileName = 'fixture-' + Math.random() + '.js'\n  const fileUrl = new URL(fileName, import.meta.url)\n  const document = String(input)\n\n  await fs.writeFile(fileUrl, document)\n\n  try {\n    /** @type {MDXModule} */\n    return await import(fileUrl.href)\n  } finally {\n    // This is not a bug: the `finally` runs after the whole `try` block, but\n    // before the `return`.\n    await fs.rm(fileUrl)\n  }\n}\n"
  },
  {
    "path": "packages/mdx/test/core.js",
    "content": "import assert from 'node:assert/strict'\nimport {test} from 'node:test'\n\ntest('@mdx-js/mdx: core', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('@mdx-js/mdx')).sort(), [\n      'compile',\n      'compileSync',\n      'createProcessor',\n      'evaluate',\n      'evaluateSync',\n      'nodeTypes',\n      'run',\n      'runSync'\n    ])\n  })\n})\n"
  },
  {
    "path": "packages/mdx/test/evaluate.js",
    "content": "import assert from 'node:assert/strict'\nimport {test} from 'node:test'\nimport {evaluate, evaluateSync, compile} from '@mdx-js/mdx'\nimport * as provider from '@mdx-js/react'\nimport {renderToStaticMarkup} from 'react-dom/server'\nimport * as runtime from 'react/jsx-runtime'\nimport * as developmentRuntime from 'react/jsx-dev-runtime'\nimport React from 'react'\n\ntest('@mdx-js/mdx: evaluate', async function (t) {\n  await t.test('should throw on missing `Fragment`', async function () {\n    try {\n      // @ts-expect-error: check how the runtime handles missing options.\n      await evaluate('a')\n      assert.fail()\n    } catch (error) {\n      assert.match(String(error), /Expected `Fragment` given to `evaluate`/)\n    }\n  })\n\n  await t.test('should throw on missing `jsx`', async function () {\n    try {\n      await evaluate('a', {Fragment: runtime.Fragment})\n      assert.fail()\n    } catch (error) {\n      assert.match(String(error), /Expected `jsx` given to `evaluate`/)\n    }\n  })\n\n  await t.test('should throw on missing `jsxs`', async function () {\n    try {\n      await evaluate('a', {Fragment: runtime.Fragment, jsx: runtime.jsx})\n      assert.fail()\n    } catch (error) {\n      assert.match(String(error), /Expected `jsxs` given to `evaluate`/)\n    }\n  })\n\n  await t.test(\n    'should throw on missing `jsxDEV` in dev mode',\n    async function () {\n      try {\n        await evaluate('a', {Fragment: runtime.Fragment, development: true})\n        assert.fail()\n      } catch (error) {\n        assert.match(String(error), /Expected `jsxDEV` given to `evaluate`/)\n      }\n    }\n  )\n\n  await t.test('should evaluate', async function () {\n    const result = await evaluate('# hi!', runtime)\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(result.default)),\n      '<h1>hi!</h1>'\n    )\n  })\n\n  await t.test('should evaluate (sync)', async function () {\n    const result = evaluateSync('# hi!', runtime)\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(result.default)),\n      '<h1>hi!</h1>'\n    )\n  })\n\n  await t.test('should evaluate (dev)', async function () {\n    const result = await evaluate('# hi dev!', {\n      development: true,\n      ...developmentRuntime\n    })\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(result.default)),\n      '<h1>hi dev!</h1>'\n    )\n  })\n\n  await t.test('should evaluate (async, dev)', async function () {\n    const result = await evaluate('# hi dev!', {\n      development: true,\n      ...developmentRuntime\n    })\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(result.default)),\n      '<h1>hi dev!</h1>'\n    )\n  })\n\n  await t.test(\n    'should throw a runtime error when using `import` w/o `baseUrl`',\n    async function () {\n      try {\n        await evaluate('import \"a\"', runtime)\n        assert.fail()\n      } catch (error) {\n        const cause = /** @type {Error} */ (error)\n        assert.match(\n          String(cause),\n          /Unexpected missing `options.baseUrl` needed to support/\n        )\n      }\n    }\n  )\n\n  await t.test(\n    'should throw a runtime error when using `export … from` w/o `baseUrl`',\n    async function () {\n      try {\n        await evaluate('export {a} from \"b\"', runtime)\n        assert.fail()\n      } catch (error) {\n        const cause = /** @type {Error} */ (error)\n        assert.match(\n          String(cause),\n          /Unexpected missing `options.baseUrl` needed to support/\n        )\n      }\n    }\n  )\n\n  await t.test(\n    'should throw a runtime error when using `export … from` w/o `baseUrl`',\n    async function () {\n      try {\n        await evaluate('{import.meta.url}', runtime)\n        assert.fail()\n      } catch (error) {\n        const cause = /** @type {Error} */ (error)\n        assert.match(\n          String(cause),\n          /Unexpected missing `options.baseUrl` needed to support/\n        )\n      }\n    }\n  )\n\n  await t.test(\n    'should support an `import` of a relative url w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'import {number} from \"./context/data.js\"\\n\\n{number}',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      assert.equal(\n        renderToStaticMarkup(React.createElement(result.default)),\n        '3.14'\n      )\n    }\n  )\n\n  await t.test(\n    'should support an `import` of a full url w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'import {number} from \"' +\n          new URL('context/data.js', import.meta.url) +\n          '\"\\n\\n{number}',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      assert.equal(\n        renderToStaticMarkup(React.createElement(result.default)),\n        '3.14'\n      )\n    }\n  )\n\n  await t.test(\n    'should support an `import` w/o specifiers w/o `baseUrl` (expecting it at runtime)',\n    async function () {\n      const document = String(\n        await compile('import \"a\"', {outputFormat: 'function-body'})\n      )\n      assert.match(document, /const _importMetaUrl = arguments\\[0]\\.baseUrl/)\n      assert.match(\n        document,\n        /await import\\(_resolveDynamicMdxSpecifier\\(\"a\"\\)\\);/\n      )\n    }\n  )\n\n  await t.test(\n    'should support an `import` w/ 0 specifiers w/o `baseUrl` (expecting it at runtime)',\n    async function () {\n      const document = String(\n        await compile('import {} from \"a\"', {outputFormat: 'function-body'})\n      )\n      assert.match(document, /const _importMetaUrl = arguments\\[0]\\.baseUrl/)\n      assert.match(\n        document,\n        /await import\\(_resolveDynamicMdxSpecifier\\(\"a\"\\)\\);/\n      )\n    }\n  )\n\n  await t.test(\n    'should support a namespace import w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'import * as x from \"./context/components.js\"\\n\\n<x.Pill>Hi!</x.Pill>',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      assert.equal(\n        renderToStaticMarkup(React.createElement(result.default)),\n        '<span style=\"color:red\">Hi!</span>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support a namespace import and a bare specifier w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'import Div, * as x from \"./context/components.js\"\\n\\n<x.Pill>a</x.Pill> and <Div>b</Div>',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      assert.equal(\n        renderToStaticMarkup(React.createElement(result.default)),\n        '<p><span style=\"color:red\">a</span> and <div style=\"color:red\">b</div></p>'\n      )\n    }\n  )\n\n  await t.test('should support an `export`', async function () {\n    const result = await evaluate('export const a = 1\\n\\n{a}', runtime)\n\n    assert.equal(renderToStaticMarkup(React.createElement(result.default)), '1')\n\n    assert.equal(result.a, 1)\n  })\n\n  await t.test('should support an `export function`', async function () {\n    const result = await evaluate(\n      'export function a() { return 1 }\\n\\n{a()}',\n      runtime\n    )\n\n    assert.equal(renderToStaticMarkup(React.createElement(result.default)), '1')\n\n    assert.ok(typeof result.a === 'function')\n\n    assert.equal(result.a(), 1)\n  })\n\n  await t.test('should support an `export class`', async function () {\n    const result = await evaluate(\n      'export class A { constructor() { this.b = 1 } }\\n\\n{new A().b}',\n      runtime\n    )\n\n    assert.equal(renderToStaticMarkup(React.createElement(result.default)), '1')\n\n    const A = /** @type {new () => {b: number}} */ (result.A)\n    const a = new A()\n    assert.equal(a.b, 1)\n  })\n\n  await t.test('should support an `export as`', async function () {\n    const result = await evaluate(\n      'export const a = 1\\nexport {a as b}\\n\\n{a}',\n      runtime\n    )\n\n    assert.equal(renderToStaticMarkup(React.createElement(result.default)), '1')\n\n    assert.equal(result.a, 1, 'should support an `export as` (2)')\n    assert.equal(result.b, 1, 'should support an `export as` (3)')\n  })\n\n  await t.test('should support an `export default`', async function () {\n    const result = await evaluate(\n      'export default function Layout({components, ...properties}) { return <section {...properties} /> }\\n\\na',\n      runtime\n    )\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(result.default)),\n      '<section><p>a</p></section>'\n    )\n  })\n\n  await t.test(\n    'should support an `export from` w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'export {number} from \"./context/data.js\"',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      assert.equal(result.number, 3.14)\n    }\n  )\n\n  await t.test('should support an `export` w/ `baseUrl`', async function () {\n    const result = await evaluate(\n      'import {number} from \"./context/data.js\"\\nexport {number}',\n      {baseUrl: import.meta.url, ...runtime}\n    )\n\n    assert.equal(result.number, 3.14)\n  })\n\n  await t.test(\n    'should support an `export as from` w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'export {number as data} from \"./context/data.js\"',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      assert.equal(result.data, 3.14)\n    }\n  )\n\n  await t.test(\n    'should support an `export default as from` w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'export {default as data} from \"./context/data.js\"',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      assert.equal(result.data, 6.28)\n    }\n  )\n\n  await t.test(\n    'should support an `export all from` w/ `baseUrl`',\n    async function () {\n      const result = await evaluate('export * from \"./context/data.js\"', {\n        baseUrl: import.meta.url,\n        ...runtime\n      })\n\n      assert.deepEqual(\n        {...result, default: undefined},\n        {array: [1, 2], default: undefined, number: 3.14, object: {a: 1, b: 2}}\n      )\n    }\n  )\n\n  await t.test(\n    'should support an `export * from`, but prefer explicit exports, w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'export {default as number} from \"./context/data.js\"\\nexport * from \"./context/data.js\"',\n        {baseUrl: import.meta.url, ...runtime}\n      )\n\n      // I’m not sure if this makes sense, but it is how Node works.\n      assert.deepEqual(\n        {...result, default: undefined},\n        {array: [1, 2], default: undefined, number: 6.28, object: {a: 1, b: 2}}\n      )\n    }\n  )\n\n  await t.test(\n    'should support rewriting `import.meta.url` w/ `baseUrl`',\n    async function () {\n      const result = await evaluate(\n        'export const x = new URL(\"example.png\", import.meta.url).href',\n        {baseUrl: 'https://example.com', ...runtime}\n      )\n\n      assert.equal(result.x, 'https://example.com/example.png')\n    }\n  )\n\n  await t.test(\n    'should support rewriting `import.meta.url` w/ `baseUrl` as an URL',\n    async function () {\n      const result = await evaluate(\n        'export const x = new URL(\"example.png\", import.meta.url).href',\n        {baseUrl: new URL('https://example.com'), ...runtime}\n      )\n\n      assert.equal(result.x, 'https://example.com/example.png')\n    }\n  )\n\n  await t.test('should support a given components', async function () {\n    const result = await evaluate('<X/>', runtime)\n\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(result.default, {\n          components: {\n            X() {\n              return React.createElement('span', {}, '!')\n            }\n          }\n        })\n      ),\n      '<span>!</span>'\n    )\n  })\n\n  await t.test(\n    'should support a provider w/ `useMDXComponents`',\n    async function () {\n      const result = await evaluate('<X/>', {...runtime, ...provider})\n\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            provider.MDXProvider,\n            {\n              components: {\n                X() {\n                  return React.createElement('span', {}, '!')\n                }\n              }\n            },\n            React.createElement(result.default)\n          )\n        ),\n        '<span>!</span>'\n      )\n    }\n  )\n})\n"
  },
  {
    "path": "packages/mdx/test/index.js",
    "content": "/* eslint-disable import-x/no-unassigned-import */\nimport './compile.js'\nimport './core.js'\nimport './evaluate.js'\nimport './syntax.js'\n"
  },
  {
    "path": "packages/mdx/test/syntax.js",
    "content": "// Register directive nodes in mdast:\n/// <reference types=\"mdast-util-directive\" />\n\n/**\n * @import {Root as MdastRoot} from 'mdast'\n */\n\nimport assert from 'node:assert/strict'\nimport {test} from 'node:test'\nimport {compile} from '@mdx-js/mdx'\nimport {h} from 'hastscript'\nimport React from 'react'\nimport {renderToStaticMarkup} from 'react-dom/server'\nimport rehypeKatex from 'rehype-katex'\nimport remarkDirective from 'remark-directive'\nimport remarkFrontmatter from 'remark-frontmatter'\nimport remarkGfm from 'remark-gfm'\nimport remarkMath from 'remark-math'\nimport {visit} from 'unist-util-visit'\nimport {run, runWhole} from './context/run.js'\n\ntest('@mdx-js/mdx: syntax: markdown (CommonMark)', async function (t) {\n  await t.test(\n    'should support links (resource) (`[]()` -> `a`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('[a](b)')))\n        ),\n        '<p><a href=\"b\">a</a></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support links (reference) (`[][]` -> `a`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('[a]: b\\n[a]')))\n        ),\n        '<p><a href=\"b\">a</a></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should *not* support links (autolink) (`<http://a>` -> error)',\n    async function () {\n      try {\n        await compile('<http://a>')\n        assert.fail()\n      } catch (error) {\n        assert.match(\n          String(error),\n          /note: to create a link in MDX, use `\\[text]\\(url\\)/\n        )\n      }\n    }\n  )\n\n  await t.test(\n    'should support block quotes (`>` -> `blockquote`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('> a')))\n        ),\n        '<blockquote>\\n<p>a</p>\\n</blockquote>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support characters (escape) (`\\\\` -> ``)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('\\\\*a*')))\n        ),\n        '<p>*a*</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support character (reference) (`&lt;` -> `<`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('&lt;')))\n        ),\n        '<p>&lt;</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support code (fenced) (` ``` ` -> `pre code`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('```\\na')))\n        ),\n        '<pre><code>a\\n</code></pre>'\n      )\n    }\n  )\n\n  await t.test(\n    'should *not* support code (indented) (`\\\\ta` -> `p`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('    a')))\n        ),\n        '<p>a</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support code (text) (`` `a` `` -> `code`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('`a`')))\n        ),\n        '<p><code>a</code></p>'\n      )\n    }\n  )\n\n  await t.test('should support emphasis (`*` -> `em`)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('*a*')))\n      ),\n      '<p><em>a</em></p>'\n    )\n  })\n\n  await t.test(\n    'should support hard break (escape) (`\\\\\\\\\\\\n` -> `<br>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('a\\\\\\nb')))\n        ),\n        '<p>a<br/>\\nb</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support hard break (whitespace) (`\\\\\\\\\\\\n` -> `<br>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('a  \\nb')))\n        ),\n        '<p>a<br/>\\nb</p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support headings (atx) (`#` -> `<h1>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('#')))\n        ),\n        '<h1></h1>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support headings (setext) (`=` -> `<h1>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('a\\n=')))\n        ),\n        '<h1>a</h1>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support list (ordered) (`1.` -> `<ol><li>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('1.')))\n        ),\n        '<ol>\\n<li></li>\\n</ol>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support list (unordered) (`*` -> `<ul><li>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('*')))\n        ),\n        '<ul>\\n<li></li>\\n</ul>'\n      )\n    }\n  )\n\n  await t.test('should support strong (`**` -> `strong`)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('**a**')))\n      ),\n      '<p><strong>a</strong></p>'\n    )\n  })\n\n  await t.test(\n    'should support thematic break (`***` -> `<hr>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('***')))\n        ),\n        '<hr/>'\n      )\n    }\n  )\n})\n\ntest('@mdx-js/mdx: syntax: markdown (GFM, `remark-gfm`)', async function (t) {\n  await t.test(\n    'should support links (autolink literal) (`http://a` -> `a`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile('http://a', {remarkPlugins: [remarkGfm]}))\n          )\n        ),\n        '<p><a href=\"http://a\">http://a</a></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support footnotes (`[^a]` -> `<sup><a…>`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('[^a]\\n[^a]: b', {remarkPlugins: [remarkGfm]})\n            )\n          )\n        ),\n        `<p><sup><a href=\"#user-content-fn-a\" id=\"user-content-fnref-a\" data-footnote-ref=\"true\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"true\" class=\"footnotes\"><h2 class=\"sr-only\" id=\"footnote-label\">Footnotes</h2>\n<ol>\n<li id=\"user-content-fn-a\">\n<p>b <a href=\"#user-content-fnref-a\" data-footnote-backref=\"\" aria-label=\"Back to reference 1\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>`\n      )\n    }\n  )\n\n  await t.test(\n    'should support tables (`| a |` -> `<table>...`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('| a |\\n| - |', {remarkPlugins: [remarkGfm]})\n            )\n          )\n        ),\n        '<table><thead><tr><th>a</th></tr></thead></table>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support task lists (`* [x]` -> `input`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('* [x] a\\n* [ ] b', {remarkPlugins: [remarkGfm]})\n            )\n          )\n        ),\n        '<ul class=\"contains-task-list\">\\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\" checked=\"\"/> a</li>\\n<li class=\"task-list-item\"><input type=\"checkbox\" disabled=\"\"/> b</li>\\n</ul>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support strikethrough (`~` -> `del`)',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(await compile('~a~', {remarkPlugins: [remarkGfm]}))\n          )\n        ),\n        '<p><del>a</del></p>'\n      )\n    }\n  )\n})\n\ntest('@mdx-js/mdx: syntax: markdown (GFM footnotes, `remark-gfm`, `remark-rehype` options)', async function (t) {\n  await t.test('should support `remark-rehype` options', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('Text[^1]\\n\\n[^1]: Note.', {\n              remarkPlugins: [remarkGfm],\n              remarkRehypeOptions: {\n                footnoteLabel: 'Notes',\n                footnoteBackLabel: 'Back'\n              }\n            })\n          )\n        )\n      ),\n      `<p>Text<sup><a href=\"#user-content-fn-1\" id=\"user-content-fnref-1\" data-footnote-ref=\"true\" aria-describedby=\"footnote-label\">1</a></sup></p>\n<section data-footnotes=\"true\" class=\"footnotes\"><h2 class=\"sr-only\" id=\"footnote-label\">Notes</h2>\n<ol>\n<li id=\"user-content-fn-1\">\n<p>Note. <a href=\"#user-content-fnref-1\" data-footnote-backref=\"\" aria-label=\"Back\" class=\"data-footnote-backref\">↩</a></p>\n</li>\n</ol>\n</section>`,\n      'should pass options to remark-rehype'\n    )\n  })\n})\n\ntest('@mdx-js/mdx: syntax: markdown (frontmatter, `remark-frontmatter`)', async function (t) {\n  await t.test('should support frontmatter (YAML)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('---\\na: b\\n---\\nc', {\n              remarkPlugins: [remarkFrontmatter]\n            })\n          )\n        )\n      ),\n      '<p>c</p>'\n    )\n  })\n\n  await t.test('should support frontmatter (TOML)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('+++\\na: b\\n+++\\nc', {\n              remarkPlugins: [[remarkFrontmatter, 'toml']]\n            })\n          )\n        )\n      ),\n      '<p>c</p>'\n    )\n  })\n})\n\ntest('@mdx-js/mdx: syntax: markdown (math, `remark-math`, `rehype-katex`)', async function (t) {\n  await t.test('should support math', async function () {\n    assert.match(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('$C_L$', {\n              remarkPlugins: [remarkMath],\n              rehypePlugins: [rehypeKatex]\n            })\n          )\n        )\n      ),\n      /<math/,\n      'should support math (LaTeX)'\n    )\n  })\n})\n\ntest('@mdx-js/mdx: syntax: markdown (directive, `remark-directive`)', async function (t) {\n  await t.test('should support directives', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile(':span[*text*]{.red}', {\n              remarkPlugins: [remarkDirective, plugin]\n            })\n          )\n        )\n      ),\n      '<p><span class=\"red\"><em>text</em></span></p>'\n    )\n  })\n\n  function plugin() {\n    /**\n     * @param {MdastRoot} tree\n     *   Tree.\n     * @returns {undefined}\n     *   Nothing.\n     */\n    return function (tree) {\n      visit(tree, function (node) {\n        if (\n          node.type === 'containerDirective' ||\n          node.type === 'leafDirective' ||\n          node.type === 'textDirective'\n        ) {\n          const element = h(node.name, node.attributes || {})\n          node.data = {\n            hName: element.tagName,\n            hProperties: element.properties\n          }\n        }\n      })\n    }\n  }\n})\n\ntest('@mdx-js/mdx: syntax: MDX (JSX)', async function (t) {\n  await t.test('should support JSX (text)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('a <s>b</s>')))\n      ),\n      '<p>a <s>b</s></p>'\n    )\n  })\n\n  await t.test('should support JSX (flow)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('<div>\\n  b\\n</div>')))\n      ),\n      '<div><p>b</p></div>'\n    )\n  })\n\n  await t.test('should unravel JSX (text) as an only child', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('<h1>b</h1>')))\n      ),\n      '<h1>b</h1>'\n    )\n  })\n\n  await t.test('should unravel JSX (text) as only children', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('<a>b</a><b>c</b>')))\n      ),\n      '<a>b</a>\\n<b>c</b>'\n    )\n  })\n\n  await t.test(\n    'should unravel JSX (text) and whitespace as only children',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('<a>b</a>\\t<b>c</b>')))\n        ),\n        '<a>b</a>\\n<b>c</b>'\n      )\n    }\n  )\n\n  await t.test(\n    'should unravel expression (text) as an only child',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('{1}')))\n        ),\n        '1'\n      )\n    }\n  )\n\n  await t.test(\n    'should unravel expression (text) as only children',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('{1}{2}')))\n        ),\n        '1\\n2'\n      )\n    }\n  )\n\n  await t.test(\n    'should unravel expression (text) and whitespace as only children',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(await run(await compile('{1}\\n{2}')))\n        ),\n        '1\\n2'\n      )\n    }\n  )\n\n  await t.test('should support JSX (text, fragment)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('a <>b</>')))\n      ),\n      '<p>a b</p>'\n    )\n  })\n\n  await t.test('should support JSX (flow, fragment)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('<>\\n  b\\n</>')))\n      ),\n      '<p>b</p>'\n    )\n  })\n\n  await t.test('should support JSX (namespace)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('a <x:y>b</x:y>')))\n      ),\n      '<p>a <x:y>b</x:y></p>'\n    )\n  })\n\n  await t.test('should support expressions in MDX (text)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await compile('export const a = 1\\n\\na {a}'))\n        )\n      ),\n      '<p>a 1</p>'\n    )\n  })\n\n  await t.test('should support expressions in MDX (flow)', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('{\\n  1 + 1\\n}')))\n      ),\n      '2'\n    )\n  })\n\n  await t.test('should support empty expressions in MDX', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('{/*!*/}')))\n      ),\n      ''\n    )\n  })\n\n  await t.test('should support JSX attribute names', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await compile('<x a=\"1\" b:c=\"1\" hidden />'))\n        )\n      ),\n      '<x a=\"1\" b:c=\"1\" hidden=\"\"></x>'\n    )\n  })\n\n  await t.test('should support JSX attribute values', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(await compile('<x y=\"1\" z=\\'w\\' style={{color: \"red\"}} />'))\n        )\n      ),\n      '<x y=\"1\" z=\"w\" style=\"color:red\"></x>'\n    )\n  })\n\n  await t.test('should support JSX spread attributes', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(await run(await compile('<x {...{a: 1}} />')))\n      ),\n      '<x a=\"1\"></x>'\n    )\n  })\n\n  await t.test('should support JSX in expressions', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('{<i>the sum of one and one is: {1 + 1}</i>}')\n          )\n        )\n      ),\n      '<i>the sum of one and one is: 2</i>'\n    )\n  })\n\n  await t.test('should not include whitespace in tables', async function () {\n    // Important: there should not be whitespace in the `tr`.\n    // This is normally not present, but unraveling makes this a bit more complex.\n    // See: <https://github.com/mdx-js/mdx/issues/2000>.\n    assert.equal(\n      String(\n        await compile(`<table>\n  <thead>\n    <tr>\n      <th>a</th>\n      <th>b</th>\n    </tr>\n  </thead>\n</table>`)\n      ),\n      [\n        'import {jsx as _jsx, jsxs as _jsxs} from \"react/jsx-runtime\";',\n        'function _createMdxContent(props) {',\n        '  return _jsx(\"table\", {',\n        '    children: _jsx(\"thead\", {',\n        '      children: _jsxs(\"tr\", {',\n        '        children: [_jsx(\"th\", {',\n        '          children: \"a\"',\n        '        }), _jsx(\"th\", {',\n        '          children: \"b\"',\n        '        })]',\n        '      })',\n        '    })',\n        '  });',\n        '}',\n        'export default function MDXContent(props = {}) {',\n        '  const {wrapper: MDXLayout} = props.components || ({});',\n        '  return MDXLayout ? _jsx(MDXLayout, {',\n        '    ...props,',\n        '    children: _jsx(_createMdxContent, {',\n        '      ...props',\n        '    })',\n        '  }) : _createMdxContent(props);',\n        '}',\n        ''\n      ].join('\\n')\n    )\n  })\n})\n\ntest('@mdx-js/mdx: syntax: MDX (ESM)', async function (t) {\n  await t.test('should support importing components w/ ESM', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile(\n              'import {Pill} from \"./components.js\"\\n\\n<Pill>!</Pill>'\n            )\n          )\n        )\n      ),\n      '<span style=\"color:red\">!</span>'\n    )\n  })\n\n  await t.test('should support importing data w/ ESM', async function () {\n    assert.equal(\n      renderToStaticMarkup(\n        React.createElement(\n          await run(\n            await compile('import {number} from \"./data.js\"\\n\\n{number}')\n          )\n        )\n      ),\n      '3.14'\n    )\n  })\n\n  await t.test('should support exporting w/ ESM', async function () {\n    const result = await runWhole(\n      await compile('export const number = Math.PI')\n    )\n\n    assert.equal(result.number, Math.PI)\n  })\n\n  await t.test(\n    'should support exporting an identifier w/o a value',\n    async function () {\n      assert.ok('a' in (await runWhole(await compile('export var a'))))\n    }\n  )\n\n  await t.test('should support exporting an object pattern', async function () {\n    const result = await runWhole(\n      await compile('import {object} from \"./data.js\"\\nexport var {a} = object')\n    )\n\n    assert.equal(result.a, 1)\n  })\n\n  await t.test(\n    'should support exporting a rest element in an object pattern',\n    async function () {\n      const result = await runWhole(\n        await compile(\n          'import {object} from \"./data.js\"\\nexport var {a, ...rest} = object'\n        )\n      )\n\n      assert.deepEqual(result.rest, {b: 2})\n    }\n  )\n\n  await t.test(\n    'should support exporting an assignment pattern in an object pattern',\n    async function () {\n      const result = await runWhole(\n        await compile(\n          'import {object} from \"./data.js\"\\nexport var {c = 3} = object'\n        )\n      )\n\n      assert.equal(result.c, 3)\n    }\n  )\n\n  await t.test('should support exporting an array pattern', async function () {\n    const result = await runWhole(\n      await compile('import {array} from \"./data.js\"\\nexport var [a] = array')\n    )\n\n    assert.equal(result.a, 1)\n  })\n\n  await t.test('should support `export as` w/ ESM', async function () {\n    const result = await runWhole(\n      await compile('export const number = Math.PI\\nexport {number as pi}')\n    )\n\n    assert.equal(result.pi, Math.PI)\n  })\n\n  await t.test(\n    'should support default export to define a layout',\n    async function () {\n      const Content = await run(\n        await compile(\n          'export default function Layout(props) { return <div {...props} /> }\\n\\na'\n        )\n      )\n\n      assert.equal(\n        renderToStaticMarkup(React.createElement(Content)),\n        '<div><p>a</p></div>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support default export from a source',\n    async function () {\n      const Content = await run(\n        await compile('export {Layout as default} from \"./components.js\"\\n\\na')\n      )\n\n      assert.equal(\n        renderToStaticMarkup(React.createElement(Content)),\n        '<div style=\"color:red\"><p>a</p></div>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support rexporting something as a default export from a source',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('export {default} from \"./components.js\"\\n\\na')\n            )\n          )\n        ),\n        '<div style=\"color:red\"><p>a</p></div>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support rexporting the default export from a source',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('export {default} from \"./components.js\"\\n\\na')\n            )\n          )\n        ),\n        '<div style=\"color:red\"><p>a</p></div>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support rexporting the default export from a source',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile('export {default} from \"./components.js\"\\n\\na')\n            )\n          )\n        ),\n        '<div style=\"color:red\"><p>a</p></div>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support rexporting the default export, and other things, from a source',\n    async function () {\n      assert.equal(\n        renderToStaticMarkup(\n          React.createElement(\n            await run(\n              await compile(\n                'export {default, Pill} from \"./components.js\"\\n\\na'\n              )\n            )\n          )\n        ),\n        '<div style=\"color:red\"><p>a</p></div>'\n      )\n    }\n  )\n\n  await t.test('should support the jsx dev runtime', async function () {\n    assert.equal(\n      String(\n        await compile(\n          {value: '<X />', path: 'path/to/file.js'},\n          {development: true}\n        )\n      ),\n      [\n        'import {jsxDEV as _jsxDEV} from \"react/jsx-dev-runtime\";',\n        'function _createMdxContent(props) {',\n        '  const {X} = props.components || ({});',\n        '  if (!X) _missingMdxReference(\"X\", true, \"1:1-1:6\");',\n        '  return _jsxDEV(X, {}, undefined, false, {',\n        '    fileName: \"path/to/file.js\",',\n        '    lineNumber: 1,',\n        '    columnNumber: 1',\n        '  }, this);',\n        '}',\n        'export default function MDXContent(props = {}) {',\n        '  const {wrapper: MDXLayout} = props.components || ({});',\n        '  return MDXLayout ? _jsxDEV(MDXLayout, {',\n        '    ...props,',\n        '    children: _jsxDEV(_createMdxContent, {',\n        '      ...props',\n        '    }, undefined, false, {',\n        '      fileName: \"path/to/file.js\"',\n        '    }, this)',\n        '  }, undefined, false, {',\n        '    fileName: \"path/to/file.js\"',\n        '  }, this) : _createMdxContent(props);',\n        '}',\n        'function _missingMdxReference(id, component, place) {',\n        '  throw new Error(\"Expected \" + (component ? \"component\" : \"object\") + \" `\" + id + \"` to be defined: you likely forgot to import, pass, or provide it.\" + (place ? \"\\\\nIt’s referenced in your code at `\" + place + \"` in `path/to/file.js`\" : \"\"));',\n        '}',\n        ''\n      ].join('\\n')\n    )\n  })\n\n  await t.test(\n    \"should add a 'use strict' when generating a `function-body`\",\n    async function () {\n      assert.equal(\n        String(await compile('# hi', {outputFormat: 'function-body'})),\n        [\n          '\"use strict\";',\n          'const {jsx: _jsx} = arguments[0];',\n          'function _createMdxContent(props) {',\n          '  const _components = {',\n          '    h1: \"h1\",',\n          '    ...props.components',\n          '  };',\n          '  return _jsx(_components.h1, {',\n          '    children: \"hi\"',\n          '  });',\n          '}',\n          'function MDXContent(props = {}) {',\n          '  const {wrapper: MDXLayout} = props.components || ({});',\n          '  return MDXLayout ? _jsx(MDXLayout, {',\n          '    ...props,',\n          '    children: _jsx(_createMdxContent, {',\n          '      ...props',\n          '    })',\n          '  }) : _createMdxContent(props);',\n          '}',\n          'return {',\n          '  default: MDXContent',\n          '};',\n          ''\n        ].join('\\n')\n      )\n    }\n  )\n})\n"
  },
  {
    "path": "packages/mdx/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/node-loader/index.js",
    "content": "/**\n * @typedef {import('./lib/index.js').Options} Options\n */\n\nimport {createLoader} from './lib/index.js'\n\nconst defaultLoader = createLoader()\n\nexport {createLoader} from './lib/index.js'\n\n/**\n * Pass options to the loader.\n */\nexport const initialize = defaultLoader.initialize\n\n/**\n * Load `file:` URLs to MD(X) files.\n */\nexport const load = defaultLoader.load\n"
  },
  {
    "path": "packages/node-loader/lib/condition.default.js",
    "content": "export const development = false\n"
  },
  {
    "path": "packages/node-loader/lib/condition.development.js",
    "content": "export const development = true\n"
  },
  {
    "path": "packages/node-loader/lib/index.js",
    "content": "/**\n * @import {LoadFnOutput, LoadHook, LoadHookContext} from 'node:module'\n * @import {Process} from '@mdx-js/mdx/internal-create-format-aware-processors'\n * @import {CompileOptions} from '@mdx-js/mdx'\n */\n\n/**\n * @typedef {Parameters<LoadHook>[2]} NextLoad\n *   Next.\n *\n * @typedef {Omit<CompileOptions, 'development'>} Options\n *   Configuration.\n *\n *   Options are the same as `compile` from `@mdx-js/mdx` with the\n *   exception that the `development` option is supported based on\n *   whether you run Node with `--conditions development`.\n *   You cannot pass it manually.\n *\n * @typedef {[regex: RegExp, process: Process]} Settings\n */\n\nimport {Buffer} from 'node:buffer'\nimport fs from 'node:fs/promises'\nimport {createFormatAwareProcessors} from '@mdx-js/mdx/internal-create-format-aware-processors'\nimport {extnamesToRegex} from '@mdx-js/mdx/internal-extnames-to-regex'\nimport {SourceMapGenerator} from 'source-map'\nimport {reporter} from 'vfile-reporter'\nimport {VFile} from 'vfile'\nimport {development as defaultDevelopment} from '#condition'\n\n/**\n * Create Node.js hooks to handle markdown and MDX.\n *\n * @param {Readonly<Options> | null | undefined} [loaderOptions]\n *   Configuration (optional).\n * @returns\n *   Node.js hooks.\n */\nexport function createLoader(loaderOptions) {\n  /** @type {Settings} */\n  let settings = configure(loaderOptions || {})\n\n  return {initialize, load}\n\n  /**\n   *\n   * @param {Readonly<Options> | null | undefined} options\n   */\n  async function initialize(options) {\n    settings = configure({...loaderOptions, ...options})\n  }\n\n  /**\n   * Load `file:` URLs to MD(X) files.\n   *\n   * @param {string} href\n   *   URL.\n   * @param {LoadHookContext} context\n   *   Context.\n   * @param {NextLoad} nextLoad\n   *   Next or default `load` function.\n   * @returns {Promise<LoadFnOutput>}\n   *   Result.\n   * @satisfies {LoadHook}\n   */\n  async function load(href, context, nextLoad) {\n    const url = new URL(href)\n    const [regex, process] = settings\n\n    if (url.protocol === 'file:' && regex.test(url.pathname)) {\n      const value = await fs.readFile(url)\n      const file = await process(new VFile({value, path: url}))\n\n      /* c8 ignore next 3 -- hard to test. */\n      if (file.messages.length > 0) {\n        console.error(reporter(file))\n      }\n\n      return {\n        format: 'module',\n        shortCircuit: true,\n        source:\n          String(file) +\n          '\\n//# sourceMappingURL=data:application/json;base64,' +\n          Buffer.from(JSON.stringify(file.map)).toString('base64') +\n          '\\n'\n      }\n    }\n\n    return nextLoad(href, context)\n  }\n}\n\n/**\n * @param {Readonly<Options>} options\n * @returns {Settings}\n */\nfunction configure(options) {\n  const {extnames, process} = createFormatAwareProcessors({\n    development: defaultDevelopment,\n    ...options,\n    SourceMapGenerator\n  })\n  const regex = extnamesToRegex(extnames)\n\n  return [regex, process]\n}\n"
  },
  {
    "path": "packages/node-loader/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2021 Titus Wormer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/node-loader/package.json",
    "content": "{\n  \"name\": \"@mdx-js/node-loader\",\n  \"version\": \"3.1.1\",\n  \"description\": \"Node.js loader for MDX\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"jsx\",\n    \"loader\",\n    \"markdown\",\n    \"mdx\",\n    \"node\",\n    \"react\",\n    \"remark\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/node-loader/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n  \"contributors\": [\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.js\",\n  \"imports\": {\n    \"#condition\": {\n      \"development\": \"./lib/condition.development.js\",\n      \"default\": \"./lib/condition.default.js\"\n    }\n  },\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"@mdx-js/mdx\": \"^3.0.0\",\n    \"source-map\": \"^0.7.0\",\n    \"vfile-reporter\": \"^8.0.0\",\n    \"vfile\": \"^6.0.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development --enable-source-maps --loader=@mdx-js/node-loader test/index.js\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"prettier\": true,\n    \"rules\": {\n      \"n/file-extension-in-import\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/node-loader/readme.md",
    "content": "# `@mdx-js/node-loader`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nNode.js hooks (also knows as loaders) for MDX.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`createLoader(options?)`](#createloaderoptions)\n  * [`load`](#load)\n  * [`Options`](#options)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package contains Node.js hooks to add support for importing MDX files.\nNode *Customization Hooks* are currently a release candidate.\n\n## When should I use this?\n\nThis integration is useful if you’re using Node and want to import MDX files\nfrom the file system.\n\nIf you’re using a bundler (webpack, Rollup, esbuild), or a site builder\n(Next.js) or build system (Vite) which comes with a bundler, you can instead\nanother integration: see [§ Integrations][integrations].\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/node-loader\n```\n\n## Use\n\nSay we have an MDX document, `example.mdx`:\n\n```mdx\nexport function Thing() {\n  return <>World!</>\n}\n\n# Hello, <Thing />\n```\n\n…and our module `example.js` looks as follows:\n\n```tsx\nimport {renderToStaticMarkup} from 'react-dom/server'\nimport React from 'react'\nimport Content from './example.mdx'\n\nconsole.log(renderToStaticMarkup(React.createElement(Content)))\n```\n\n…then running with:\n\n```sh\nnode --loader=@mdx-js/node-loader example.js\n```\n\n…yields:\n\n```html\n<h1>Hello, World!</h1>\n```\n\n> **Note**: if you use Node 18 and lower, then you can ignore the following\n> warning:\n>\n> ```text\n> (node:20718) ExperimentalWarning: Custom ESM Loaders is an experimental feature and might change at any > time\n> (Use `node --trace-warnings ...` to show where the warning was created)\n> ```\n\n> **Note**: if you use Node 20 and higher, then you get the following warning:\n>\n> ```text\n> (node:20908) ExperimentalWarning: `--experimental-loader` may be removed in the future; instead use > `register()`:\n> --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from > \"node:url\"; register(\"%40mdx-js/node-loader\", pathToFileURL(\"./\"));'\n> ```\n>\n> You can solve that by adding a `register.js` file:\n>\n> ```tsx\n> import {register} from 'node:module'\n>\n> register('@mdx-js/node-loader', import.meta.url)\n> ```\n>\n> …and running `node --import ./register.js example.js` instead.\n\n## API\n\nThis package export the identifiers [`createLoader`][api-create-loader] and\n[`load`][api-load].\nThere is no default export.\n\n### `createLoader(options?)`\n\nCreate Node.js hooks to handle markdown and MDX.\n\n###### Parameters\n\n* `options` ([`Options`][api-options], optional)\n  — configuration\n\n###### Returns\n\nNode.js hooks ([`{load}`][api-load]).\n\n### `load`\n\nLoad `file:` URLs to MD(X) files.\n\nSee [`load` in Node.js docs][node-load] for more info.\n\n### `Options`\n\nConfiguration (TypeScript type).\n\nOptions are the same as [`CompileOptions` from `@mdx-js/mdx`][compile-options]\nexception that the `development` option is supported based on whether you\nrun Node with `--conditions development`.\nYou cannot pass it manually.\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional type [`Options`][api-options].\nSee [§ Types][types] on our website for information.\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/node-loader@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © [Titus Wormer][author]\n\n[api-create-loader]: #createloaderoptions\n\n[api-load]: #load\n\n[api-options]: #options\n\n[author]: https://wooorm.com\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[compile-options]: https://mdxjs.com/packages/mdx/#compileoptions\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/node-loader\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/node-loader.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[integrations]: https://mdxjs.com/getting-started/#integrations\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/node-loader/license\n\n[node-load]: https://nodejs.org/api/module.html#loadurl-context-nextload\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[support]: https://mdxjs.com/community/support/\n\n[types]: https://mdxjs.com/getting-started/#types\n\n[typescript]: https://www.typescriptlang.org\n"
  },
  {
    "path": "packages/node-loader/test/index.js",
    "content": "/**\n * @import {MDXModule} from 'mdx/types.js'\n */\n\nimport assert from 'node:assert/strict'\nimport fs from 'node:fs/promises'\nimport {test} from 'node:test'\nimport React from 'react'\nimport {renderToStaticMarkup} from 'react-dom/server'\n\ntest('@mdx-js/node-loader', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('@mdx-js/node-loader')).sort(), [\n      'createLoader',\n      'initialize',\n      'load'\n    ])\n  })\n\n  await t.test('should work', async function () {\n    const mdxUrl = new URL('node-loader.mdx', import.meta.url)\n\n    await fs.writeFile(\n      mdxUrl,\n      'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n    )\n\n    /** @type {MDXModule} */\n    let result\n\n    try {\n      result = await import(mdxUrl.href)\n    } catch (error) {\n      const exception = /** @type {NodeJS.ErrnoException} */ (error)\n\n      if (exception.code === 'ERR_UNKNOWN_FILE_EXTENSION') {\n        await fs.rm(mdxUrl)\n\n        throw new Error(\n          'Please run Node with `--loader=@mdx-js/node-loader` to test the ESM loader'\n        )\n      }\n\n      throw error\n    }\n\n    const Content = result.default\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(Content)),\n      '<h1>Hello, World!</h1>'\n    )\n\n    await fs.rm(mdxUrl)\n  })\n\n  await t.test('supports source maps work', async function () {\n    const mdxUrl = new URL('crash.mdx', import.meta.url)\n\n    await fs.writeFile(\n      mdxUrl,\n      '<Throw />\\nexport function Throw() { throw new Error(\"Boom\") }\\n'\n    )\n\n    /** @type {MDXModule} */\n    let result\n\n    try {\n      result = await import(mdxUrl.href)\n    } catch (error) {\n      const exception = /** @type {NodeJS.ErrnoException} */ (error)\n\n      if (exception.code === 'ERR_UNKNOWN_FILE_EXTENSION') {\n        await fs.rm(mdxUrl)\n\n        throw new Error(\n          'Please run Node with `--loader=@mdx-js/node-loader` to test the ESM loader'\n        )\n      }\n\n      throw error\n    }\n\n    const Content = result.default\n\n    assert.throws(\n      () => renderToStaticMarkup(React.createElement(Content)),\n      (error) => {\n        assert.ok(error instanceof Error)\n        assert.equal(error.message, 'Boom')\n        // Source maps are off.\n        // The column should be 26, not 8.\n        assert.ok(error.stack?.includes('crash.mdx:2:8)'))\n        return true\n      }\n    )\n\n    await fs.rm(mdxUrl)\n  })\n})\n"
  },
  {
    "path": "packages/node-loader/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/preact/index.js",
    "content": "export {MDXProvider, useMDXComponents} from './lib/index.js'\n"
  },
  {
    "path": "packages/preact/lib/index.js",
    "content": "/**\n * @import {MDXComponents} from 'mdx/types.js'\n * @import {Component, ComponentChildren, VNode} from 'preact'\n */\n\n/**\n * @callback MergeComponents\n *   Custom merge function.\n * @param {Readonly<MDXComponents>} currentComponents\n *   Current components from the context.\n * @returns {MDXComponents}\n *   Additional components.\n *\n * @typedef Props\n *   Configuration for `MDXProvider`.\n * @property {ComponentChildren} [children]\n *   Children (optional).\n * @property {Readonly<MDXComponents> | MergeComponents | null | undefined} [components]\n *   Additional components to use or a function that creates them (optional).\n * @property {boolean | null | undefined} [disableParentContext=false]\n *   Turn off outer component context (default: `false`).\n */\n\nimport {createContext, h} from 'preact'\nimport {useContext} from 'preact/hooks'\n\n/** @type {Readonly<MDXComponents>} */\nconst emptyComponents = {}\n\nconst MDXContext = createContext(emptyComponents)\n\n/**\n * Get current components from the MDX Context.\n *\n * @param {Readonly<MDXComponents> | MergeComponents | null | undefined} [components]\n *   Additional components to use or a function that creates them (optional).\n * @returns {MDXComponents}\n *   Current components.\n */\nexport function useMDXComponents(components) {\n  const contextComponents = useContext(MDXContext)\n\n  // Custom merge via a function prop\n  if (typeof components === 'function') {\n    return components(contextComponents)\n  }\n\n  return {...contextComponents, ...components}\n}\n\n/**\n * Provider for MDX context.\n *\n * @param {Readonly<Props>} properties\n *   Properties.\n * @returns {VNode}\n *   Element.\n * @satisfies {Component}\n */\nexport function MDXProvider(properties) {\n  /** @type {Readonly<MDXComponents>} */\n  let allComponents\n\n  if (properties.disableParentContext) {\n    allComponents =\n      typeof properties.components === 'function'\n        ? properties.components(emptyComponents)\n        : properties.components || emptyComponents\n  } else {\n    allComponents = useMDXComponents(properties.components)\n  }\n\n  return h(\n    MDXContext.Provider,\n    {children: undefined, value: allComponents},\n    properties.children\n  )\n}\n"
  },
  {
    "path": "packages/preact/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Compositor and Vercel, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/preact/package.json",
    "content": "{\n  \"name\": \"@mdx-js/preact\",\n  \"version\": \"3.1.1\",\n  \"description\": \"Preact context for MDX\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"jsx\",\n    \"markdown\",\n    \"mdx\",\n    \"preact\",\n    \"remark\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/preact/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n  \"contributors\": [\n    \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n    \"Tim Neutkens <tim@vercel.com>\",\n    \"Matija Marohnić <matija.marohnic@gmail.com>\",\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\",\n    \"JounQin <admin@1stg.me> (https://www.1stg.me)\",\n    \"Chris Biscardi <chris@christopherbiscardi.com> (https://www.christopherbiscardi.com)\",\n    \"Christian Murphy <christian.murphy.42@gmail.com>\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.js\",\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"@types/mdx\": \"^2.0.0\"\n  },\n  \"peerDependencies\": {\n    \"preact\": \">=10.0.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development --loader=../../script/jsx-loader.js test/index.jsx\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"overrides\": [\n      {\n        \"extends\": \"xo-react\",\n        \"files\": [\n          \"**/*.jsx\"\n        ],\n        \"rules\": {\n          \"react/jsx-no-bind\": \"off\",\n          \"react/react-in-jsx-scope\": \"off\"\n        }\n      }\n    ],\n    \"prettier\": true,\n    \"rules\": {\n      \"n/file-extension-in-import\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/preact/readme.md",
    "content": "# `@mdx-js/preact`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Size][size-badge]][size]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nPreact context for MDX.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`MDXProvider(properties?)`](#mdxproviderproperties)\n  * [`useMDXComponents(components?)`](#usemdxcomponentscomponents)\n  * [`MergeComponents`](#mergecomponents)\n  * [`Props`](#props)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a *context* based components provider for combining Preact with\nMDX.\n\n## When should I use this?\n\nThis package is **not needed** for MDX to work with Preact.\nSee [¶ MDX provider in § Using MDX][use-provider] for when and how to use an MDX\nprovider.\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/preact\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```tsx\nimport {MDXProvider} from 'https://esm.sh/@mdx-js/preact@3'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n<script type=\"module\">\n  import {MDXProvider} from 'https://esm.sh/@mdx-js/preact@3?bundle'\n</script>\n```\n\n## Use\n\n```tsx\n/**\n * @import {MDXComponents} from 'mdx/types.js'\n */\n\nimport {MDXProvider} from '@mdx-js/preact'\nimport Post from './post.mdx'\n// ^-- Assumes an integration is used to compile MDX to JS, such as\n// `@mdx-js/esbuild`, `@mdx-js/loader`, `@mdx-js/node-loader`, or\n// `@mdx-js/rollup`, and that it is configured with\n// `options.providerImportSource: '@mdx-js/preact'`.\n\n/** @type {MDXComponents} */\nconst components = {\n  em(properties) {\n    return <i {...properties} />\n  }\n}\n\nconsole.log(\n  <MDXProvider components={components}>\n    <Post />\n  </MDXProvider>\n)\n```\n\n> 👉 **Note**: you don’t have to use `MDXProvider` and can pass components\n> directly:\n>\n> ```diff\n> -<MDXProvider components={components}>\n> -  <Post />\n> -</MDXProvider>\n> +<Post components={components} />\n> ```\n\nSee [¶ Preact in § Getting started][start-preact] for how to get started with\nMDX and Preact.\nSee [¶ MDX provider in § Using MDX][use-provider] for how to use an MDX\nprovider.\n\n## API\n\nThis package exports the identifiers [`MDXProvider`][api-mdx-provider] and\n[`useMDXComponents`][api-use-mdx-components].\nThere is no default export.\n\n### `MDXProvider(properties?)`\n\nProvider for MDX context.\n\n###### Parameters\n\n* `properties` ([`Props`][api-props])\n  — configuration\n\n##### Returns\n\nElement (`VNode`).\n\n### `useMDXComponents(components?)`\n\nGet current components from the MDX Context.\n\n###### Parameters\n\n* `components` ([`MDXComponents` from `mdx/types.js`][mdx-types-components]\n  or [`MergeComponents`][api-merge-components], optional)\n  — additional components to use or a function that creates them\n\n###### Returns\n\nCurrent components ([`MDXComponents` from\n`mdx/types.js`][mdx-types-components]).\n\n### `MergeComponents`\n\nCustom merge function (TypeScript type).\n\n###### Parameters\n\n* `components` ([`MDXComponents` from `mdx/types.js`][mdx-types-components])\n  — current components from the context\n\n###### Returns\n\nAdditional components ([`MDXComponents` from\n`mdx/types.js`][mdx-types-components]).\n\n### `Props`\n\nConfiguration for `MDXProvider` (TypeScript type).\n\n###### Fields\n\n* `children` ([`ComponentChildren` from `preact`][preact-component-children],\n  optional)\n  — children\n* `components` ([`MDXComponents` from `mdx/types.js`][mdx-types-components]\n  or [`MergeComponents`][api-merge-components], optional)\n  — additional components to use or a function that creates them\n* `disableParentContext` (`boolean`, default: `false`)\n  — turn off outer component context\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional types [`MergeComponents`][api-merge-components] and\n[`Props`][api-props].\n\nFor types to work, make sure the TypeScript `JSX` namespace is typed.\nThis is done by installing and using the types of your framework, as in\n[`preact`](https://github.com/preactjs/preact).\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/preact@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © Compositor and [Vercel][]\n\n[api-mdx-provider]: #mdxproviderproperties\n\n[api-merge-components]: #mergecomponents\n\n[api-props]: #props\n\n[api-use-mdx-components]: #usemdxcomponentscomponents\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/preact\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/preact.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[esmsh]: https://esm.sh\n\n[mdx-types-components]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/mdx/types.d.ts#L65\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/preact/license\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[preact-component-children]: https://github.com/preactjs/preact/blob/main/src/index.d.ts#L53\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[size]: https://bundlejs.com/?q=@mdx-js/preact\n\n[size-badge]: https://img.shields.io/bundlejs/size/@mdx-js/preact\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[start-preact]: https://mdxjs.com/getting-started/#preact\n\n[support]: https://mdxjs.com/community/support/\n\n[typescript]: https://www.typescriptlang.org\n\n[use-provider]: https://mdxjs.com/docs/using-mdx/#mdx-provider\n\n[vercel]: https://vercel.com\n"
  },
  {
    "path": "packages/preact/test/index.jsx",
    "content": "/* @jsxRuntime automatic */\n/* @jsxImportSource preact */\n\n/**\n * @import {ComponentProps} from 'preact'\n */\n\nimport assert from 'node:assert/strict'\nimport {test} from 'node:test'\nimport {evaluate} from '@mdx-js/mdx'\nimport {MDXProvider, useMDXComponents} from '@mdx-js/preact'\nimport * as runtime from 'preact/jsx-runtime'\nimport {render} from 'preact-render-to-string'\n\ntest('@mdx-js/preact', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('@mdx-js/preact')).sort(), [\n      'MDXProvider',\n      'useMDXComponents'\n    ])\n  })\n\n  await t.test(\n    'should support `components` with `MDXProvider`',\n    async function () {\n      const {default: Content} = await evaluate('# hi', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        render(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              }\n            }}\n          >\n            <Content />\n          </MDXProvider>\n        ),\n        '<h1 style=\"color:tomato;\">hi</h1>'\n      )\n    }\n  )\n\n  await t.test('should support `wrapper` in `components`', async function () {\n    const {default: Content} = await evaluate('# hi', {\n      ...runtime,\n      useMDXComponents\n    })\n\n    assert.equal(\n      render(\n        <MDXProvider\n          components={{\n            /**\n             * @param {ComponentProps<'div'>} properties\n             *   Properties.\n             * @returns\n             *   Element.\n             */\n            wrapper(properties) {\n              return <div id=\"layout\" {...properties} />\n            }\n          }}\n        >\n          <Content />\n        </MDXProvider>\n      ),\n      '<div id=\"layout\"><h1>hi</h1></div>'\n    )\n  })\n\n  await t.test(\n    'should combine components in nested `MDXProvider`s',\n    async function () {\n      const {default: Content} = await evaluate('# hi\\n## hello', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        render(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              },\n              h2(properties) {\n                return <h2 style={{color: 'rebeccapurple'}} {...properties} />\n              }\n            }}\n          >\n            <MDXProvider\n              components={{\n                h2(properties) {\n                  return <h2 style={{color: 'papayawhip'}} {...properties} />\n                }\n              }}\n            >\n              <Content />\n            </MDXProvider>\n          </MDXProvider>\n        ),\n        '<h1 style=\"color:tomato;\">hi</h1>\\n<h2 style=\"color:papayawhip;\">hello</h2>'\n      )\n    }\n  )\n\n  await t.test('should support components as a function', async function () {\n    const {default: Content} = await evaluate('# hi\\n## hello', {\n      ...runtime,\n      useMDXComponents\n    })\n\n    assert.equal(\n      render(\n        <MDXProvider\n          components={{\n            h1(properties) {\n              return <h1 style={{color: 'tomato'}} {...properties} />\n            },\n            h2(properties) {\n              return <h2 style={{color: 'rebeccapurple'}} {...properties} />\n            }\n          }}\n        >\n          <MDXProvider\n            components={function () {\n              return {\n                h2(properties) {\n                  return <h2 style={{color: 'papayawhip'}} {...properties} />\n                }\n              }\n            }}\n          >\n            <Content />\n          </MDXProvider>\n        </MDXProvider>\n      ),\n      '<h1>hi</h1>\\n<h2 style=\"color:papayawhip;\">hello</h2>'\n    )\n  })\n\n  await t.test(\n    'should support a `disableParentContext` prop (sandbox)',\n    async function () {\n      const {default: Content} = await evaluate('# hi', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        render(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              }\n            }}\n          >\n            <MDXProvider disableParentContext>\n              <Content />\n            </MDXProvider>\n          </MDXProvider>\n        ),\n        '<h1>hi</h1>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support a `disableParentContext` *and* `components` as a function',\n    async function () {\n      const {default: Content} = await evaluate('# hi\\n## hello', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        render(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              }\n            }}\n          >\n            <MDXProvider\n              disableParentContext\n              components={function () {\n                return {\n                  h2(properties) {\n                    return <h2 style={{color: 'papayawhip'}} {...properties} />\n                  }\n                }\n              }}\n            >\n              <Content />\n            </MDXProvider>\n          </MDXProvider>\n        ),\n        '<h1>hi</h1>\\n<h2 style=\"color:papayawhip;\">hello</h2>'\n      )\n    }\n  )\n})\n"
  },
  {
    "path": "packages/preact/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/react/index.js",
    "content": "export {MDXProvider, useMDXComponents} from './lib/index.js'\n"
  },
  {
    "path": "packages/react/lib/index.js",
    "content": "/**\n * @import {MDXComponents} from 'mdx/types.js'\n * @import {Component, ReactElement, ReactNode} from 'react'\n */\n\n/**\n * @callback MergeComponents\n *   Custom merge function.\n * @param {Readonly<MDXComponents>} currentComponents\n *   Current components from the context.\n * @returns {MDXComponents}\n *   Additional components.\n *\n * @typedef Props\n *   Configuration for `MDXProvider`.\n * @property {ReactNode | null | undefined} [children]\n *   Children (optional).\n * @property {Readonly<MDXComponents> | MergeComponents | null | undefined} [components]\n *   Additional components to use or a function that creates them (optional).\n * @property {boolean | null | undefined} [disableParentContext=false]\n *   Turn off outer component context (default: `false`).\n */\n\nimport React from 'react'\n\n/** @type {Readonly<MDXComponents>} */\nconst emptyComponents = {}\n\nconst MDXContext = React.createContext(emptyComponents)\n\n/**\n * Get current components from the MDX Context.\n *\n * @param {Readonly<MDXComponents> | MergeComponents | null | undefined} [components]\n *   Additional components to use or a function that creates them (optional).\n * @returns {MDXComponents}\n *   Current components.\n */\nexport function useMDXComponents(components) {\n  const contextComponents = React.useContext(MDXContext)\n\n  // Memoize to avoid unnecessary top-level context changes\n  return React.useMemo(\n    function () {\n      // Custom merge via a function prop\n      if (typeof components === 'function') {\n        return components(contextComponents)\n      }\n\n      return {...contextComponents, ...components}\n    },\n    [contextComponents, components]\n  )\n}\n\n/**\n * Provider for MDX context.\n *\n * @param {Readonly<Props>} properties\n *   Properties.\n * @returns {ReactElement}\n *   Element.\n * @satisfies {Component}\n */\nexport function MDXProvider(properties) {\n  /** @type {Readonly<MDXComponents>} */\n  let allComponents\n\n  if (properties.disableParentContext) {\n    allComponents =\n      typeof properties.components === 'function'\n        ? properties.components(emptyComponents)\n        : properties.components || emptyComponents\n  } else {\n    allComponents = useMDXComponents(properties.components)\n  }\n\n  return React.createElement(\n    MDXContext.Provider,\n    {value: allComponents},\n    properties.children\n  )\n}\n"
  },
  {
    "path": "packages/react/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Compositor and Vercel, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/react/package.json",
    "content": "{\n  \"name\": \"@mdx-js/react\",\n  \"version\": \"3.1.1\",\n  \"description\": \"React context for MDX\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"jsx\",\n    \"markdown\",\n    \"mdx\",\n    \"react\",\n    \"remark\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/react/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n  \"contributors\": [\n    \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n    \"Tim Neutkens <tim@vercel.com>\",\n    \"Matija Marohnić <matija.marohnic@gmail.com>\",\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\",\n    \"JounQin <admin@1stg.me> (https://www.1stg.me)\",\n    \"Christian Murphy <christian.murphy.42@gmail.com>\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.js\",\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"@types/mdx\": \"^2.0.0\"\n  },\n  \"peerDependencies\": {\n    \"@types/react\": \">=16\",\n    \"react\": \">=16\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development --loader=../../script/jsx-loader.js test/index.jsx\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"overrides\": [\n      {\n        \"extends\": \"xo-react\",\n        \"files\": [\n          \"**/*.jsx\"\n        ],\n        \"rules\": {\n          \"react/jsx-no-bind\": \"off\",\n          \"react/react-in-jsx-scope\": \"off\"\n        }\n      }\n    ],\n    \"prettier\": true,\n    \"rules\": {\n      \"n/file-extension-in-import\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/react/readme.md",
    "content": "# `@mdx-js/react`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Size][size-badge]][size]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nReact context for MDX.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`MDXProvider(properties?)`](#mdxproviderproperties)\n  * [`useMDXComponents(components?)`](#usemdxcomponentscomponents)\n  * [`MergeComponents`](#mergecomponents)\n  * [`Props`](#props)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a *context* based components provider for combining React with\nMDX.\n\n## When should I use this?\n\nThis package is **not needed** for MDX to work with React.\nSee [¶ MDX provider in § Using MDX][use-provider] for when and how to use an MDX\nprovider.\n\nIf you use Next.js, **do not use this**.\nAdd an `mdx-components.tsx` (in `src/` or `/`) file instead.\nSee [Configuring MDX on `nextjs.org`][next-configuring-mdx] for more info.\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/react\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```tsx\nimport {MDXProvider} from 'https://esm.sh/@mdx-js/react@3'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n<script type=\"module\">\n  import {MDXProvider} from 'https://esm.sh/@mdx-js/react@3?bundle'\n</script>\n```\n\n## Use\n\n```tsx\n/**\n * @import {MDXComponents} from 'mdx/types.js'\n */\n\nimport {MDXProvider} from '@mdx-js/react'\nimport Post from './post.mdx'\n// ^-- Assumes an integration is used to compile MDX to JS, such as\n// `@mdx-js/esbuild`, `@mdx-js/loader`, `@mdx-js/node-loader`, or\n// `@mdx-js/rollup`, and that it is configured with\n// `options.providerImportSource: '@mdx-js/react'`.\n\n/** @type {MDXComponents} */\nconst components = {\n  em(properties) {\n    return <i {...properties} />\n  }\n}\n\nconsole.log(\n  <MDXProvider components={components}>\n    <Post />\n  </MDXProvider>\n)\n```\n\n> 👉 **Note**: you don’t have to use `MDXProvider` and can pass components\n> directly:\n>\n> ```diff\n> -<MDXProvider components={components}>\n> -  <Post />\n> -</MDXProvider>\n> +<Post components={components} />\n> ```\n\nSee [¶ React in § Getting started][start-react] for how to get started with MDX\nand React.\nSee [¶ MDX provider in § Using MDX][use-provider] for how to use an MDX\nprovider.\n\n## API\n\nThis package exports the identifiers [`MDXProvider`][api-mdx-provider] and\n[`useMDXComponents`][api-use-mdx-components].\nThere is no default export.\n\n### `MDXProvider(properties?)`\n\nProvider for MDX context.\n\n###### Parameters\n\n* `properties` ([`Props`][api-props])\n  — configuration\n\n##### Returns\n\nElement (`ReactElement`).\n\n### `useMDXComponents(components?)`\n\nGet current components from the MDX Context.\n\n###### Parameters\n\n* `components` ([`MDXComponents` from `mdx/types.js`][mdx-types-components]\n  or [`MergeComponents`][api-merge-components], optional)\n  — additional components to use or a function that creates them\n\n###### Returns\n\nCurrent components ([`MDXComponents` from\n`mdx/types.js`][mdx-types-components]).\n\n### `MergeComponents`\n\nCustom merge function (TypeScript type).\n\n###### Parameters\n\n* `components` ([`MDXComponents` from `mdx/types.js`][mdx-types-components])\n  — current components from the context\n\n###### Returns\n\nAdditional components ([`MDXComponents` from\n`mdx/types.js`][mdx-types-components]).\n\n### `Props`\n\nConfiguration for `MDXProvider` (TypeScript type).\n\n###### Fields\n\n* `children` ([`ReactNode` from `react`][react-node],\n  optional)\n  — children\n* `components` ([`MDXComponents` from `mdx/types.js`][mdx-types-components]\n  or [`MergeComponents`][api-merge-components], optional)\n  — additional components to use or a function that creates them\n* `disableParentContext` (`boolean`, default: `false`)\n  — turn off outer component context\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional types [`MergeComponents`][api-merge-components] and\n[`Props`][api-props].\n\nFor types to work, make sure the TypeScript `JSX` namespace is typed.\nThis is done by installing and using the types of your framework, as in\n[`@types/react`](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react).\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/react@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © Compositor and [Vercel][]\n\n[api-mdx-provider]: #mdxproviderproperties\n\n[api-merge-components]: #mergecomponents\n\n[api-props]: #props\n\n[api-use-mdx-components]: #usemdxcomponentscomponents\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/react\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/react.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[esmsh]: https://esm.sh\n\n[mdx-types-components]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/mdx/types.d.ts#L65\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/react/license\n\n[next-configuring-mdx]: https://nextjs.org/docs/pages/building-your-application/configuring/mdx\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[react-node]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/react/index.d.ts#L244\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[size]: https://bundlejs.com/?q=@mdx-js/react\n\n[size-badge]: https://img.shields.io/bundlejs/size/@mdx-js/react\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[start-react]: https://mdxjs.com/getting-started/#react\n\n[support]: https://mdxjs.com/community/support/\n\n[typescript]: https://www.typescriptlang.org\n\n[use-provider]: https://mdxjs.com/docs/using-mdx/#mdx-provider\n\n[vercel]: https://vercel.com\n"
  },
  {
    "path": "packages/react/test/index.jsx",
    "content": "/**\n * @import {ComponentProps} from 'react'\n */\n\nimport assert from 'node:assert/strict'\nimport {test} from 'node:test'\nimport {evaluate} from '@mdx-js/mdx'\nimport {MDXProvider, useMDXComponents} from '@mdx-js/react'\nimport React from 'react'\nimport * as runtime from 'react/jsx-runtime'\nimport {renderToString} from 'react-dom/server'\n\ntest('@mdx-js/react', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('@mdx-js/preact')).sort(), [\n      'MDXProvider',\n      'useMDXComponents'\n    ])\n  })\n\n  await t.test(\n    'should support `components` with `MDXProvider`',\n    async function () {\n      const {default: Content} = await evaluate('# hi', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        renderToString(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              }\n            }}\n          >\n            <Content />\n          </MDXProvider>\n        ),\n        '<h1 style=\"color:tomato\">hi</h1>'\n      )\n    }\n  )\n\n  await t.test('should support `wrapper` in `components`', async function () {\n    const {default: Content} = await evaluate('# hi', {\n      ...runtime,\n      useMDXComponents\n    })\n\n    assert.equal(\n      renderToString(\n        <MDXProvider\n          components={{\n            /**\n             * @param {ComponentProps<'div'>} properties\n             */\n            wrapper(properties) {\n              return <div id=\"layout\" {...properties} />\n            }\n          }}\n        >\n          <Content />\n        </MDXProvider>\n      ),\n      '<div id=\"layout\"><h1>hi</h1></div>'\n    )\n  })\n\n  await t.test(\n    'should combine components in nested `MDXProvider`s',\n    async function () {\n      const {default: Content} = await evaluate('# hi\\n## hello', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        renderToString(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              },\n              h2(properties) {\n                return <h2 style={{color: 'rebeccapurple'}} {...properties} />\n              }\n            }}\n          >\n            <MDXProvider\n              components={{\n                h2(properties) {\n                  return <h2 style={{color: 'papayawhip'}} {...properties} />\n                }\n              }}\n            >\n              <Content />\n            </MDXProvider>\n          </MDXProvider>\n        ),\n        '<h1 style=\"color:tomato\">hi</h1>\\n<h2 style=\"color:papayawhip\">hello</h2>'\n      )\n    }\n  )\n\n  await t.test('should support components as a function', async function () {\n    const {default: Content} = await evaluate('# hi\\n## hello', {\n      ...runtime,\n      useMDXComponents\n    })\n\n    assert.equal(\n      renderToString(\n        <MDXProvider\n          components={{\n            h1(properties) {\n              return <h1 style={{color: 'tomato'}} {...properties} />\n            },\n            h2(properties) {\n              return <h2 style={{color: 'rebeccapurple'}} {...properties} />\n            }\n          }}\n        >\n          <MDXProvider\n            components={function () {\n              return {\n                h2(properties) {\n                  return <h2 style={{color: 'papayawhip'}} {...properties} />\n                }\n              }\n            }}\n          >\n            <Content />\n          </MDXProvider>\n        </MDXProvider>\n      ),\n      '<h1>hi</h1>\\n<h2 style=\"color:papayawhip\">hello</h2>'\n    )\n  })\n\n  await t.test(\n    'should support a `disableParentContext` prop (sandbox)',\n    async function () {\n      const {default: Content} = await evaluate('# hi', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        renderToString(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              }\n            }}\n          >\n            <MDXProvider disableParentContext>\n              <Content />\n            </MDXProvider>\n          </MDXProvider>\n        ),\n        '<h1>hi</h1>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support a `disableParentContext` *and* `components` as a function',\n    async function () {\n      const {default: Content} = await evaluate('# hi\\n## hello', {\n        ...runtime,\n        useMDXComponents\n      })\n\n      assert.equal(\n        renderToString(\n          <MDXProvider\n            components={{\n              h1(properties) {\n                return <h1 style={{color: 'tomato'}} {...properties} />\n              }\n            }}\n          >\n            <MDXProvider\n              disableParentContext\n              components={function () {\n                return {\n                  h2(properties) {\n                    return <h2 style={{color: 'papayawhip'}} {...properties} />\n                  }\n                }\n              }}\n            >\n              <Content />\n            </MDXProvider>\n          </MDXProvider>\n        ),\n        '<h1>hi</h1>\\n<h2 style=\"color:papayawhip\">hello</h2>'\n      )\n    }\n  )\n})\n"
  },
  {
    "path": "packages/react/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/remark-mdx/index.js",
    "content": "// Augment node types:\n/// <reference types=\"mdast-util-mdx\" />\n\n/**\n * @typedef {import('./lib/index.js').Options} Options\n */\n\nexport {default} from './lib/index.js'\n"
  },
  {
    "path": "packages/remark-mdx/lib/index.js",
    "content": "/**\n * @import {ToMarkdownOptions} from 'mdast-util-mdx'\n * @import {Options as MicromarkOptions} from 'micromark-extension-mdxjs'\n * @import {Processor} from 'unified'\n */\n\n/**\n * @typedef {MicromarkOptions & ToMarkdownOptions} Options\n *   Configuration.\n */\n\nimport {mdxFromMarkdown, mdxToMarkdown} from 'mdast-util-mdx'\nimport {mdxjs} from 'micromark-extension-mdxjs'\n\n/** @type {Readonly<Options>} */\nconst emptyOptions = {}\n\n/**\n * Add support for MDX (JSX: `<Video id={123} />`, export/imports: `export {x}\n * from 'y'`; and expressions: `{1 + 1}`).\n *\n * @this {Processor}\n *   Processor.\n * @param {Readonly<Options> | null | undefined} [options]\n *   Configuration (optional).\n * @returns {undefined}\n *   Nothing.\n */\nexport default function remarkMdx(options) {\n  const self = this\n  const settings = options || emptyOptions\n  const data = self.data()\n\n  const micromarkExtensions =\n    data.micromarkExtensions || (data.micromarkExtensions = [])\n  const fromMarkdownExtensions =\n    data.fromMarkdownExtensions || (data.fromMarkdownExtensions = [])\n  const toMarkdownExtensions =\n    data.toMarkdownExtensions || (data.toMarkdownExtensions = [])\n\n  micromarkExtensions.push(mdxjs(settings))\n  fromMarkdownExtensions.push(mdxFromMarkdown())\n  toMarkdownExtensions.push(mdxToMarkdown(settings))\n}\n"
  },
  {
    "path": "packages/remark-mdx/license",
    "content": "(The MIT License)\n\nCopyright (c) 2020 Titus Wormer <tituswormer@gmail.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/remark-mdx/package.json",
    "content": "{\n  \"name\": \"remark-mdx\",\n  \"version\": \"3.1.1\",\n  \"description\": \"remark plugin to support MDX syntax\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"javascript\",\n    \"jsx\",\n    \"markdown\",\n    \"mdast\",\n    \"mdx\",\n    \"plugin\",\n    \"remark\",\n    \"remark-plugin\",\n    \"unified\",\n    \"xml\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/remark-mdx/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\",\n  \"contributors\": [\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\",\n    \"Christian Murphy <christian.murphy.42@gmail.com>\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.js\",\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"mdast-util-mdx\": \"^3.0.0\",\n    \"micromark-extension-mdxjs\": \"^3.0.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development test/index.js\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"prettier\": true,\n    \"rules\": {\n      \"logical-assignment-operators\": \"off\",\n      \"n/file-extension-in-import\": \"off\",\n      \"unicorn/no-this-assignment\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/remark-mdx/readme.md",
    "content": "# remark-mdx\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Size][size-badge]][size]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nremark plugin to support the MDX syntax (JSX, export/import, expressions).\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`unified().use(remarkMdx[, options])`](#unifieduseremarkmdx-options)\n  * [`Options`](#options)\n* [Authoring](#authoring)\n* [HTML](#html)\n* [Syntax](#syntax)\n* [Syntax tree](#syntax-tree)\n* [Errors](#errors)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a [unified][] ([remark][]) plugin to enable the extensions to\nmarkdown that MDX adds: JSX (`<x/>`), export/import (`export x from 'y'`), and\nexpression {`{1 + 1}`}.\nYou can use this plugin to add support for parsing and serializing them.\n\nThis plugin does not handle how MDX is compiled to JavaScript or evaluated and\nrendered to HTML.\nThat’s done by [`@mdx-js/mdx`][mdx].\n\n## When should I use this?\n\nThis plugin is useful if you’re dealing with the MDX syntax and integrating\nwith remark, rehype, and the rest of unified.\nSome example use cases are when you want to lint the syntax or compile it to\nsomething other that JavaScript.\n\nIf you don’t use plugins and want to access the syntax tree, you can use\n[`mdast-util-from-markdown`][mdast-util-from-markdown] with\n[`mdast-util-mdx`][mdast-util-mdx].\n\nTypically though, you’d want to move a layer up: `@mdx-js/mdx`.\nThat package is the core compiler for turning MDX into JavaScript which\ngives you the most control.\nOr even higher: if you’re using a bundler (Rollup, esbuild, webpack), or a site\nbuilder (Next.js) or build system (Vite) which comes with a bundler, you’re\nbetter off using an integration: see [§ Integrations][integrations].\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install remark-mdx\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```tsx\nimport remarkMdx from 'https://esm.sh/remark-mdx@3'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n<script type=\"module\">\n  import remarkMdx from 'https://esm.sh/remark-mdx@3?bundle'\n</script>\n```\n\n## Use\n\n```tsx\nimport {remark} from 'remark'\nimport remarkMdx from 'remark-mdx'\n\nconst file = await remark()\n  .use(remarkMdx)\n  .process('import a from \"b\"\\n\\na <b /> c {1 + 1} d')\n\nconsole.log(String(file))\n```\n\nYields:\n\n```mdx\nimport a from \"b\"\n\na <b/> c {1 + 1} d\n```\n\n## API\n\nThis package exports no identifiers.\nThe default export is [`remarkMdx`][api-remark-mdx].\n\n### `unified().use(remarkMdx[, options])`\n\nAdd support for MDX (JSX: `<Video id={123} />`, export/imports: `export {x}\nfrom 'y'`; and expressions: `{1 + 1}`).\n\n###### Parameters\n\n* `options` ([`Options`][api-options], optional)\n  — configuration\n\n###### Returns\n\nNothing (`undefined`).\n\n### `Options`\n\nConfiguration (TypeScript type).\n\n###### Fields\n\n* `acornOptions` ([`AcornOptions`][acorn-options], default:\n  `{ecmaVersion: 2024, locations: true, sourceType: 'module'}`)\n  — configuration for acorn; all fields except `locations` can be set\n* `printWidth` (`number`, default: `Infinity`)\n  — try and wrap syntax at this width;\n  when set to a finite number (say, `80`), the formatter will print\n  attributes on separate lines when a tag doesn’t fit on one line;\n  the normal behavior is to print attributes with spaces between them instead\n  of line endings\n* `quote` (`'\"'` or `\"'\"`, default: `'\"'`)\n  — preferred quote to use around attribute values\n* `quoteSmart` (`boolean`, default: `false`)\n  — use the other quote if that results in less bytes\n* `tightSelfClosing` (`boolean`, default: `false`)\n  — do not use an extra space when closing self-closing elements: `<img/>`\n  instead of `<img />`\n\n<!-- Note: `acorn`, `addResult`, `allowEmpty`, and `spread` are intentionally not documented. -->\n\n## Authoring\n\nFor recommendations on how to author MDX, see each corresponding readme:\n\n* [ESM](https://github.com/micromark/micromark-extension-mdxjs-esm#authoring)\n* [JSX](https://github.com/micromark/micromark-extension-mdx-jsx#authoring)\n* [expressions](https://github.com/micromark/micromark-extension-mdx-expression/tree/main/packages/micromark-extension-mdx-expression#authoring)\n* [CommonMark features not in MDX](https://github.com/micromark/micromark-extension-mdx-md#authoring)\n\n## HTML\n\nMDX has no representation in HTML.\nThough, when you are dealing with MDX, you will likely go *through* hast.\nYou can enable passing MDX through to hast by configuring\n[`remark-rehype`][remark-rehype] with `passThrough: ['mdxjsEsm',\n'mdxFlowExpression', 'mdxJsxFlowElement', 'mdxJsxTextElement', 'mdxTextExpression']`.\n\n## Syntax\n\nFor info on the syntax of these features, see each corresponding readme:\n\n* [ESM](https://github.com/micromark/micromark-extension-mdxjs-esm#syntax)\n* [JSX](https://github.com/micromark/micromark-extension-mdx-jsx#syntax)\n* [expressions](https://github.com/micromark/micromark-extension-mdx-expression/tree/main/packages/micromark-extension-mdx-expression#syntax)\n* CommonMark features not in MDX: n/a\n\n## Syntax tree\n\nFor info on the syntax tree of these features, see each corresponding readme:\n\n* [ESM](https://github.com/syntax-tree/mdast-util-mdxjs-esm#syntax-tree)\n* [JSX](https://github.com/syntax-tree/mdast-util-mdx-jsx#syntax-tree)\n* [expressions](https://github.com/syntax-tree/mdast-util-mdx-expression#syntax-tree)\n* CommonMark features not in MDX: n/a\n\n## Errors\n\nFor info on what errors are thrown, see each corresponding readme:\n\n* [ESM](https://github.com/micromark/micromark-extension-mdxjs-esm#errors)\n* [JSX](https://github.com/micromark/micromark-extension-mdx-jsx#errors)\n* [expressions](https://github.com/micromark/micromark-extension-mdx-expression/tree/main/packages/micromark-extension-mdx-expression#errors)\n* CommonMark features not in MDX: n/a\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional type [`Options`][api-options].\n\nIf you’re working with the syntax tree, you can register the new node types\nwith `@types/mdast` by adding a reference:\n\n```tsx\n// Register MDX nodes in mdast:\n/// <reference types=\"remark-mdx\" />\n\n/**\n * @import {Root} from 'mdast'\n */\n\nimport {visit} from 'unist-util-visit'\n\nfunction myRemarkPlugin() {\n  /**\n   * @param {Root} tree\n   *   Tree.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree) {\n    visit(tree, function (node) {\n      console.log(node) // `node` can now be one of the MDX nodes.\n    })\n  }\n}\n```\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `remark-mdx@^3`, compatible\nwith Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © [Titus Wormer][author]\n\n[acorn-options]: https://github.com/acornjs/acorn/blob/520547b/acorn/src/acorn.d.ts#L578\n\n[api-options]: #options\n\n[api-remark-mdx]: #unifieduseremarkmdx-options\n\n[author]: https://wooorm.com\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/remark-mdx\n\n[downloads-badge]: https://img.shields.io/npm/dm/remark-mdx.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[esmsh]: https://esm.sh\n\n[integrations]: https://mdxjs.com/getting-started/#integrations\n\n[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown\n\n[mdast-util-mdx]: https://github.com/syntax-tree/mdast-util-mdx\n\n[mdx]: https://mdxjs.com/packages/mdx/\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/remark-mdx/license\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[remark]: https://github.com/remarkjs/remark\n\n[remark-rehype]: https://github.com/remarkjs/remark-rehype\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[size]: https://bundlephobia.com/result?p=remark-mdx\n\n[size-badge]: https://img.shields.io/bundlephobia/minzip/remark-mdx.svg\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[support]: https://mdxjs.com/community/support/\n\n[typescript]: https://www.typescriptlang.org\n\n[unified]: https://github.com/unifiedjs/unified\n"
  },
  {
    "path": "packages/remark-mdx/test/index.js",
    "content": "/**\n * @import {Nodes} from 'mdast'\n * @import {\n      MdxJsxAttribute,\n      MdxJsxAttributeValueExpression,\n      MdxJsxExpressionAttribute\n * } from 'mdast-util-mdx'\n */\n\nimport assert from 'node:assert/strict'\nimport {test} from 'node:test'\nimport remarkMdx from 'remark-mdx'\nimport remarkParse from 'remark-parse'\nimport remarkStringify from 'remark-stringify'\nimport {unified} from 'unified'\nimport {removePosition} from 'unist-util-remove-position'\nimport {visit} from 'unist-util-visit'\n\nconst basic = unified().use(remarkParse).use(remarkMdx)\n\ntest('remark-mdx: core', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('remark-mdx')).sort(), [\n      'default'\n    ])\n  })\n})\n\ntest('remark-mdx: parse', async function (t) {\n  await t.test('should parse a self-closing tag', function () {\n    const tree = basic.parse('Alpha <b/> charlie.')\n\n    clean(tree)\n\n    assert.deepEqual(tree, {\n      type: 'root',\n      children: [\n        {\n          type: 'paragraph',\n          children: [\n            {type: 'text', value: 'Alpha '},\n            {\n              type: 'mdxJsxTextElement',\n              name: 'b',\n              attributes: [],\n              children: []\n            },\n            {type: 'text', value: ' charlie.'}\n          ]\n        }\n      ]\n    })\n  })\n\n  await t.test('should parse an opening and a closing tag', function () {\n    const tree = basic.parse('Alpha <b></b> charlie.')\n\n    clean(tree)\n\n    assert.deepEqual(tree, {\n      type: 'root',\n      children: [\n        {\n          type: 'paragraph',\n          children: [\n            {type: 'text', value: 'Alpha '},\n            {\n              type: 'mdxJsxTextElement',\n              name: 'b',\n              attributes: [],\n              children: []\n            },\n            {type: 'text', value: ' charlie.'}\n          ]\n        }\n      ]\n    })\n  })\n\n  await t.test('should parse fragments', function () {\n    const tree = basic.parse('Alpha <></> charlie.')\n\n    clean(tree)\n\n    assert.deepEqual(tree, {\n      type: 'root',\n      children: [\n        {\n          type: 'paragraph',\n          children: [\n            {type: 'text', value: 'Alpha '},\n            {\n              type: 'mdxJsxTextElement',\n              name: null,\n              attributes: [],\n              children: []\n            },\n            {type: 'text', value: ' charlie.'}\n          ]\n        }\n      ]\n    })\n  })\n\n  await t.test('should parse markdown inside tags', function () {\n    const tree = basic.parse('Alpha <b>*bravo*</b> charlie.')\n\n    clean(tree)\n\n    assert.deepEqual(tree, {\n      type: 'root',\n      children: [\n        {\n          type: 'paragraph',\n          children: [\n            {type: 'text', value: 'Alpha '},\n            {\n              type: 'mdxJsxTextElement',\n              name: 'b',\n              attributes: [],\n              children: [\n                {type: 'emphasis', children: [{type: 'text', value: 'bravo'}]}\n              ]\n            },\n            {type: 'text', value: ' charlie.'}\n          ]\n        }\n      ]\n    })\n  })\n\n  await t.test('should parse expressions', function () {\n    const tree = basic.parse('Alpha {1 + 1} charlie.')\n\n    clean(tree)\n\n    assert.deepEqual(tree, {\n      type: 'root',\n      children: [\n        {\n          type: 'paragraph',\n          children: [\n            {type: 'text', value: 'Alpha '},\n            {\n              type: 'mdxTextExpression',\n              data: {estree: undefined},\n              value: '1 + 1'\n            },\n            {type: 'text', value: ' charlie.'}\n          ]\n        }\n      ]\n    })\n  })\n})\n\ntest('remark-mdx: stringify', async function (t) {\n  const basic = unified().use(remarkStringify).use(remarkMdx)\n\n  await t.test('should serialize an empty nameless fragment', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {\n                type: 'mdxJsxTextElement',\n                name: null,\n                attributes: [],\n                children: []\n              },\n              {type: 'text', value: ' charlie.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha <></> charlie.\\n'\n    )\n  })\n\n  await t.test('should serialize a tag with a name', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {\n                type: 'mdxJsxTextElement',\n                name: 'b',\n                attributes: [],\n                children: []\n              },\n              {type: 'text', value: ' charlie.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha <b /> charlie.\\n'\n    )\n  })\n\n  await t.test('should serialize a boolean attribute (element)', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {\n                type: 'mdxJsxTextElement',\n                name: 'b',\n                attributes: [{type: 'mdxJsxAttribute', name: 'bravo'}],\n                children: []\n              },\n              {type: 'text', value: ' charlie.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha <b bravo /> charlie.\\n'\n    )\n  })\n\n  await t.test('should serialize an attribute (element)', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {\n                type: 'mdxJsxTextElement',\n                name: 'b',\n                attributes: [\n                  {type: 'mdxJsxAttribute', name: 'bravo', value: 'bravo'}\n                ],\n                children: []\n              },\n              {type: 'text', value: ' charlie.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha <b bravo=\"bravo\" /> charlie.\\n'\n    )\n  })\n\n  await t.test('should serialize a prefixed attribute (element)', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {\n                type: 'mdxJsxTextElement',\n                name: 'b',\n                attributes: [\n                  {type: 'mdxJsxAttribute', name: 'br:avo', value: 'bravo'}\n                ],\n                children: []\n              },\n              {type: 'text', value: ' charlie.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha <b br:avo=\"bravo\" /> charlie.\\n'\n    )\n  })\n\n  await t.test(\n    'should serialize a attribute expression (element)',\n    function () {\n      assert.equal(\n        basic.stringify({\n          type: 'root',\n          children: [\n            {\n              type: 'paragraph',\n              children: [\n                {type: 'text', value: 'Alpha '},\n                {\n                  type: 'mdxJsxTextElement',\n\n                  name: 'b',\n                  attributes: [\n                    {type: 'mdxJsxExpressionAttribute', value: '...properties'}\n                  ],\n                  children: []\n                },\n                {type: 'text', value: ' charlie.'}\n              ]\n            }\n          ]\n        }),\n        'Alpha <b {...properties} /> charlie.\\n'\n      )\n    }\n  )\n\n  await t.test(\n    'should serialize an expression attribute (element)',\n    function () {\n      assert.equal(\n        basic.stringify({\n          type: 'root',\n          children: [\n            {\n              type: 'paragraph',\n              children: [\n                {type: 'text', value: 'Alpha '},\n                {\n                  type: 'mdxJsxTextElement',\n\n                  name: 'b',\n                  attributes: [\n                    {\n                      type: 'mdxJsxAttribute',\n                      name: 'b',\n                      value: {\n                        type: 'mdxJsxAttributeValueExpression',\n                        data: {estree: undefined},\n                        value: '1 + 1'\n                      }\n                    }\n                  ],\n                  children: []\n                },\n                {type: 'text', value: ' charlie.'}\n              ]\n            }\n          ]\n        }),\n        'Alpha <b b={1 + 1} /> charlie.\\n'\n      )\n    }\n  )\n\n  await t.test('should write out a url as the raw value', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {\n                type: 'link',\n                url: 'https://mdxjs.com',\n                children: [{type: 'text', value: 'https://mdxjs.com'}]\n              }\n            ]\n          }\n        ]\n      }),\n      '[https://mdxjs.com](https://mdxjs.com)\\n'\n    )\n  })\n\n  await t.test('should encode `<` in text', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {\n                type: 'mdxJsxTextElement',\n                name: null,\n                attributes: [],\n                children: [{type: 'text', value: '1 < 3'}]\n              },\n              {type: 'text', value: ' bravo.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha <>1 \\\\< 3</> bravo.\\n'\n    )\n  })\n\n  await t.test('should encode `{` in text', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {\n                type: 'mdxJsxTextElement',\n                name: null,\n                attributes: [],\n                children: [{type: 'text', value: '1 { 3'}]\n              },\n              {type: 'text', value: ' bravo.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha <>1 \\\\{ 3</> bravo.\\n'\n    )\n  })\n\n  await t.test('should serialize empty expressions', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {type: 'mdxTextExpression', value: ''},\n              {type: 'text', value: ' bravo.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha {} bravo.\\n'\n    )\n  })\n\n  await t.test('should serialize expressions', function () {\n    assert.equal(\n      basic.stringify({\n        type: 'root',\n        children: [\n          {\n            type: 'paragraph',\n            children: [\n              {type: 'text', value: 'Alpha '},\n              {type: 'mdxTextExpression', value: '1 + 1'},\n              {type: 'text', value: ' bravo.'}\n            ]\n          }\n        ]\n      }),\n      'Alpha {1 + 1} bravo.\\n'\n    )\n  })\n})\n\n/**\n * @param {Nodes} tree\n *   Tree.\n * @returns {undefined}\n *   Nothing.\n */\nfunction clean(tree) {\n  removePosition(tree, {force: true})\n  visit(tree, onvisit)\n}\n\n/**\n * @param {MdxJsxAttribute | MdxJsxAttributeValueExpression | MdxJsxExpressionAttribute | Nodes} node\n *   Node.\n * @returns {undefined}\n *   Nothing.\n */\nfunction onvisit(node) {\n  if (\n    (node.type === 'mdxjsEsm' ||\n      node.type === 'mdxTextExpression' ||\n      node.type === 'mdxFlowExpression' ||\n      node.type === 'mdxJsxAttribute' ||\n      node.type === 'mdxJsxAttributeValueExpression' ||\n      node.type === 'mdxJsxExpressionAttribute') &&\n    node.data &&\n    'estree' in node.data &&\n    node.data.estree\n  ) {\n    node.data.estree = undefined\n  }\n\n  if (node.type === 'mdxJsxTextElement' || node.type === 'mdxJsxFlowElement') {\n    let index = -1\n\n    while (++index < node.attributes.length) {\n      const child = node.attributes[index]\n\n      onvisit(child)\n\n      if (child.value && typeof child.value === 'object') {\n        onvisit(child.value)\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/remark-mdx/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/rollup/index.js",
    "content": "/**\n * @typedef {import('./lib/index.js').Options} Options\n */\n\nexport {rollup as default} from './lib/index.js'\n"
  },
  {
    "path": "packages/rollup/lib/index.js",
    "content": "/**\n * @import {FormatAwareProcessors} from '@mdx-js/mdx/internal-create-format-aware-processors'\n * @import {CompileOptions} from '@mdx-js/mdx'\n * @import {FilterPattern} from '@rollup/pluginutils'\n * @import {SourceDescription} from 'rollup'\n */\n\n/**\n * @typedef {Omit<CompileOptions, 'SourceMapGenerator'>} ApplicableOptions\n *   Applicable compile configuration.\n *\n * @typedef ExtraOptions\n *   Extra configuration.\n * @property {FilterPattern | null | undefined} [exclude]\n *   Picomatch patterns to exclude (optional).\n * @property {FilterPattern | null | undefined} [include]\n *   Picomatch patterns to include (optional).\n *\n * @typedef {ApplicableOptions & ExtraOptions} Options\n *   Configuration.\n *\n * @typedef Plugin\n *   Plugin that is compatible with both Rollup and Vite.\n * @property {string} name\n *   The name of the plugin\n * @property {ViteConfig} config\n *   Function used by Vite to set additional configuration options.\n * @property {Transform} transform\n *   Function to transform the source content.\n *\n * @callback Transform\n *   Callback called by Rollup and Vite to transform.\n * @param {string} value\n *   File contents.\n * @param {string} id\n *   Module ID.\n * @returns {Promise<SourceDescription | undefined>}\n *   Result.\n *\n * @callback ViteConfig\n *   Callback called by Vite to set additional configuration options.\n * @param {unknown} config\n *   Configuration object (unused).\n * @param {ViteEnv} env\n *   Environment variables.\n * @returns {undefined}\n *   Nothing.\n *\n * @typedef ViteEnv\n *   Environment variables used by Vite.\n * @property {string} mode\n *   Mode.\n */\n\nimport {createFormatAwareProcessors} from '@mdx-js/mdx/internal-create-format-aware-processors'\nimport {createFilter} from '@rollup/pluginutils'\nimport {SourceMapGenerator} from 'source-map'\nimport {VFile} from 'vfile'\n\n/**\n * Plugin to compile MDX w/ rollup.\n *\n * @param {Readonly<Options> | null | undefined} [options]\n *   Configuration (optional).\n * @return {Plugin}\n *   Rollup plugin.\n */\nexport function rollup(options) {\n  const {exclude, include, ...rest} = options || {}\n  /** @type {FormatAwareProcessors} */\n  let formatAwareProcessors\n  const filter = createFilter(include, exclude)\n\n  return {\n    name: '@mdx-js/rollup',\n    config(config, env) {\n      formatAwareProcessors = createFormatAwareProcessors({\n        SourceMapGenerator,\n        development: env.mode === 'development',\n        ...rest\n      })\n    },\n    async transform(value, id) {\n      if (!formatAwareProcessors) {\n        formatAwareProcessors = createFormatAwareProcessors({\n          SourceMapGenerator,\n          ...rest\n        })\n      }\n\n      const [path] = id.split('?')\n      const file = new VFile({path, value})\n\n      if (\n        file.extname &&\n        filter(file.path) &&\n        formatAwareProcessors.extnames.includes(file.extname)\n      ) {\n        const compiled = await formatAwareProcessors.process(file)\n        const code = String(compiled.value)\n        /** @type {SourceDescription} */\n        const result = {code, map: compiled.map}\n        return result\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "packages/rollup/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2021 Titus Wormer\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/rollup/package.json",
    "content": "{\n  \"name\": \"@mdx-js/rollup\",\n  \"version\": \"3.1.1\",\n  \"description\": \"Rollup plugin for MDX\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"jsx\",\n    \"markdown\",\n    \"mdx\",\n    \"preact\",\n    \"react\",\n    \"remark\",\n    \"rollup\",\n    \"vue\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/rollup/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"John Otander <johnotander@gmail.com> (https://johno.com)\",\n  \"contributors\": [\n    \"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.js\",\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"@mdx-js/mdx\": \"^3.0.0\",\n    \"@rollup/pluginutils\": \"^5.0.0\",\n    \"source-map\": \"^0.7.0\",\n    \"vfile\": \"^6.0.0\"\n  },\n  \"peerDependencies\": {\n    \"rollup\": \">=2\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development test/index.js\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"prettier\": true,\n    \"rules\": {\n      \"logical-assignment-operators\": \"off\",\n      \"n/file-extension-in-import\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/rollup/readme.md",
    "content": "# `@mdx-js/rollup`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nRollup (and Vite) plugin for MDX.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`mdx(options?)`](#mdxoptions)\n  * [`Options`](#options)\n* [Examples](#examples)\n  * [Combine with Babel](#combine-with-babel)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a Rollup (and Vite) plugin to support MDX.\n\n## When should I use this?\n\nThis integration is useful if you’re using Rollup (or another tool that uses\nRollup, such as Vite).\n\nThis integration can be combined with the Babel plugin to compile modern\nJavaScript features to ones your users support.\n\nIf you want to evaluate MDX code then the lower-level compiler (`@mdx-js/mdx`)\ncan be used manually.\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/rollup\n```\n\n## Use\n\nAdd something along these lines to your `rollup.config.js`:\n\n```tsx\n/**\n * @import {RollupOptions} from 'rollup'\n */\n\nimport mdx from '@mdx-js/rollup'\n\n/** @type {RollupOptions} */\nconst config = {\n  // …\n  plugins: [\n    // …\n    mdx({/* jsxImportSource: …, otherOptions… */})\n  ]\n}\n\nexport default config\n```\n\nSee also [¶ Vite][vite] if you’re using Rollup through them for more info.\n\n## API\n\nThis package exports no identifiers.\nThe default export is [`mdx`][api-mdx].\n\n### `mdx(options?)`\n\nPlugin to compile MDX w/ [rollup][].\n\n###### Parameters\n\n* `options` ([`Options`][api-options], optional)\n  — configuration\n\n###### Returns\n\nRollup (and Vite) plugin.\n\n### `Options`\n\nConfiguration (TypeScript type).\n\nOptions are the same as [`CompileOptions` from `@mdx-js/mdx`][compile-options]\nwith the exception that the `SourceMapGenerator` option is supported based on\nhow you configure Rollup.\nYou cannot pass it manually.\nWhen using Vite, the `development` option is also supported based on how you\nconfigure Vite.\n\nThere are also two additional options:\n\n###### Fields\n\n* `exclude` (`Array<RegExp | string>`, `RegExp`, or `string`, optional)\n  — [picomatch][] patterns to exclude\n* `include` (`Array<RegExp | string>`, `RegExp`, or `string`, optional)\n  — [picomatch][] patterns to include\n\n## Examples\n\n### Combine with Babel\n\nIf you use modern JavaScript features you might want to use Babel through\n[`@rollup/plugin-babel`][rollup-plugin-babel] to compile to code that works:\n\n```tsx\n/**\n * @import {RollupOptions} from 'rollup'\n */\n\nimport mdx from '@mdx-js/rollup'\nimport {babel} from '@rollup/plugin-babel'\n\n/** @type {RollupOptions} */\nconst config = {\n  // …\n  plugins: [\n    // …\n    mdx({/* jsxImportSource: …, otherOptions… */}),\n    babel({\n      // Also run on what used to be `.mdx` (but is now JS):\n      extensions: ['.js', '.jsx', '.cjs', '.mjs', '.md', '.mdx']\n      // Other options…\n    })\n  ]\n}\n\nexport default config\n```\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional type [`Options`][api-options].\nSee [§ Types][types] on our website for information.\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/rollup@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © [Titus Wormer][author]\n\n[api-mdx]: #mdxoptions\n\n[api-options]: #options\n\n[author]: https://wooorm.com\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[compile-options]: https://mdxjs.com/packages/mdx/#compileoptions\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/rollup\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/rollup.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/rollup/license\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[picomatch]: https://github.com/micromatch/picomatch#globbing-features\n\n[rollup]: https://rollupjs.org\n\n[rollup-plugin-babel]: https://github.com/rollup/plugins/tree/HEAD/packages/babel\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[support]: https://mdxjs.com/community/support/\n\n[types]: https://mdxjs.com/getting-started/#types\n\n[typescript]: https://www.typescriptlang.org\n\n[vite]: https://mdxjs.com/getting-started/#vite\n"
  },
  {
    "path": "packages/rollup/test/index.js",
    "content": "/**\n * @import {MDXModule} from 'mdx/types.js'\n * @import {RollupOutput} from 'rollup'\n */\n\nimport assert from 'node:assert/strict'\nimport fs from 'node:fs/promises'\nimport {test} from 'node:test'\nimport {fileURLToPath} from 'node:url'\nimport rollupMdx from '@mdx-js/rollup'\nimport React from 'react'\nimport {renderToStaticMarkup} from 'react-dom/server'\nimport {rollup} from 'rollup'\nimport {build} from 'vite'\n\ntest('@mdx-js/rollup', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('@mdx-js/rollup')).sort(), [\n      'default'\n    ])\n  })\n\n  await t.test('should work', async function () {\n    const mdxUrl = new URL('rollup.mdx', import.meta.url)\n    const jsUrl = new URL('rollup.js', import.meta.url)\n\n    await fs.writeFile(\n      mdxUrl,\n      'export function Message() { return <>World!</> }\\n\\n# Hello, <Message />'\n    )\n\n    const build = await rollup({\n      external: ['react/jsx-runtime'],\n      input: fileURLToPath(mdxUrl),\n      plugins: [rollupMdx()]\n    })\n\n    const {output} = await build.generate({format: 'es', sourcemap: true})\n    const chunk = output[0]\n\n    // Source map.\n    assert.equal(\n      chunk.map?.mappings,\n      ';;AAAO,SAAA,OAAA,GAAA;;AAA8B,IAAA,QAAA,EAAA;;;;;;;;;AAEnC,IAAA,QAAA,EAAA,CAAA,SAAA,EAAAA,GAAA,CAAA,OAAA,EAAA,EAAA,CAAA;;;;;;;;;;;;;;;'\n    )\n\n    await fs.writeFile(jsUrl, chunk.code)\n\n    /** @type {MDXModule} */\n    const result = await import(jsUrl.href)\n    const Content = result.default\n\n    assert.equal(\n      renderToStaticMarkup(React.createElement(Content)),\n      '<h1>Hello, World!</h1>'\n    )\n\n    await fs.rm(mdxUrl)\n    await fs.rm(jsUrl)\n  })\n\n  await t.test('should infer production mode in vite', async () => {\n    const result = /** @type {Array<RollupOutput>} */ (\n      await build({\n        build: {\n          lib: {\n            entry: fileURLToPath(new URL('vite-entry.mdx', import.meta.url)),\n            name: 'production'\n          },\n          write: false\n        },\n        logLevel: 'silent',\n        plugins: [rollupMdx()]\n      })\n    )\n\n    const code = result[0].output[0].code\n\n    assert.match(code, /jsxs?\\(/)\n    assert.doesNotMatch(code, /jsxDEV\\(/)\n  })\n\n  await t.test('should infer development mode in vite', async () => {\n    const result = /** @type {Array<RollupOutput>} */ (\n      await build({\n        build: {\n          lib: {\n            entry: fileURLToPath(new URL('vite-entry.mdx', import.meta.url)),\n            name: 'production'\n          },\n          write: false\n        },\n        logLevel: 'silent',\n        mode: 'development',\n        plugins: [rollupMdx()]\n      })\n    )\n\n    const code = result[0].output[0].code\n\n    assert.doesNotMatch(code, /jsxs?\\(/)\n    assert.match(code, /jsxDEV\\(/)\n  })\n\n  await t.test('should handle query parameters in vite', async () => {\n    const result = /** @type {Array<RollupOutput>} */ (\n      await build({\n        build: {\n          lib: {\n            entry:\n              fileURLToPath(new URL('vite-entry.mdx', import.meta.url)) +\n              '?query=param',\n            name: 'query'\n          },\n          write: false\n        },\n        logLevel: 'silent',\n        plugins: [rollupMdx()]\n      })\n    )\n\n    const code = result[0].output[0].code\n\n    assert.match(code, /Hello Vite/)\n    assert.match(code, /jsxs?\\(/)\n  })\n})\n"
  },
  {
    "path": "packages/rollup/test/vite-entry.mdx",
    "content": "# Hello Vite\n"
  },
  {
    "path": "packages/rollup/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "packages/vue/index.js",
    "content": "export {MDXProvider, useMDXComponents} from './lib/index.js'\n"
  },
  {
    "path": "packages/vue/lib/index.js",
    "content": "/**\n * @import {MDXComponents} from 'mdx/types.js'\n * @import {Component, ComponentPublicInstance} from 'vue'\n */\n\n/**\n * @typedef Props\n *   Configuration for `MDXProvider`.\n * @property {MDXComponents | null | undefined} [components]\n *   Additional components to use (optional).\n */\n\nimport {Fragment, createVNode, inject, provide} from 'vue'\n\n/**\n * Provider for MDX context.\n *\n * @type {Component<Props>}\n *   Provider.\n */\nexport const MDXProvider = {\n  name: 'MDXProvider',\n  props: {\n    components: {\n      default() {\n        return {}\n      },\n      type: Object\n    }\n  },\n  setup(properties) {\n    provide('$mdxComponents', properties.components)\n  },\n  /**\n   * @this {ComponentPublicInstance}\n   *   Context.\n   * @returns\n   *   Element.\n   */\n  render() {\n    return createVNode(\n      Fragment,\n      undefined,\n      this.$slots.default ? this.$slots.default() : []\n    )\n  }\n}\n\n/**\n * Get current components from the MDX Context.\n *\n * @returns {MDXComponents}\n *   Current components.\n */\nexport function useMDXComponents() {\n  return inject('$mdxComponents', {})\n}\n"
  },
  {
    "path": "packages/vue/license",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2017 Compositor, Inc. and Vercel, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "packages/vue/package.json",
    "content": "{\n  \"name\": \"@mdx-js/vue\",\n  \"version\": \"3.1.1\",\n  \"description\": \"Vue provider for MDX\",\n  \"license\": \"MIT\",\n  \"keywords\": [\n    \"jsx\",\n    \"markdown\",\n    \"mdx\",\n    \"remark\",\n    \"vue\"\n  ],\n  \"homepage\": \"https://mdxjs.com\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mdx-js/mdx\",\n    \"directory\": \"packages/vue/\"\n  },\n  \"bugs\": \"https://github.com/mdx-js/mdx/issues\",\n  \"funding\": {\n    \"type\": \"opencollective\",\n    \"url\": \"https://opencollective.com/unified\"\n  },\n  \"author\": \"Jonathan Bakebwa <jonas@akkadu-team.com> (https://jbakebwa.dev)\",\n  \"contributors\": [\n    \"Jonathan Bakebwa <jonas@akkadu-team.com> (https://jbakebwa.dev)\",\n    \"Christian Murphy <christian.murphy.42@gmail.com>\"\n  ],\n  \"type\": \"module\",\n  \"sideEffects\": false,\n  \"exports\": \"./index.js\",\n  \"files\": [\n    \"lib/\",\n    \"index.d.ts.map\",\n    \"index.d.ts\",\n    \"index.js\"\n  ],\n  \"dependencies\": {\n    \"@types/mdx\": \"^2.0.0\"\n  },\n  \"peerDependencies\": {\n    \"vue\": \">=3.0.0\"\n  },\n  \"devDependencies\": {},\n  \"scripts\": {\n    \"test\": \"npm run test-coverage\",\n    \"test-api\": \"node --conditions development test/index.js\",\n    \"test-coverage\": \"c8 --100 --reporter lcov npm run test-api\"\n  },\n  \"xo\": {\n    \"prettier\": true,\n    \"rules\": {\n      \"n/file-extension-in-import\": \"off\"\n    }\n  }\n}\n"
  },
  {
    "path": "packages/vue/readme.md",
    "content": "# `@mdx-js/vue`\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Size][size-badge]][size]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\nVue context for MDX.\n\n<!-- more -->\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`MDXProvider(properties?)`](#mdxproviderproperties)\n  * [`useMDXComponents(components?)`](#usemdxcomponentscomponents)\n  * [`Props`](#props)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a *context* based components provider for combining Vue with\nMDX.\n\n## When should I use this?\n\nThis package is **not needed** for MDX to work with Vue.\nSee [¶ MDX provider in § Using MDX][use-provider] for when and how to use an MDX\nprovider.\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install @mdx-js/vue\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```tsx\nimport {MDXProvider} from 'https://esm.sh/@mdx-js/vue@3'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n<script type=\"module\">\n  import {MDXProvider} from 'https://esm.sh/@mdx-js/vue@3?bundle'\n</script>\n```\n\n## Use\n\n```tsx\nimport {MDXProvider} from '@mdx-js/vue'\nimport {createApp} from 'vue'\nimport Post from './post.mdx'\n// ^-- Assumes an integration is used to compile MDX to JS, such as\n// `@mdx-js/esbuild`, `@mdx-js/loader`, `@mdx-js/node-loader`, or\n// `@mdx-js/rollup`, and that it is configured with\n// `options.providerImportSource: '@mdx-js/vue'`.\n\ncreateApp({\n  data() {\n    return {components: {h1: 'h2'}}\n  },\n  template: '<MDXProvider v-bind:components=\"components\"><Post /></MDXProvider>',\n  components: {MDXProvider, Post}\n})\n```\n\n> 👉 **Note**: you don’t have to use `MDXProvider` and can pass components\n> directly:\n>\n> ```diff\n> -createApp({\n> -  data() {\n> -    return {components: {h1: 'h2'}}\n> -  },\n> -  template: '<MDXProvider v-bind:components=\"components\"><Post /></MDXProvider>',\n> -  components: {MDXProvider, Post}\n> -})\n> +createApp(Post, {components: {h1: 'h2'}})\n> ```\n\nSee [¶ Vue in § Getting started][start-vue] for how to get started with MDX and\nVue.\nSee [¶ MDX provider in § Using MDX][use-provider] for how to use an MDX\nprovider.\n\n## API\n\nThis package exports the identifiers [`MDXProvider`][api-mdx-provider] and\n[`useMDXComponents`][api-use-mdx-components].\nThere is no default export.\n\n### `MDXProvider(properties?)`\n\nProvider for MDX context (`Component` from `vue`).\n\n### `useMDXComponents(components?)`\n\nGet current components from the MDX Context.\n\n###### Parameters\n\nThere are no parameters.\n\n###### Returns\n\nCurrent components ([`MDXComponents` from\n`mdx/types.js`][mdx-types-components]).\n\n### `Props`\n\nConfiguration for `MDXProvider` (TypeScript type).\n\n###### Fields\n\n* `components` ([`MDXComponents` from `mdx/types.js`][mdx-types-components],\n  optional)\n  — additional components to use\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional type [`Props`][api-props].\n\nFor types to work, make sure the TypeScript `JSX` namespace is typed.\nThis is done by installing and using the types of your framework, as in\n[`vue`](https://github.com/vuejs/core).\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `@mdx-js/vue@^3`,\ncompatible with Node.js 16.\n\n## Security\n\nSee [§ Security][security] on our website for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our website for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][] © Compositor and [Vercel][]\n\n[api-mdx-provider]: #mdxproviderproperties\n\n[api-props]: #props\n\n[api-use-mdx-components]: #usemdxcomponentscomponents\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[downloads]: https://www.npmjs.com/package/@mdx-js/vue\n\n[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/vue.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[esmsh]: https://esm.sh\n\n[mdx-types-components]: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/HEAD/types/mdx/types.d.ts#L65\n\n[mit]: https://github.com/mdx-js/mdx/blob/main/packages/vue/license\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[size]: https://bundlejs.com/?q=@mdx-js/vue\n\n[size-badge]: https://img.shields.io/bundlejs/size/@mdx-js/vue\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[start-vue]: https://mdxjs.com/getting-started/#vue\n\n[support]: https://mdxjs.com/community/support/\n\n[typescript]: https://www.typescriptlang.org\n\n[use-provider]: https://mdxjs.com/docs/using-mdx/#mdx-provider\n\n[vercel]: https://vercel.com\n"
  },
  {
    "path": "packages/vue/test/index.js",
    "content": "/**\n * @import {MDXModule} from 'mdx/types.js'\n * @import {Component} from 'vue'\n */\n\nimport assert from 'node:assert/strict'\nimport test from 'node:test'\nimport {compile, run} from '@mdx-js/mdx'\nimport {MDXProvider, useMDXComponents} from '@mdx-js/vue'\nimport serverRenderer from '@vue/server-renderer'\nimport * as runtime from 'vue/jsx-runtime'\nimport * as vue from 'vue'\n\ntest('@mdx-js/vue', async function (t) {\n  await t.test('should expose the public api', async function () {\n    assert.deepEqual(Object.keys(await import('@mdx-js/vue')).sort(), [\n      'MDXProvider',\n      'useMDXComponents'\n    ])\n  })\n\n  await t.test('should evaluate MDX code', async function () {\n    const {default: Content} = await evaluate('# hi')\n\n    assert.equal(await vueToString(Content), '<h1>hi</h1>')\n  })\n\n  await t.test(\n    'should evaluate some more complex MDX code (text, inline)',\n    async function () {\n      const {default: Content} = await evaluate(\n        '*a* **b** `c` <abbr title=\"Markdown + JSX\">MDX</abbr>'\n      )\n\n      assert.equal(\n        await vueToString(Content),\n        '<p><em>a</em> <strong>b</strong> <code>c</code> <abbr title=\"Markdown + JSX\">MDX</abbr></p>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support Vue components defined in MDX',\n    async function () {\n      const {default: Content} = await evaluate(\n        'export const A = {render() { return <b>!</b> }}\\n\\n<A />'\n      )\n\n      assert.equal(await vueToString(Content), '<b>!</b>')\n    }\n  )\n\n  await t.test('should support passing `components`', async function () {\n    const {default: Content} = await evaluate('# hi')\n\n    assert.equal(\n      await vueToString(Content, {components: {h1: 'h2'}}),\n      '<h2>hi</h2>'\n    )\n  })\n\n  await t.test('should support passing `components`', async function () {\n    const {default: Content} = await evaluate('# hi')\n\n    assert.equal(\n      await vueToString(Content, {components: {h1: 'h2'}}),\n      '<h2>hi</h2>'\n    )\n  })\n\n  await t.test('should support `MDXProvider`', async function () {\n    const {default: Content} = await evaluate('# hi')\n\n    assert.equal(\n      await vueToString({\n        components: {Content, MDXProvider},\n        data() {\n          return {components: {h1: 'h2'}}\n        },\n        template:\n          '<MDXProvider v-bind:components=\"components\"><Content /></MDXProvider>'\n      }),\n      '<h2>hi</h2>'\n    )\n  })\n\n  await t.test(\n    'should support the MDX provider w/o components',\n    async function () {\n      const {default: Content} = await evaluate('# hi')\n\n      assert.equal(\n        await vueToString({\n          components: {Content, MDXProvider},\n          template: '<MDXProvider><Content /></MDXProvider>'\n        }),\n        '<h1>hi</h1>'\n      )\n    }\n  )\n\n  await t.test(\n    'should support the MDX provider w/o content',\n    async function () {\n      assert.equal(\n        await vueToString({\n          components: {MDXProvider},\n          template: '<MDXProvider />'\n        }),\n        ''\n      )\n    }\n  )\n})\n\n/**\n * @param {string} value\n *   MDX.\n * @returns {Promise<MDXModule>}\n *   Module.\n */\nasync function evaluate(value) {\n  const file = await compile(value, {\n    outputFormat: 'function-body',\n    providerImportSource: '#'\n  })\n  return run(file, {\n    ...runtime,\n    useMDXComponents\n  })\n}\n\n/**\n * @param {Component} root\n *   Component.\n * @param {Record<string, unknown> | null | undefined} [rootProperties]\n *   Props.\n * @returns {Promise<string>}\n *   HTML.\n */\nasync function vueToString(root, rootProperties) {\n  const result = await serverRenderer.renderToString(\n    vue.createSSRApp(root, rootProperties)\n  )\n  // Remove SSR comments used to hydrate.\n  return result.replaceAll(/<!--[[\\]]-->/g, '')\n}\n"
  },
  {
    "path": "packages/vue/tsconfig.json",
    "content": "{\n  \"extends\": \"../../tsconfig.json\"\n}\n"
  },
  {
    "path": "readme.md",
    "content": "[![MDX][githubusercontent-logo]][website]\n\n# Markdown for the component era\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\n[MDX][website] is an authorable format that lets you seamlessly write JSX in\nyour markdown documents.\nYou can import components, such as interactive charts or alerts, and embed them\nwithin your content.\nThis makes writing long-form content with components a blast.\n🚀\n\n```mdx\nimport {Chart} from './snowfall.js'\nexport const year = 2013\n\n# Last year’s snowfall\n\nIn {year}, the snowfall was above average.\nIt was followed by a warm spring which caused\nflood conditions in many of the nearby rivers.\n\n<Chart year={year} color=\"#fcb32c\" />\n```\n\nSee [§ What is MDX](https://mdxjs.com/docs/what-is-mdx/) for more info on the\nformat.\nSee [§ Playground](https://mdxjs.com/playground/) to try it out.\n\n## What is this?\n\nThis GitHub repository contains several packages for compiling the MDX format to\nJavaScript, integrating with bundlers such as webpack and Rollup, and for using\nit with frameworks such as React, Preact, and Vue.\n\nSee [§ Getting started](https://mdxjs.com/getting-started/) for how to\nintegrate MDX into your project.\n\n## Security\n\nSee [§ Security][security] on our site for information.\n\n## Contribute\n\nSee [§ Contribute][contribute] on our site for ways to get started.\nSee [§ Support][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## Sponsor\n\nSee [§ Sponsor][sponsor] on our site for how to help financially.\n\n<table>\n<tr valign=\"middle\">\n<td width=\"20%\" align=\"center\" rowspan=\"2\" colspan=\"2\">\n  <a href=\"https://vercel.com\">Vercel</a><br><br>\n  <a href=\"https://vercel.com\"><img src=\"https://avatars1.githubusercontent.com/u/14985020?s=256&v=4\" width=\"128\"></a>\n</td>\n<td width=\"20%\" align=\"center\" rowspan=\"2\" colspan=\"2\">\n  <a href=\"https://motif.land\">Motif</a><br><br>\n  <a href=\"https://motif.land\"><img src=\"https://avatars1.githubusercontent.com/u/74457950?s=256&v=4\" width=\"128\"></a>\n</td>\n<td width=\"20%\" align=\"center\" rowspan=\"2\" colspan=\"2\">\n  <a href=\"https://www.hashicorp.com\">HashiCorp</a><br><br>\n  <a href=\"https://www.hashicorp.com\"><img src=\"https://avatars1.githubusercontent.com/u/761456?s=256&v=4\" width=\"128\"></a>\n</td>\n<td width=\"20%\" align=\"center\" rowspan=\"2\" colspan=\"2\">\n  <a href=\"https://www.gitbook.com\">GitBook</a><br><br>\n  <a href=\"https://www.gitbook.com\"><img src=\"https://avatars1.githubusercontent.com/u/7111340?s=256&v=4\" width=\"128\"></a>\n</td>\n<td width=\"20%\" align=\"center\" rowspan=\"2\" colspan=\"2\">\n  <a href=\"https://www.gatsbyjs.org\">Gatsby</a><br><br>\n  <a href=\"https://www.gatsbyjs.org\"><img src=\"https://avatars1.githubusercontent.com/u/12551863?s=256&v=4\" width=\"128\"></a>\n</td>\n</tr>\n<tr valign=\"middle\"></tr>\n<tr valign=\"middle\">\n<td width=\"20%\" align=\"center\" rowspan=\"2\" colspan=\"2\">\n  <a href=\"https://www.netlify.com\">Netlify</a><br><br>\n  <!--OC has a sharper image-->\n  <a href=\"https://www.netlify.com\"><img src=\"https://images.opencollective.com/netlify/4087de2/logo/256.png\" width=\"128\"></a>\n</td>\n<td width=\"10%\" align=\"center\">\n  <a href=\"https://www.coinbase.com\">Coinbase</a><br><br>\n  <a href=\"https://www.coinbase.com\"><img src=\"https://avatars1.githubusercontent.com/u/1885080?s=256&v=4\" width=\"64\"></a>\n</td>\n<td width=\"10%\" align=\"center\">\n  <a href=\"https://themeisle.com\">ThemeIsle</a><br><br>\n  <a href=\"https://themeisle.com\"><img src=\"https://avatars1.githubusercontent.com/u/58979018?s=128&v=4\" width=\"64\"></a>\n</td>\n<td width=\"10%\" align=\"center\">\n  <a href=\"https://expo.io\">Expo</a><br><br>\n  <a href=\"https://expo.io\"><img src=\"https://avatars1.githubusercontent.com/u/12504344?s=128&v=4\" width=\"64\"></a>\n</td>\n<td width=\"10%\" align=\"center\">\n  <a href=\"https://boostnote.io\">Boost Note</a><br><br>\n  <a href=\"https://boostnote.io\"><img src=\"https://images.opencollective.com/boosthub/6318083/logo/128.png\" width=\"64\"></a>\n</td>\n<td width=\"10%\" align=\"center\">\n  <a href=\"https://markdown.space\">Markdown Space</a><br><br>\n  <a href=\"https://markdown.space\"><img src=\"https://images.opencollective.com/markdown-space/e1038ed/logo/128.png\" width=\"64\"></a>\n</td>\n<td width=\"10%\" align=\"center\">\n  <a href=\"https://www.holloway.com\">Holloway</a><br><br>\n  <a href=\"https://www.holloway.com\"><img src=\"https://avatars1.githubusercontent.com/u/35904294?s=128&v=4\" width=\"64\"></a>\n</td>\n<td width=\"10%\"></td>\n<td width=\"10%\"></td>\n</tr>\n<tr valign=\"middle\">\n<td width=\"100%\" align=\"center\" colspan=\"8\">\n  <br>\n  <a href=\"https://opencollective.com/unified\"><strong>You?</strong></a>\n  <br><br>\n</td>\n</tr>\n</table>\n\n## License\n\n[MIT][] © Compositor and [Vercel][]\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/mdx-js/mdx/actions\n\n[build-badge]: https://github.com/mdx-js/mdx/workflows/main/badge.svg\n\n[chat]: https://github.com/mdx-js/mdx/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/mdx-js/.github/blob/main/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[contribute]: https://mdxjs.com/community/contribute/\n\n[coverage]: https://codecov.io/github/mdx-js/mdx\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/mdx-js/mdx/main.svg\n\n[githubusercontent-logo]: https://raw.githubusercontent.com/mdx-js/.github/5a63e56/image/cover.svg?sanitize=true\n\n[mit]: license\n\n[security]: https://mdxjs.com/getting-started/#security\n\n[sponsor]: https://mdxjs.com/community/sponsor/\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[support]: https://mdxjs.com/community/support/\n\n[vercel]: https://vercel.com\n\n[website]: https://mdxjs.com\n"
  },
  {
    "path": "renovate.json5",
    "content": "{\n  extends: ['config:base', ':preserveSemverRanges'],\n  schedule: 'before 3am on Monday'\n}\n"
  },
  {
    "path": "script/jsx-loader.js",
    "content": "import fs from 'node:fs/promises'\nimport {fileURLToPath} from 'node:url'\nimport {transform} from 'esbuild'\n\nconst {load} = createLoader()\n\nexport {load}\n\n/**\n * A tiny JSX loader.\n */\nexport function createLoader() {\n  return {load}\n\n  /**\n   * @param {string} href\n   *   URL.\n   * @param {unknown} context\n   *   Context.\n   * @param {Function} defaultLoad\n   *   Default `load`.\n   * @returns\n   *   Result.\n   */\n  async function load(href, context, defaultLoad) {\n    const url = new URL(href)\n\n    if (!url.pathname.endsWith('.jsx')) {\n      return defaultLoad(href, context, defaultLoad)\n    }\n\n    const {code, warnings} = await transform(String(await fs.readFile(url)), {\n      format: 'esm',\n      loader: 'jsx',\n      sourcefile: fileURLToPath(url),\n      sourcemap: 'both',\n      target: 'esnext'\n    })\n\n    if (warnings) {\n      for (const warning of warnings) {\n        console.log(warning.location)\n        console.log(warning.text)\n      }\n    }\n\n    return {format: 'module', shortCircuit: true, source: code}\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"checkJs\": true,\n    \"customConditions\": [\"development\"],\n    \"declaration\": true,\n    \"declarationMap\": true,\n    \"emitDeclarationOnly\": true,\n    \"exactOptionalPropertyTypes\": true,\n    \"jsx\": \"preserve\",\n    \"lib\": [\"es2022\"],\n    \"module\": \"node16\",\n    \"moduleResolution\": \"node16\",\n    // To do: needed for DocSearch for now: <https://github.com/mdx-js/mdx/issues/1776#issuecomment-2349294900>.\n    \"skipLibCheck\": true,\n    \"strict\": true,\n    \"target\": \"es2022\"\n  },\n  \"exclude\": [\"**/coverage/\", \"**/node_modules/\", \"**/public/\"],\n  \"include\": [\n    \"**/*.cjs\",\n    \"**/*.js\",\n    \"**/*.jsx\",\n    \"packages/mdx/lib/types.d.ts\",\n    \"website/types.d.ts\"\n  ]\n}\n"
  },
  {
    "path": "vercel.json",
    "content": "{\n  \"public\": true,\n  \"trailingSlash\": true,\n  \"redirects\": [\n    {\n      \"destination\": \"/community/about/\",\n      \"source\": \"/about/\"\n    },\n    {\n      \"destination\": \"/guides/\",\n      \"source\": \"/advanced/\"\n    },\n    {\n      \"destination\": \"/packages/mdx/#api\",\n      \"source\": \"/advanced/api/\"\n    },\n    {\n      \"destination\": \"/packages/remark-mdx/#syntax-tree\",\n      \"source\": \"/advanced/ast/\"\n    },\n    {\n      \"destination\": \"/docs/using-mdx/\",\n      \"source\": \"/advanced/components/\"\n    },\n    {\n      \"destination\": \"/community/contribute/\",\n      \"source\": \"/advanced/contributing/\"\n    },\n    {\n      \"destination\": \"/guides/frontmatter/\",\n      \"source\": \"/advanced/custom-loader/\"\n    },\n    {\n      \"destination\": \"/docs/extending-mdx/#using-plugins\",\n      \"source\": \"/advanced/retext-plugins/\"\n    },\n    {\n      \"destination\": \"/docs/extending-mdx/\",\n      \"source\": \"/advanced/plugins/\"\n    },\n    {\n      \"destination\": \"/packages/mdx/#evaluatefile-options\",\n      \"source\": \"/advanced/runtime/\"\n    },\n    {\n      \"destination\": \"/packages/remark-mdx/#syntax-tree\",\n      \"source\": \"/advanced/specification/\"\n    },\n    {\n      \"destination\": \"/packages/mdx/#api\",\n      \"source\": \"/advanced/sync-api/\"\n    },\n    {\n      \"destination\": \"/packages/remark-mdx/\",\n      \"source\": \"/advanced/transform-content/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#types\",\n      \"source\": \"/advanced/typescript/\"\n    },\n    {\n      \"destination\": \"/guides/frontmatter/\",\n      \"source\": \"/advanced/writing-a-plugin/\"\n    },\n    {\n      \"destination\": \"/community/contribute/\",\n      \"source\": \"/contributing/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#editor\",\n      \"source\": \"/editor-plugins/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#editor\",\n      \"source\": \"/editors/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#vite\",\n      \"source\": \"/getting-started/create-react-app/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#gatsby\",\n      \"source\": \"/getting-started/gatsby/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#nextjs\",\n      \"source\": \"/getting-started/next/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#parcel\",\n      \"source\": \"/getting-started/parcel/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#vite\",\n      \"source\": \"/getting-started/react-static/\"\n    },\n    {\n      \"destination\": \"/table-of-components/\",\n      \"source\": \"/getting-started/table-of-components/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#types\",\n      \"source\": \"/getting-started/typescript/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#webpack\",\n      \"source\": \"/getting-started/webpack/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/\",\n      \"source\": \"/getting-started/\"\n    },\n    {\n      \"destination\": \"/guides/frontmatter/\",\n      \"source\": \"/guides/custom-loader/\"\n    },\n    {\n      \"destination\": \"/guides/syntax-highlighting/#syntax-highlighting-with-the-meta-field\",\n      \"source\": \"/guides/live-code/\"\n    },\n    {\n      \"destination\": \"/docs/what-is-mdx/\",\n      \"source\": \"/guides/markdown-in-components/\"\n    },\n    {\n      \"destination\": \"/guides/math/\",\n      \"source\": \"/guides/math-blocks/\"\n    },\n    {\n      \"destination\": \"/guides/embed/#embeds-at-run-time\",\n      \"source\": \"/guides/mdx-embed/\"\n    },\n    {\n      \"destination\": \"/docs/extending-mdx/\",\n      \"source\": \"/guides/table-of-contents/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#ink\",\n      \"source\": \"/guides/terminal/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#vue\",\n      \"source\": \"/guides/vue/\"\n    },\n    {\n      \"destination\": \"/docs/using-mdx/#layout\",\n      \"source\": \"/guides/wrapper-customization/\"\n    },\n    {\n      \"destination\": \"/docs/extending-mdx/#creating-plugins\",\n      \"source\": \"/guides/writing-a-plugin/\"\n    },\n    {\n      \"destination\": \"/docs/what-is-mdx/\",\n      \"source\": \"/mdx/\"\n    },\n    {\n      \"destination\": \"/docs/extending-mdx/#using-plugins\",\n      \"source\": \"/plugins/\"\n    },\n    {\n      \"destination\": \"/community/projects/\",\n      \"source\": \"/projects/\"\n    },\n    {\n      \"destination\": \"/community/support/\",\n      \"source\": \"/support/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#syntax\",\n      \"source\": \"/syntax/\"\n    },\n    {\n      \"destination\": \"/docs/getting-started/#vue\",\n      \"source\": \"/vue/\"\n    }\n  ]\n}\n"
  },
  {
    "path": "website/generate.js",
    "content": "#!/usr/bin/env node\n/**\n * @import {Element, Properties, Root} from 'hast'\n * @import {MDXContent} from 'mdx/types.js'\n * @import {DataMapMatter, DataMapMeta} from 'vfile'\n * @import {Item} from '../docs/_component/sort.js'\n */\n\n/**\n * @typedef Author\n *   Author.\n * @property {string | undefined} [github]\n *   GitHub handle (optional).\n * @property {string} name\n *   Name.\n * @property {string | undefined} [url]\n *   URL (optional).\n *\n * @typedef Info\n *   Info.\n * @property {Array<Readonly<Author>> | Readonly<Author> | undefined} [author]\n *   Author(s) (optional);\n *   note: mutable because `isArray` casts to any.\n * @property {Date | undefined} [published]\n *   Published date (optional).\n * @property {Date | undefined} [modified]\n *   Modified date (optional).\n */\n\nimport assert from 'node:assert'\nimport fs from 'node:fs/promises'\nimport {fileURLToPath} from 'node:url'\nimport structuredClone from '@ungap/structured-clone'\nimport {globby} from 'globby'\nimport {h} from 'hastscript'\nimport {sanitize} from 'hast-util-sanitize'\nimport {select} from 'hast-util-select'\nimport pAll from 'p-all'\nimport React from 'react'\nimport {renderToString} from 'react-dom/server'\nimport rehypeDocument from 'rehype-document'\nimport rehypeMeta from 'rehype-meta'\nimport rehypeMinifyUrl from 'rehype-minify-url'\nimport rehypeParse from 'rehype-parse'\nimport rehypePresetMinify from 'rehype-preset-minify'\nimport rehypeStringify from 'rehype-stringify'\nimport {unified} from 'unified'\nimport {VFile} from 'vfile'\nimport {sitemap} from 'xast-util-sitemap'\nimport {toXml} from 'xast-util-to-xml'\nimport {Layout} from '../docs/_component/layout.jsx'\nimport {config} from '../docs/_config.js'\nimport {schema} from './schema-description.js'\n\nimport {register} from 'node:module'\n\nregister('./mdx-loader.js', import.meta.url)\n\nconst listFormat = new Intl.ListFormat('en')\n\nconst filePaths = await globby(['**/*.{md,mdx}', '!_component/*'], {\n  cwd: fileURLToPath(config.input)\n})\nconst files = filePaths.map(function (d) {\n  return new URL(d, config.input)\n})\n\nconst allInfo = await pAll(\n  files.map(function (url) {\n    return async function () {\n      const name = url.href\n        .slice(config.input.href.length - 1)\n        .replace(/\\.mdx?$/, '/')\n        .replace(/\\/index\\/$/, '/')\n      const jsonUrl = new URL('.' + name + 'index.json', config.output)\n      const ghUrl = new URL(\n        url.href.slice(config.git.href.length),\n        config.ghBlob\n      )\n\n      /** @type {{default: MDXContent, info?: Info, matter: DataMapMatter, meta: DataMapMeta, navExclude?: boolean | undefined, navSortSelf?: number | undefined}} */\n      const imported = await import(url.href)\n      const {default: Content, info, ...data} = imported\n      // Handle `author` differently.\n      const {author, ...restInfo} = info || {}\n      const authors = Array.isArray(author) ? author : author ? [author] : []\n      const authorNames = authors.map(function (d) {\n        return d.name\n      })\n\n      const abbreviatedAuthors =\n        authorNames.length > 3\n          ? [...authorNames.slice(0, 2), 'others']\n          : authorNames\n\n      data.meta = {\n        ...restInfo,\n        author:\n          abbreviatedAuthors.length > 0\n            ? listFormat.format(abbreviatedAuthors)\n            : undefined,\n        ...data.meta,\n        authors\n      }\n\n      // Sanitize the hast description:\n      if (data.meta && data.meta.descriptionHast) {\n        // Cast because we get a root back.\n        data.meta.descriptionHast = /** @type {Root} */ (\n          sanitize(data.meta.descriptionHast, schema)\n        )\n      }\n\n      return {Content, data, ghUrl, jsonUrl, name, url}\n    }\n  }),\n  {concurrency: 6}\n)\n\n/** @type {Item} */\nconst navigationTree = {name: '/', data: {}, children: []}\nlet index = -1\n\nwhile (++index < allInfo.length) {\n  const {data, name} = allInfo[index]\n  const parts = name.split('/').slice(0, -1)\n  let partIndex = 0\n  let context = navigationTree\n\n  if (data.navExclude) continue\n\n  while (++partIndex < parts.length) {\n    const name = parts.slice(0, partIndex + 1).join('/') + '/'\n    let contextItem = context.children.find(function (d) {\n      return d.name === name\n    })\n\n    if (!contextItem) {\n      contextItem = {name, data: {}, children: []}\n      context.children.push(contextItem)\n    }\n\n    context = contextItem\n  }\n\n  context.data = data\n}\n\nawait fs.writeFile(\n  new URL('sitemap.xml', config.output),\n  toXml(\n    sitemap(\n      allInfo.map(function (d) {\n        return {\n          lang: 'en',\n          modified: d.data && d.data.meta && d.data.meta.modified,\n          url: new URL(d.name, config.site).href\n        }\n      })\n    )\n  )\n)\n\nconsole.log('✔ `/sitemap.xml`')\n\nindex = -1\n\nawait pAll(\n  allInfo.map(function (d) {\n    return async function () {\n      const {Content, data, ghUrl, jsonUrl, name} = d\n\n      await fs.mkdir(new URL('./', jsonUrl), {recursive: true})\n      await fs.writeFile(jsonUrl, JSON.stringify(data))\n\n      const element = React.createElement(Content, {\n        ...data,\n        components: {wrapper: Layout},\n        ghUrl,\n        name,\n        navigationTree\n      })\n\n      const result = renderToString(element)\n\n      const canonical = new URL(name, config.site)\n      data.meta.origin = canonical.origin\n      data.meta.pathname = canonical.pathname\n\n      const file = await unified()\n        .use(rehypeParse, {fragment: true})\n        .use(rehypeDocument, {\n          css: ['/index.css', 'https://esm.sh/@docsearch/css@3/dist/style.css'],\n          // Idea: only include editor on playground? Use more editors.\n          js: ['/index.js', '/editor.js'],\n          language: 'en',\n          link: [\n            {\n              href: new URL('rss.xml', config.site).href,\n              rel: 'alternate',\n              title: config.site.hostname,\n              type: 'application/rss+xml'\n            },\n            {\n              href: new URL('favicon.ico', config.site).href,\n              rel: 'icon',\n              sizes: 'any'\n            },\n            {\n              href: new URL('icon.svg', config.site).href,\n              rel: 'icon',\n              type: 'image/svg+xml'\n            }\n          ],\n          meta: [{content: 'mdx', name: 'generator'}]\n        })\n        .use(rehypeMeta, {\n          color: config.color,\n          copyright: true,\n          image:\n            name === '/'\n              ? {\n                  height: 1490,\n                  url: new URL('og.png', config.site).href,\n                  width: 3062\n                }\n              : {\n                  height: 1256,\n                  url:\n                    name === '/blog/v2/' || name === '/migrating/v2/'\n                      ? new URL('og-v2.png', config.site).href\n                      : new URL('index.png', canonical).href,\n                  width: 2400\n                },\n          name: config.title,\n          og: true,\n          ogNameInTitle: true,\n          separator: ' | ',\n          siteAuthor: config.author,\n          siteTags: config.tags,\n          type: 'article'\n        })\n        .use(rehypeLazyCss, [\n          {href: 'https://esm.sh/@wooorm/starry-night@3/style/both.css'}\n        ])\n        .use(rehypePresetMinify)\n        .use(rehypeMinifyUrl, {from: canonical.href})\n        .use(rehypeStringify)\n        .process(\n          new VFile({\n            data,\n            path: new URL('index.html', jsonUrl),\n            value: result\n          })\n        )\n\n      if (file.dirname) await fs.mkdir(file.dirname, {recursive: true})\n      await fs.writeFile(file.path, String(file))\n      console.log('  generate: `%s`', name)\n    }\n  }),\n  {concurrency: 6}\n)\n\nconsole.log('✔ Generate')\n\n/**\n * @param {ReadonlyArray<Readonly<Properties>>} styles\n *   Styles.\n * @returns\n *   Transform.\n */\nfunction rehypeLazyCss(styles) {\n  /**\n   * @param {Root} tree\n   *   Styles.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree) {\n    const head = select('head', tree)\n    assert.ok(head)\n    /** @type {Array<Element>} */\n    const enabled = []\n    /** @type {Array<Element>} */\n    const disabled = []\n\n    let index = -1\n    while (++index < styles.length) {\n      const properties = styles[index]\n      enabled.push(\n        h('link', {\n          ...structuredClone(properties),\n          as: 'style',\n          onLoad: \"this.onload=undefined;this.rel='stylesheet'\",\n          rel: 'preload'\n        })\n      )\n      disabled.push(\n        h('link', {...structuredClone(properties), rel: 'stylesheet'})\n      )\n    }\n\n    head.children.push(...enabled)\n\n    if (disabled.length > 0) {\n      head.children.push(h('noscript', disabled))\n    }\n  }\n}\n"
  },
  {
    "path": "website/mdx-loader.js",
    "content": "/**\n * @import {CompileOptions} from '@mdx-js/mdx'\n * @import {Program} from 'estree'\n * @import {ElementContent, Root} from 'hast'\n * @import {VFile} from 'vfile'\n */\n\n/**\n * @typedef MetaOptions\n *   Configuration.\n * @property {ReadonlyArray<string> | null | undefined} [include]\n *   List of keys to include (optional).\n * @property {ReadonlyArray<string> | null | undefined} [exclude]\n *   List of keys to exclude (optional).\n */\n\nimport assert from 'node:assert/strict'\nimport {fileURLToPath, pathToFileURL} from 'node:url'\nimport {createLoader} from '@mdx-js/node-loader'\nimport {nodeTypes} from '@mdx-js/mdx'\nimport {common} from '@wooorm/starry-night'\nimport sourceMdx from '@wooorm/starry-night/source.mdx'\nimport sourceToml from '@wooorm/starry-night/source.toml'\nimport sourceTsx from '@wooorm/starry-night/source.tsx'\nimport {createVisitors} from 'estree-util-scope'\nimport {valueToEstree} from 'estree-util-value-to-estree'\nimport {walk} from 'estree-walker'\nimport {h, s} from 'hastscript'\nimport {toText} from 'hast-util-to-text'\nimport rehypeAutolinkHeadings from 'rehype-autolink-headings'\nimport rehypeInferDescriptionMeta from 'rehype-infer-description-meta'\nimport rehypeInferReadingTimeMeta from 'rehype-infer-reading-time-meta'\nimport rehypeInferTitleMeta from 'rehype-infer-title-meta'\nimport rehypeMinifyUrl from 'rehype-minify-url'\nimport rehypePresetMinify from 'rehype-preset-minify'\nimport rehypeRaw from 'rehype-raw'\nimport rehypeShiftHeading from 'rehype-shift-heading'\nimport rehypeSlug from 'rehype-slug'\nimport rehypeStarryNight from 'rehype-starry-night'\nimport rehypeTwoslash from 'rehype-twoslash'\nimport remarkFrontmatter from 'remark-frontmatter'\nimport remarkGemoji from 'remark-gemoji'\nimport remarkGfm from 'remark-gfm'\nimport remarkGithub from 'remark-github'\nimport remarkMdxFrontmatter from 'remark-mdx-frontmatter'\nimport remarkSqueezeParagraphs from 'remark-squeeze-paragraphs'\nimport remarkStripBadges from 'remark-strip-badges'\nimport remarkToc from 'remark-toc'\nimport {visit} from 'unist-util-visit'\nimport typescript from 'typescript'\nimport {config} from '../docs/_config.js'\n\nconst configPath = typescript.findConfigFile(\n  fileURLToPath(import.meta.url),\n  typescript.sys.fileExists,\n  'tsconfig.json'\n)\nassert.ok(configPath)\nconst commandLine = typescript.getParsedCommandLineOfConfigFile(\n  configPath,\n  undefined,\n  {\n    fileExists: typescript.sys.fileExists,\n    getCurrentDirectory: typescript.sys.getCurrentDirectory,\n    onUnRecoverableConfigFileDiagnostic(x) {\n      console.warn('Unrecoverable diagnostic', x)\n    },\n    readDirectory: typescript.sys.readDirectory,\n    readFile: typescript.sys.readFile,\n    useCaseSensitiveFileNames: typescript.sys.useCaseSensitiveFileNames\n  }\n)\nassert.ok(commandLine)\n\n/** @type {Readonly<CompileOptions>} */\nconst options = {\n  recmaPlugins: [recmaInjectMeta],\n  rehypePlugins: [\n    rehypePrettyCodeBlocks,\n    [rehypeRaw, {passThrough: nodeTypes}],\n    unifiedInferRemoteMeta,\n    [\n      rehypeInferDescriptionMeta,\n      {inferDescriptionHast: true, truncateSize: 280}\n    ],\n    rehypeInferReadingTimeMeta,\n    rehypeInferTitleMeta,\n    [rehypeShiftHeading, {shift: 1}],\n    rehypeSlug,\n    [\n      rehypeAutolinkHeadings,\n      {\n        behavior: 'prepend',\n        content: link(),\n        properties: {ariaLabel: 'Link to this section', className: ['anchor']}\n      }\n    ],\n    [\n      rehypeStarryNight,\n      {\n        grammars: [...common, sourceMdx, sourceToml, sourceTsx],\n        plainText: ['mdx-invalid', 'text']\n      }\n    ],\n    [rehypeTwoslash, {twoslash: {compilerOptions: commandLine.options}}],\n    rehypePresetMinify,\n    rehypeMinifyUrl\n  ],\n  remarkPlugins: [\n    remarkFrontmatter,\n    remarkGemoji,\n    remarkGfm,\n    remarkGithub,\n    [remarkMdxFrontmatter, {name: 'matter'}],\n    remarkStripBadges,\n    remarkSqueezeParagraphs,\n    [remarkToc, {maxDepth: 3}]\n  ]\n}\n\nconst {initialize, load} = createLoader(options)\n\nexport {initialize, load}\n\nfunction link() {\n  return s(\n    'svg.icon',\n    {\n      ariaHidden: 'true',\n      viewBox: [0, 0, 16, 16],\n      focusable: false,\n      width: 18,\n      height: 18\n    },\n    s('path', {\n      fill: 'currentcolor',\n      d: 'M7.775 3.275C7.64252 3.41717 7.57039 3.60522 7.57382 3.79952C7.57725 3.99382 7.65596 4.1792 7.79337 4.31662C7.93079 4.45403 8.11617 4.53274 8.31047 4.53617C8.50477 4.5396 8.69282 4.46748 8.835 4.335L10.085 3.085C10.2708 2.89918 10.4914 2.75177 10.7342 2.65121C10.977 2.55064 11.2372 2.49888 11.5 2.49888C11.7628 2.49888 12.023 2.55064 12.2658 2.65121C12.5086 2.75177 12.7292 2.89918 12.915 3.085C13.1008 3.27082 13.2482 3.49142 13.3488 3.7342C13.4493 3.97699 13.5011 4.23721 13.5011 4.5C13.5011 4.76279 13.4493 5.023 13.3488 5.26579C13.2482 5.50857 13.1008 5.72917 12.915 5.915L10.415 8.415C10.2292 8.60095 10.0087 8.74847 9.76588 8.84911C9.52308 8.94976 9.26283 9.00157 9 9.00157C8.73716 9.00157 8.47691 8.94976 8.23411 8.84911C7.99132 8.74847 7.77074 8.60095 7.585 8.415C7.44282 8.28252 7.25477 8.21039 7.06047 8.21382C6.86617 8.21725 6.68079 8.29596 6.54337 8.43337C6.40596 8.57079 6.32725 8.75617 6.32382 8.95047C6.32039 9.14477 6.39252 9.33282 6.525 9.475C6.85001 9.80004 7.23586 10.0579 7.66052 10.2338C8.08518 10.4097 8.54034 10.5002 9 10.5002C9.45965 10.5002 9.91481 10.4097 10.3395 10.2338C10.7641 10.0579 11.15 9.80004 11.475 9.475L13.975 6.975C14.6314 6.31858 15.0002 5.4283 15.0002 4.5C15.0002 3.57169 14.6314 2.68141 13.975 2.025C13.3186 1.36858 12.4283 0.999817 11.5 0.999817C10.5717 0.999817 9.68141 1.36858 9.02499 2.025L7.775 3.275ZM3.085 12.915C2.89904 12.7292 2.75152 12.5087 2.65088 12.2659C2.55023 12.0231 2.49842 11.7628 2.49842 11.5C2.49842 11.2372 2.55023 10.9769 2.65088 10.7341C2.75152 10.4913 2.89904 10.2707 3.085 10.085L5.585 7.585C5.77074 7.39904 5.99132 7.25152 6.23411 7.15088C6.47691 7.05023 6.73716 6.99842 7 6.99842C7.26283 6.99842 7.52308 7.05023 7.76588 7.15088C8.00867 7.25152 8.22925 7.39904 8.415 7.585C8.55717 7.71748 8.74522 7.7896 8.93952 7.78617C9.13382 7.78274 9.3192 7.70403 9.45662 7.56662C9.59403 7.4292 9.67274 7.24382 9.67617 7.04952C9.6796 6.85522 9.60748 6.66717 9.475 6.525C9.14999 6.19995 8.76413 5.94211 8.33947 5.7662C7.91481 5.59029 7.45965 5.49974 7 5.49974C6.54034 5.49974 6.08518 5.59029 5.66052 5.7662C5.23586 5.94211 4.85001 6.19995 4.525 6.525L2.025 9.02499C1.36858 9.68141 0.999817 10.5717 0.999817 11.5C0.999817 12.4283 1.36858 13.3186 2.025 13.975C2.68141 14.6314 3.57169 15.0002 4.5 15.0002C5.4283 15.0002 6.31858 14.6314 6.975 13.975L8.225 12.725C8.35748 12.5828 8.4296 12.3948 8.42617 12.2005C8.42274 12.0062 8.34403 11.8208 8.20662 11.6834C8.0692 11.546 7.88382 11.4672 7.68952 11.4638C7.49522 11.4604 7.30717 11.5325 7.165 11.665L5.915 12.915C5.72925 13.1009 5.50867 13.2485 5.26588 13.3491C5.02308 13.4498 4.76283 13.5016 4.5 13.5016C4.23716 13.5016 3.97691 13.4498 3.73411 13.3491C3.49132 13.2485 3.27074 13.1009 3.085 12.915Z'\n    })\n  )\n}\n\n/**\n * @returns\n *   Transform.\n */\nfunction unifiedInferRemoteMeta() {\n  /**\n   * @param {Root} _\n   *   Tree.\n   * @param {VFile} file\n   *   File.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (_, file) {\n    const meta = file.data.meta || (file.data.meta = {})\n\n    const fileUrl = pathToFileURL(file.path)\n    const parts = fileUrl.href.slice(config.git.href.length - 1).split('/')\n    /** @type {string} */\n    let fp\n\n    if (parts[1] === 'docs') {\n      fp = ('/' + parts.slice(2).join('/'))\n        .replace(/\\.mdx$/, '/')\n        .replace(/\\/index\\/$/, '/')\n    } else {\n      // Symlinks, which we have to hack around.\n      if (parts[1] !== 'packages' || parts.at(-1) !== 'readme.md') {\n        throw new Error(\n          'Expected symlinked file to match `/packages/*/readme.md`'\n        )\n      }\n\n      fp = parts.slice(0, -1).join('/') + '/'\n    }\n\n    const url = new URL(fp, config.site)\n\n    meta.origin = url.origin\n    meta.pathname = url.pathname\n  }\n}\n\n/**\n * @param {Readonly<MetaOptions> | null | undefined} [options]\n *   Configuration (optional).\n * @returns\n *   Transform.\n */\nfunction recmaInjectMeta(options) {\n  const {exclude, include} = options || {}\n  /**\n   * @param {Program} tree\n   *   Tree.\n   * @param {VFile} file\n   *   File.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree, file) {\n    // Find everything that’s defined in the top-level scope.\n    const visitors = createVisitors()\n    walk(tree, {\n      enter(node) {\n        visitors.enter(node)\n\n        if (\n          node.type === 'ArrowFunctionExpression' ||\n          node.type === 'FunctionDeclaration' ||\n          node.type === 'FunctionExpression'\n        ) {\n          this.skip()\n          visitors.exit(node) // Call the exit handler manually.\n        }\n      },\n      leave: visitors.exit\n    })\n    const topScope = visitors.scopes[0]\n\n    // Exit if `meta` is already defined.\n    if (topScope.defined.includes('meta')) return\n\n    // Treat as arbitrary object.\n    const meta = /** @type {Record<string, unknown>} */ (file.data.meta || {})\n    /** @type {Record<string, unknown>} */\n    const value = {}\n    /** @type {string} */\n    let key\n\n    for (key in meta) {\n      if (\n        Object.hasOwn(meta, key) &&\n        (!exclude || !exclude.includes(key)) &&\n        (!include || include.includes(key))\n      ) {\n        value[key] = meta[key]\n      }\n    }\n\n    tree.body.unshift({\n      type: 'ExportNamedDeclaration',\n      declaration: {\n        type: 'VariableDeclaration',\n        kind: 'const',\n        declarations: [\n          {\n            type: 'VariableDeclarator',\n            id: {type: 'Identifier', name: 'meta'},\n            init: valueToEstree(value, {instanceAsObject: true})\n          }\n        ]\n      },\n      source: undefined,\n      attributes: [],\n      specifiers: []\n    })\n  }\n}\n\nfunction rehypePrettyCodeBlocks() {\n  const re = /\\b([-\\w]+)(?:=(?:\"([^\"]*)\"|'([^']*)'|([^\"'\\s]+)))?/g\n\n  /** @type {Readonly<Record<string, string>>} */\n  const languageNames = {\n    diff: 'Diff',\n    html: 'HTML',\n    js: 'JavaScript',\n    jsx: 'JavaScript',\n    md: 'Markdown',\n    mdx: 'MDX',\n    sh: 'Shell',\n    text: 'Plain text',\n    ts: 'TypeScript',\n    tsx: 'TypeScript'\n  }\n\n  /**\n   * @param {Root} tree\n   *   Tree.\n   * @returns {undefined}\n   *   Nothing.\n   */\n  return function (tree) {\n    visit(tree, 'element', function (node, index, parent) {\n      if (node.tagName !== 'pre' || !parent || index === undefined) {\n        return\n      }\n\n      const code = node.children[0]\n\n      if (\n        !code ||\n        code.type !== 'element' ||\n        code.tagName !== 'code' ||\n        node.children.length > 1\n      ) {\n        return\n      }\n\n      /** @type {Record<string, string>} */\n      const metaProperties = {}\n      const meta = code.data?.meta\n\n      if (meta) {\n        /** @type {RegExpMatchArray | null} */\n        let match\n        re.lastIndex = 0 // Reset regex.\n\n        while ((match = re.exec(meta))) {\n          metaProperties[match[1]] = match[2] || match[3] || match[4] || ''\n        }\n      }\n\n      const className = Array.isArray(code.properties.className)\n        ? code.properties.className\n        : (code.properties.className = [])\n\n      if (metaProperties.twoslash === '') {\n        className.push('twoslash')\n      }\n\n      if (metaProperties.chrome === 'no') {\n        return\n      }\n\n      const textContent = toText(node)\n      /** @type {Array<ElementContent>} */\n      const children = [node]\n      const lang = className.find(function (value) {\n        return String(value).slice(0, 9) === 'language-'\n      })\n      /** @type {Array<ElementContent>} */\n      const footer = []\n      /** @type {Array<ElementContent>} */\n      const header = []\n      const language = lang ? String(lang).slice(9) : undefined\n\n      // Not giant.\n      if (textContent.length < 8192 && metaProperties.copy !== 'no') {\n        footer.push({\n          type: 'element',\n          tagName: 'button',\n          properties: {\n            className: ['copy-button'],\n            dataValue: textContent\n          },\n          children: []\n        })\n      }\n\n      if (metaProperties.path) {\n        header.push(\n          h('span.frame-tab-item.frame-tab-item-selected', metaProperties.path)\n        )\n      } else if (language) {\n        if (!Object.hasOwn(languageNames, language)) {\n          console.log(\n            '[mdx-config]: warn: please add %s to have a nice language name',\n            language\n          )\n        }\n\n        header.push(\n          h(\n            'span.frame-tab-item.frame-tab-item-language.frame-tab-item-inactive',\n            languageNames[language] || language\n          )\n        )\n      }\n\n      if (header && header.length > 0) {\n        children.unshift(h('.frame-tab-bar.frame-tab-bar-scroll', header))\n      }\n\n      if (footer && footer.length > 0) {\n        children.push(...footer)\n      }\n\n      parent.children[index] = h('.frame.code-frame', children)\n    })\n  }\n}\n"
  },
  {
    "path": "website/post.js",
    "content": "/**\n * @import {Stats} from 'node:fs'\n * @import {DataMapMatter, DataMapMeta} from 'vfile'\n * @import {Entry} from 'xast-util-feed'\n */\n\n/**\n * @typedef Info\n *   Info.\n * @property {Readonly<DataMapMeta>} meta\n *   Meta.\n * @property {Readonly<DataMapMatter>} matter\n *   Matter.\n * @property {boolean | undefined} [navExclude=false]\n *   Whether to exclude from the navigation (default: `false`).\n * @property {number | undefined} [navSortSelf=0]\n *   Self sort order (default: `0`).\n */\n\nimport assert from 'node:assert'\nimport fs from 'node:fs/promises'\nimport process from 'node:process'\nimport {fileURLToPath} from 'node:url'\nimport chromium from '@sparticuz/chromium'\nimport {globby} from 'globby'\nimport {fromHtml} from 'hast-util-from-html'\nimport {sanitize, defaultSchema} from 'hast-util-sanitize'\nimport {select} from 'hast-util-select'\nimport {toHtml} from 'hast-util-to-html'\nimport {h, s} from 'hastscript'\nimport pAll from 'p-all'\nimport puppeteer from 'puppeteer'\nimport {rss} from 'xast-util-feed'\nimport {toXml} from 'xast-util-to-xml'\nimport {config} from '../docs/_config.js'\nimport {schema} from './schema-description.js'\n\nconst dateTimeFormat = new Intl.DateTimeFormat('en', {dateStyle: 'long'})\n\nfs.copyFile(\n  new URL('404/index.html', config.output),\n  new URL('404.html', config.output)\n)\nconsole.log('✔ `/404/index.html` -> `/404.html`')\n\nconst css = await fs.readFile(\n  new URL('../docs/_asset/index.css', import.meta.url),\n  'utf8'\n)\n\nconst filePaths = await globby('**/index.json', {\n  cwd: fileURLToPath(config.output)\n})\nconst files = filePaths.map(function (d) {\n  return new URL(d, config.output)\n})\n\nconst allInfo = await Promise.all(\n  files.map(async function (url) {\n    /** @type {Info} */\n    const info = JSON.parse(String(await fs.readFile(url)))\n    return {info, url}\n  })\n)\n\n// RSS feed.\nconst now = new Date()\n\nconst entries = await pAll(\n  [...allInfo]\n    // All blog entries that are published in the past.\n    .filter(function (d) {\n      return (\n        d.info.meta.pathname &&\n        d.info.meta.pathname.startsWith('/blog/') &&\n        d.info.meta.pathname !== '/blog/' &&\n        d.info.meta.published !== null &&\n        d.info.meta.published !== undefined &&\n        new Date(d.info.meta.published) < now\n      )\n    })\n    // Sort.\n    .sort(function (a, b) {\n      assert.ok(a.info.meta.published)\n      assert.ok(b.info.meta.published)\n      return (\n        new Date(b.info.meta.published).valueOf() -\n        new Date(a.info.meta.published).valueOf()\n      )\n    })\n    // Ten most recently published articles.\n    .slice(0, 10)\n    .map(function ({info, url}) {\n      /**\n       * @returns {Promise<Entry>}\n       *   Entry.\n       */\n      return async function () {\n        const buf = await fs.readFile(new URL('index.html', url))\n        const tree = fromHtml(buf)\n        const body = select('.body', tree)\n        assert.ok(body)\n        const clean = sanitize(body, {\n          ...defaultSchema,\n          attributes: {\n            ...defaultSchema.attributes,\n            code: [\n              [\n                'className',\n                'language-diff',\n                'language-html',\n                'language-js',\n                'language-jsx',\n                'language-md',\n                'language-mdx',\n                'language-sh',\n                'language-ts'\n              ]\n            ]\n          },\n          clobber: []\n        })\n\n        return {\n          author: info.meta.author,\n          description: info.meta.description,\n          descriptionHtml: toHtml(clean),\n          modified: info.meta.modified,\n          published: info.meta.published,\n          title: info.meta.title,\n          url: new URL(\n            url.href.slice(config.output.href.length - 1) + '/../',\n            config.site\n          ).href\n        }\n      }\n    }),\n  {concurrency: 6}\n)\n\nawait fs.writeFile(\n  new URL('rss.xml', config.output),\n  toXml(\n    rss(\n      {\n        author: config.author,\n        description: 'MDX updates',\n        feedUrl: new URL('rss.xml', config.site).href,\n        lang: 'en',\n        tags: config.tags,\n        title: config.title,\n        url: config.site.href\n      },\n      entries\n    )\n  ) + '\\n'\n)\n\nconsole.log('✔ `/rss.xml`')\n\nawait fs.writeFile(new URL('CNAME', config.output), config.site.host + '\\n')\n\nconsole.log('✔ `/CNAME`')\n\nchromium.setGraphicsMode = false\n\nconst browser = await puppeteer.launch(\n  process.env.AWS_EXECUTION_ENV\n    ? {\n        // See: <https://github.com/Sparticuz/chromium/issues/85#issuecomment-1527692751>\n        args: [...chromium.args, '--disable-gpu'],\n        executablePath: await chromium.executablePath(),\n        headless: true\n      }\n    : {headless: true}\n)\n\nawait pAll(\n  allInfo.map(function (data) {\n    return async function () {\n      const {url, info} = data\n      const output = new URL('index.png', url)\n      /** @type {Stats | undefined} */\n      let stats\n\n      try {\n        stats = await fs.stat(output)\n      } catch (error) {\n        const cause = /** @type {NodeJS.ErrnoException} */ (error)\n        if (cause.code !== 'ENOENT') throw cause\n      }\n\n      // Don’t regenerate to improve performance.\n      if (stats) return\n\n      const value = toHtml({\n        type: 'root',\n        children: [\n          {type: 'doctype'},\n          h('html', {lang: 'en'}, [\n            h('head', [\n              h('meta', {charSet: 'utf8'}),\n              h('title', 'Generated image'),\n              h('style', css),\n              h(\n                'style',\n                `\n                html {\n                  font-size: 24px;\n                }\n\n                body {\n                  /* yellow */\n                  background-image: radial-gradient(\n                      ellipse at 0% 0%,\n                      rgb(252 180 45 / 15%) 20%,\n                      rgb(252 180 45 / 0%) 80%\n                    ),\n                    /* purple */\n                      radial-gradient(\n                        ellipse at 0% 100%,\n                        rgb(130 80 223 / 15%) 20%,\n                        rgb(130 80 223 / 0%) 80%\n                      );\n                }\n\n                .og-root {\n                  height: calc(100vh - calc(2 * (1em + 1ex)));\n                  display: flex;\n                  flex-flow: column;\n                  margin-block: calc(1 * (1em + 1ex));\n                  padding-block: calc(1 * (1em + 1ex));\n                  padding-inline: calc(1 * (1em + 1ex));\n                  background-color: var(--bg);\n                }\n\n                .og-head {\n                  margin-block-end: calc(2 * (1em + 1ex));\n                }\n\n                .og-icon {\n                  display: block;\n                  height: calc(1em + 1ex);\n                  width: auto;\n                  vertical-align: middle;\n                }\n\n                .og-title {\n                  font-size: 3rem;\n                  line-height: calc(1em + (1 / 3 * 1ex));\n                  margin-block: 0;\n                  overflow: hidden;\n                  text-overflow: ellipsis;\n                  white-space: nowrap;\n                  flex-shrink: 0;\n                }\n\n                .og-description {\n                  flex-grow: 1;\n                  overflow: hidden;\n                }\n\n                .og-description-inside {\n                  -webkit-line-clamp: 2;\n                  -webkit-box-orient: vertical;\n                  display: -webkit-box;\n                  overflow: hidden;\n                }\n\n                .og-meta {\n                  flex-shrink: 0;\n                  margin-top: calc(1em + 1ex);\n                  display: flex;\n                  justify-content: space-between;\n                }\n\n                .og-right {\n                  margin-left: auto;\n                  text-align: right;\n                }\n            `\n              )\n            ]),\n            h('body', [\n              h('.og-root', [\n                h('.og-head', [\n                  s(\n                    'svg.og-icon.og-icon-mdx',\n                    {height: 28.5, width: 69, viewBox: '0 0 138 57'},\n                    [\n                      s('rect', {\n                        fill: 'var(--fg)',\n                        height: 55.5,\n                        rx: 4.5,\n                        width: 136.5,\n                        x: 0.75,\n                        y: 0.75\n                      }),\n                      s(\n                        'g',\n                        {fill: 'none', stroke: 'var(--bg)', strokeWidth: 6},\n                        [\n                          s('path', {\n                            d: 'M16.5 44V19L30.25 32.75l14-14v25'\n                          }),\n                          s('path', {d: 'M70.5 40V10.75'}),\n                          s('path', {d: 'M57 27.25L70.5 40.75l13.5-13.5'}),\n                          s('path', {\n                            d: 'M122.5 41.24L93.25 12M93.5 41.25L122.75 12'\n                          })\n                        ]\n                      )\n                    ]\n                  )\n                ]),\n                h('h2.og-title', info.meta.title),\n                h('.og-description', [\n                  h('.og-description-inside', [\n                    info.meta.descriptionHast\n                      ? sanitize(info.meta.descriptionHast, schema)\n                      : info.meta.description || info.matter.description\n                  ])\n                ]),\n                h('.og-meta', [\n                  h('.og-left', [\n                    h('small', 'By'),\n                    h('br'),\n                    h('b', info.meta.author || 'MDX contributors')\n                  ]),\n                  info.meta.modified\n                    ? h('.og-right', [\n                        h('small', 'Last modified on'),\n                        h('br'),\n                        h(\n                          'b',\n                          dateTimeFormat.format(new Date(info.meta.modified))\n                        )\n                      ])\n                    : undefined\n                ])\n              ])\n            ])\n          ])\n        ]\n      })\n\n      try {\n        await fs.unlink(output)\n      } catch {}\n\n      const page = await browser.newPage()\n      // This is doubled in the actual file dimensions.\n      await page.setViewport({deviceScaleFactor: 2, height: 628, width: 1200})\n      await page.emulateMediaFeatures([\n        {name: 'prefers-color-scheme', value: 'light'}\n      ])\n      await page.setContent(value)\n      const screenshot = await page.screenshot()\n      await page.close()\n\n      await fs.writeFile(output, screenshot)\n\n      console.log('OG image `%s`', info.meta.title)\n    }\n  }),\n  {concurrency: 4}\n)\n\nawait browser.close()\n\nconsole.log('✔ OG images')\n"
  },
  {
    "path": "website/prep.js",
    "content": "#!/usr/bin/env node\n/**\n * @import {Root} from 'hast'\n */\n\nimport fs from 'node:fs/promises'\nimport {fileURLToPath} from 'node:url'\nimport {globby} from 'globby'\nimport {h} from 'hastscript'\nimport pAll from 'p-all'\nimport rehypeMinifyUrl from 'rehype-minify-url'\nimport rehypePresetMinify from 'rehype-preset-minify'\nimport rehypeStringify from 'rehype-stringify'\nimport {unified} from 'unified'\nimport {VFile} from 'vfile'\nimport {config, redirect} from '../docs/_config.js'\n\nawait fs.mkdir(config.output, {recursive: true})\n\nconst from = new URL('_static/', config.input)\nconst files = await globby('**/*', {cwd: fileURLToPath(from)})\n\nawait pAll(\n  files.map(function (d) {\n    return async function () {\n      return fs.copyFile(new URL(d, from), new URL(d, config.output))\n    }\n  }),\n  {concurrency: 6}\n)\n\nconsole.log('✔ `/_static/*`')\n\nawait fs.writeFile(\n  new URL('robots.txt', config.output),\n  [\n    'User-agent: *',\n    'Allow: /',\n    'Sitemap: ' + new URL('sitemap.xml', config.site),\n    ''\n  ].join('\\n')\n)\n\nconsole.log('✔ `/robots.txt`')\n\nawait pAll(\n  Object.keys(redirect).map(function (from) {\n    return async function () {\n      const to = redirect[from]\n      const canonical = new URL(from + '/../', config.site).href\n      const processor = unified()\n        .use(rehypePresetMinify)\n        .use(rehypeMinifyUrl, {from: canonical})\n        .use(rehypeStringify)\n      const file = new VFile({path: new URL('.' + from, config.output)})\n      const tree = /** @type {Root} */ (\n        await processor.run(buildRedirect(to), file)\n      )\n      file.value = processor.stringify(tree)\n      if (file.dirname) await fs.mkdir(file.dirname, {recursive: true})\n      await fs.writeFile(file.path, String(file))\n    }\n  }),\n  {concurrency: 6}\n)\n\nconsole.log('✔ %d redirects', Object.keys(redirect).length)\n\n/**\n *\n * @param {string} to\n *   Redirect to.\n * @returns {Root}\n *   Tree.\n */\nfunction buildRedirect(to) {\n  const abs = new URL(to, config.site)\n  return {\n    type: 'root',\n    children: [\n      {type: 'doctype'},\n      h('html', {lang: 'en'}, [\n        h('head', [\n          h('meta', {charSet: 'utf8'}),\n          h('title', 'Redirecting…'),\n          h('link', {href: String(abs), rel: 'canonical'}),\n          h('script', 'location = ' + JSON.stringify(abs)),\n          h('meta', {content: '0;url=' + abs, httpEquiv: 'refresh'}),\n          h('meta', {content: 'noindex', name: 'robots'})\n        ]),\n        h('body', [\n          h('h1', 'Redirecting…'),\n          h('p', [\n            h('a', {href: String(abs)}, 'Click here if you are not redirected.')\n          ])\n        ])\n      ])\n    ]\n  }\n}\n"
  },
  {
    "path": "website/schema-description.js",
    "content": "/**\n * @import {Schema} from 'hast-util-sanitize'\n */\n\n/**\n * @type {Readonly<Schema>}\n */\nexport const schema = {\n  ancestors: {},\n  attributes: {\n    a: ['href'],\n    '*': []\n  },\n  protocols: {href: ['http', 'https']},\n  strip: ['script', 'style'],\n  tagNames: [\n    'a',\n    'b',\n    'code',\n    'del',\n    'em',\n    'i',\n    'li',\n    'ol',\n    'p',\n    'pre',\n    's',\n    'strike',\n    'strong',\n    'ul'\n  ]\n}\n"
  },
  {
    "path": "website/types.d.ts",
    "content": "import type {Author} from './generate.js'\n\n// Register data on `estree`.\ndeclare module 'estree' {\n  interface BaseNode {\n    /**\n     * Field patched by `acorn`.\n     *\n     * Registered by types for the MDX website for the playground.\n     */\n    end?: number | undefined\n\n    /**\n     * Field patched by `acorn`.\n     *\n     * Registered by types for the MDX website for the playground.\n     */\n    start?: number | undefined\n  }\n}\n\n// Register data on hast.\ndeclare module 'hast' {\n  interface ElementData {\n    /**\n     * `meta` field available on `<code>` elements; added by `mdast-util-to-hast`.\n     *\n     * Registered by `website/types.d.ts` for the MDX website.\n     */\n    meta?: string | null | undefined\n  }\n}\n\n// Add custom data supported when `rehype-document` is added.\ndeclare module 'vfile' {\n  interface DataMapMeta {\n    /**\n     * Authors associated with a document.\n     *\n     * Registered by `website/types.d.ts` for the MDX website.\n     */\n    authors?: Array<Author> | null | undefined\n\n    /**\n     * Extra schema to add in an `application/ld+json` script.\n     *\n     * Registered by `website/types.d.ts` for the MDX website.\n     */\n    schemaOrg?: unknown\n  }\n\n  interface DataMap {\n    meta: DataMapMeta\n  }\n}\n"
  }
]