[
  {
    "path": ".changeset/README.md",
    "content": "# Changesets\n\nHello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works\nwith multi-package repos, or single-package repos to help you version and publish your code. You can\nfind the full documentation for it [in our repository](https://github.com/changesets/changesets)\n\nWe have a quick list of common questions to get you started engaging with this project in\n[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)\n"
  },
  {
    "path": ".changeset/config.json",
    "content": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@1.6.1/schema.json\",\n  \"changelog\": \"@changesets/cli/changelog\",\n  \"commit\": false,\n  \"linked\": [],\n  \"access\": \"public\",\n  \"baseBranch\": \"next\",\n  \"updateInternalDependencies\": \"patch\",\n  \"ignore\": []\n}\n"
  },
  {
    "path": ".devcontainer/Dockerfile",
    "content": "# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.195.0/containers/go/.devcontainer/base.Dockerfile\n# [Choice] Go version (use -bullseye variants on local arm64/Apple Silicon): 1, 1.16, 1.17, 1-bullseye, 1.16-bullseye, 1.17-bullseye, 1-buster, 1.16-buster, 1.17-buster\nARG VARIANT=1-bullseye\nFROM mcr.microsoft.com/devcontainers/go:0-${VARIANT}\n\n# [Choice] Node.js version: lts/*, 16, 14, 12, 10\nARG NODE_VERSION=\"lts/*\"\nRUN if [ \"${NODE_VERSION}\" != \"none\" ]; then su vscode -c \". /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1\"; fi\n\n# [Optional] Uncomment this section to install additional OS packages.\n# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \\\n#     && apt-get -y install --no-install-recommends <your-package-list-here>\n\n# [Optional] Uncomment the next line to use go get to install anything else you need\n# RUN go get -x <your-dependency-or-tool>\n\n# [Optional] Uncomment this line to install global node packages.\nRUN su vscode -c \"source /usr/local/share/nvm/nvm.sh && npm install -g pnpm\" 2>&1\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "// For format details, see https://aka.ms/vscode-remote/devcontainer.json or this file's README at:\n// https://github.com/microsoft/vscode-dev-containers/tree/v0.195.0/containers/go\n{\n  \"name\": \"Go\",\n  \"build\": {\n    \"dockerfile\": \"Dockerfile\",\n    \"args\": {\n      // Update the VARIANT arg to pick a version of Go: 1, 1.16, 1.17\n      // Append -bullseye or -buster to pin to an OS version.\n      // Use -bullseye variants on local arm64/Apple Silicon.\n      \"VARIANT\": \"1.19\",\n      // Options\n      \"NODE_VERSION\": \"16\"\n    }\n  },\n  \"runArgs\": [\"--cap-add=SYS_PTRACE\", \"--security-opt\", \"seccomp=unconfined\"],\n\n  // Configure tool-specific properties.\n  \"customizations\": {\n    \"vscode\": {\n      \"settings\": {\n        \"go.toolsManagement.checkForUpdates\": \"local\",\n        \"go.useLanguageServer\": true,\n        \"go.gopath\": \"/go\",\n        \"go.goroot\": \"/usr/local/go\"\n      },\n      \"extensions\": [\"golang.Go\"]\n    }\n  },\n\n  \"remoteUser\": \"vscode\"\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*.go]\nindent_style = tab\nindent_size = 2\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".git-blame-ignore-revs",
    "content": "# chore: format everything (#1020)\n402060270f50fe273d5e7387241d7eb36f99ca11\n"
  },
  {
    "path": ".gitattributes",
    "content": "# Files with the language manually specified, sorted alphabetically.\n/internal/**/*.snap linguist-language=Markdown"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/---01-bug-report.yml",
    "content": "name: \"\\U0001F41B Bug Report\"\ndescription: Report an issue or possible bug\ntitle: \"\\U0001F41B BUG:\"\nlabels: []\nassignees: []\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        ##  Quick Checklist\n        Thank you for taking the time to file a bug report! Please fill out this form as completely as possible.\n\n        ✅ I am using the **latest version of Astro** and all plugins.\n        ✅ I am using a version of Node that supports ESM (`v12.20.0+`, `v14.13.1+`, or `v16.0.0+`)\n  - type: input\n    attributes:\n      label: What version of `@astrojs/compiler` are you using?\n      placeholder: 0.0.0\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: What package manager are you using?\n      placeholder: npm, yarn, pnpm\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: What operating system are you using?\n      placeholder: Mac, Windows, Linux\n    validations:\n      required: true\n  - type: textarea\n    attributes:\n      label: Describe the Bug\n      description: A clear and concise description of what the bug is.\n    validations:\n      required: true\n  - type: input\n    attributes:\n      label: Link to Minimal Reproducible Example\n      description: 'Please use the following link to create a reproduction: https://astro.new'\n      placeholder: 'https://stackblitz.com/abcd1234'\n    validations:\n      required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\ncontact_links:\n  - name: 🏡 Main Astro Repo\n    url: https://github.com/withastro/astro\n    about: Unsure if your bug is related to the compiler? Please open an issue in the main Astro repo!\n  - name: 👾 Chat\n    url: https://astro.build/chat\n    about: Our Discord server is active, come join us!\n  - name: 💁 Support\n    url: https://astro.build/chat\n    about: 'This issue tracker is not for support questions. Join us on Discord for assistance!'\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "## Changes\n\n- What does this change?\n- Be short and concise. Bullet points can help!\n- Before/after screenshots can be helpful as well.\n\n## Testing\n\n<!-- How was this change tested? -->\n<!-- DON'T DELETE THIS SECTION! If no tests added, explain why. -->\n\n## Docs\n\n<!-- Was public documentation updated? -->\n<!-- DON'T DELETE THIS SECTION! If no docs added, explain why (e.g. \"bug fix only\") -->\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: Test\n\non:\n  workflow_dispatch:\n  push:\n    branches: ['main', 'next']\n  pull_request:\n    branches: ['main', 'next']\n\n# Automatically cancel in-progress actions on the same branch\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  test:\n    timeout-minutes: 3\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1\n\n      - name: Set up Go\n        uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0\n        with:\n          go-version: 1.22\n\n      - name: Test\n        run: go test -v -timeout 30s ./internal/...\n\n  test-wasm:\n    timeout-minutes: 10\n    strategy:\n      matrix:\n        OS: [ubuntu-latest, windows-latest]\n    runs-on: ${{ matrix.OS }}\n    steps:\n      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1\n\n      - name: Set up Go\n        uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0\n        with:\n          go-version: 1.22\n\n      - name: Set up PNPM\n        uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0\n\n      - name: Set up Node.js\n        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0\n        with:\n          node-version: 24\n          cache: pnpm\n\n      - name: Build WASM\n        run: make wasm\n\n      - name: Install NPM Dependencies\n        run: pnpm install\n        env:\n          CI: true\n\n      - name: Build JS\n        run: pnpm run build:compiler\n\n      - name: Test WASM\n        run: pnpm test:ci\n\n  lint:\n    timeout-minutes: 3\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1\n      - name: golangci-lint\n        uses: golangci/golangci-lint-action@d6238b002a20823d52840fda27e2d4891c5952dc # v4.0.1\n        with:\n          version: latest\n        env:\n          GOOS: js\n          GOARCH: wasm\n\n  lint-js:\n    timeout-minutes: 3\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1\n      - name: Setup Biome\n        uses: biomejs/setup-biome@454fa0d884737805f48d7dc236c1761a0ac3cc13 # v2.6.0\n      - name: Run linting\n        run: biome ci --diagnostic-level=warn\n"
  },
  {
    "path": ".github/workflows/congrats.yml",
    "content": "name: Congratsbot\n\non:\n  push:\n    branches: [main]\n\njobs:\n  congrats:\n    if: ${{ github.repository_owner == 'withastro' }}\n    uses: withastro/automation/.github/workflows/congratsbot.yml@main\n    with:\n      EMOJIS: '⚙️,🔩,🔧,🛠️,🧰,🗜️,🦺,<:lgtm:1121889033602215966>'\n    secrets:\n      DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_CONGRATS }}\n"
  },
  {
    "path": ".github/workflows/issue-labeled.yml",
    "content": "name: Issue Labeled\n\non:\n  issues:\n    types: [labeled]\n\njobs:\n  reply_labelled:\n    if: github.repository_owner == 'withastro'\n    uses: withastro/automation/.github/workflows/issue-labeled.yml@main\n"
  },
  {
    "path": ".github/workflows/issue-needs-repro.yml",
    "content": "name: Close Issues (needs repro)\n\non:\n  schedule:\n    - cron: \"0 0 * * *\"\n\njobs:\n  close-issues:\n    if: github.repository == 'withastro/compiler'\n    runs-on: ubuntu-latest\n    steps:\n      - name: needs repro\n        uses: actions-cool/issues-helper@9861779a695cf1898bd984c727f685f351cfc372 # v3.7.2\n        with:\n          actions: \"close-issues\"\n          token: ${{ secrets.GITHUB_TOKEN }}\n          labels: \"needs repro\"\n          inactive-day: 3\n"
  },
  {
    "path": ".github/workflows/issue-opened.yml",
    "content": "name: Label issues\non:\n  issues:\n    types:\n      - reopened\n      - opened\n\njobs:\n  label_issues:\n    if: github.repository_owner == 'withastro'\n    uses: withastro/automation/.github/workflows/issue-opened.yml@main\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\npermissions: {}\n\non:\n  # We trigger the release job when a commit is pushed to these branches\n  push:\n    branches: [main, next]\n  # We trigger the snapshot-release job for comments on PRs\n  issue_comment:\n    types: [created]\n\njobs:\n  release:\n    timeout-minutes: 3\n    if: github.repository_owner == 'withastro' && github.event_name == 'push'\n    name: Changelog\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n      id-token: write\n    steps:\n      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1\n        with:\n          persist-credentials: false\n\n      - name: Set up Go\n        uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0\n        with:\n          go-version: 1.22\n\n      - name: Set up PNPM\n        uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0\n\n      - name: Set up Node.js\n        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0\n        with:\n          node-version: 24.11.1\n          cache: pnpm\n\n      - name: Build WASM\n        run: make wasm\n\n      - name: Install NPM Dependencies\n        run: pnpm install\n\n      - name: Build JS\n        run: pnpm run build:compiler\n\n      - name: Create Release Pull Request or Publish to npm\n        uses: changesets/action@e0145edc7d9d8679003495b11f87bd8ef63c0cba # v1.5.3\n        with:\n          publish: pnpm run release\n          commit: \"[ci] release\"\n          title: \"[ci] release\"\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NPM_TOKEN: \"\" # See https://github.com/changesets/changesets/issues/1152#issuecomment-3190884868\n\n  snapshot-release:\n    timeout-minutes: 3\n    name: Create a snapshot release of a pull request\n    if: github.repository_owner == 'withastro' && github.event_name == 'issue_comment' && github.event.issue.pull_request && startsWith(github.event.comment.body, '!preview')\n    runs-on: ubuntu-latest\n    permissions:\n      contents: write\n      pull-requests: write\n      id-token: write\n    defaults:\n      run:\n        shell: bash\n    steps:\n      - name: Check if user has admin access (only admins can publish snapshot releases).\n        id: checkAccess\n        uses: actions-cool/check-user-permission@7b90a27f92f3961b368376107661682c441f6103 # v2.3.0\n        with:\n          require: admin\n          username: ${{ github.triggering_actor }}\n\n      # if the user does not have the required permission, we should return exit code 1 to stop the workflow\n      - name: Check user permission\n        if: steps.checkAccess.outputs.require-result == 'false'\n        run: |\n          echo \"${{ github.triggering_actor }} does not have permissions on this repo.\"\n          echo \"Current permission level is ${{ steps.checkAccess.outputs.user-permission }}\"\n          echo \"Job originally triggered by ${{ github.actor }}\"\n          exit 1\n\n      - name: Extract the snapshot name from comment body\n        id: getSnapshotName\n        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0\n        with:\n          script: |\n            const splitComment = context.payload.comment.body.split(' ');\n            splitComment.length !== 2 && (github.rest.issues.createComment({\n              issue_number: context.issue.number,\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              body: 'Invalid comment format. Expected: \"!preview <one-word-snapshot-name>\"',\n            }) || core.setFailed('Invalid comment format. Expected: \"!preview <one-word-snapshot-name>\"'));\n            return splitComment[1].trim();\n          result-encoding: string\n\n      - name: resolve pr refs\n        id: refs\n        uses: eficode/resolve-pr-refs@f7e14e739786aae2053e162c678cd4c3c2edaa83 # v0.0.4\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n\n      - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1\n        with:\n          persist-credentials: false\n          ref: ${{ steps.refs.outputs.head_ref }}\n\n      - name: Set up Go\n        uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0\n        with:\n          go-version: 1.22\n\n      - name: Setup PNPM\n        uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4.2.0\n\n      - name: Setup Node\n        uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0\n        with:\n          node-version: 24.11.1\n          cache: pnpm\n\n      - name: Install dependencies\n        run: pnpm install\n\n      - name: Build Packages\n        run: pnpm run build:all\n\n      - name: Bump Package Versions\n        run: |\n          pnpm exec changeset version --snapshot ${{ steps.getSnapshotName.outputs.result }} > changesets.output.txt 2>&1\n          echo ::set-output name=result::`cat changesets.output.txt`\n        env:\n          # Needs access to run the script\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Publish Release\n        id: publish\n        run: |\n          pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1\n          echo ::set-output name=result::`cat publish.output.txt`\n        env:\n          NPM_TOKEN: \"\" # See https://github.com/changesets/changesets/issues/1152#issuecomment-3190884868\n\n      - name: Pull Request Notification\n        uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0\n        env:\n          MESSAGE: ${{ steps.publish.outputs.result }}\n        with:\n          script: |\n            console.log(process.env.MESSAGE);\n            github.rest.issues.createComment({\n              issue_number: context.issue.number,\n              owner: context.repo.owner,\n              repo: context.repo.repo,\n              body: '```\\n' + process.env.MESSAGE + '\\n```',\n            })\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\n.pnpm-store\nnode_modules\n*.wasm\n/astro\ndebug.test\n__debug_bin\npackages/compiler/sourcemap.mjs\n"
  },
  {
    "path": ".gitpod.yml",
    "content": "# This configuration file was automatically generated by Gitpod.\n# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file)\n# and commit this file to your remote git repository to share the goodness with others.\n\ntasks:\n  - init: pnpm install && pnpm run build && go get && go build ./... && go test ./... && make\n    command: go run .\n"
  },
  {
    "path": ".golangci.yml",
    "content": "issues:\n  exclude-dirs:\n    - lib\n  exclude-files:\n    - xxhash.go\n  exclude-rules:\n    - path: token.go\n      linters:\n        - errcheck\n    - path: escape.go\n      linters:\n        - errcheck\n\n    - linters:\n        - staticcheck\n      text: \"SA9003\"\n"
  },
  {
    "path": ".prettierignore",
    "content": "**/dist\npnpm-lock.yaml\n"
  },
  {
    "path": ".vscode/settings.json",
    "content": "{\n  \"go.toolsEnvVars\": {\n    \"GOOS\": \"js\",\n    \"GOARCH\": \"wasm\"\n  },\n  \"editor.unusualLineTerminators\": \"off\"\n}\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nContributions are welcome to the Go compiler!\n\n## Setup\n\n### Go\n\n[Go][go] `1.20+` is needed to work with this repo. On Macs, installing via [Homebrew][homebrew] is recommended: `brew install go`. For Windows & Linux, you can [follow Go’s installation guide][go] if you don’t have your own preferred method of package installation.\n\nIf you use VS Code as your primary editor, installing the [Go extension][go-vscode] is highly recommended.\n\n### Node\n\nYou will also need [Node.js][node] installed, as well as PNPM 8.x (`npm i -g pnpm`). More often than not, you won’t need to touch JS in this repo, but in case you do, be sure to run `pnpm install` first.\n\n## Code Structure\n\nA simple explanation of the compiler process is:\n\n1. Tokenizes (`internal/token.go`)\n2. Scans (`internal/js_scanner.go`)\n3. Prints (`internal/printer/print-to-js.go`)\n\n**Tokenizing** takes the raw `.astro` text and turns it into simple tokens such as `FrontmatterStart`, `FrontmatterEnd`, `TagStart`, `TagEnd`, etc.\n\n**Scanning** does a basic scanning of the JS to pull out imports after the tokenizer has made it clear where JS begins and ends.\n\n**Printing** takes all the output up till now and generates (prints) valid TypeScript that can be executed within Node.\n\nWhen adding a new feature or debugging an issue, start at the tokenizer, then move onto the scanner, and finally end at the printer. By starting at the lowest level of complexity (tokenizer), it will be easier to reason about.\n\n## Tests\n\nIt's important to **run the test from the root of the project**. Doing so, `go` will load all the necessary global information needed to run the tests.\n\n### Run all tests\n\n```shell\ngo test -v ./internal/...\n```\n### Run a specific test suite \n\n```shell\ngo test -v ./internal/printer\n```\n### Run a specific test case\n\nMany of our test cases are designed like this:\n\n```go\nfunc TestPrintToJSON(t *testing.T) {\n  tests := []jsonTestcase{\n  \t{\n  \t  name:   \"basic\",\n  \t  source: `<h1>Hello world!</h1>`,\n  \t  want:   []ASTNode{{Type: \"element\", Name: \"h1\", Children: []ASTNode{{Type: \"text\", Value: \"Hello world!\"}}}},\n  \t},\n    {\n  \t  name:   \"Comment preserves whitespace\",\n  \t  source: `<!-- hello -->`,\n  \t  want:   []ASTNode{{Type: \"comment\", Value: \" hello \"}},\n  \t}\n  }\n}\n```\n\nIn this particular instance, the test case is name of the function, a slash `/`, followed by the `name` field. If the test case has spaces, you can use them.\n\n```shell\ngo test -v ./internal/... -run TestPrintToJSON/basic\ngo test -v ./internal/... -run TestPrintToJSON/Comment preserves whitespace\n```\n\n#### Snapshot testing\n\nWe use [go-snaps](https://github.com/gkampitakis/go-snaps) for snapshot testing. Visit their repository for more details on how to use it\n\n#### Update snapshots\n\nSome of our tests use snapshot tests. If some of you changes are expected to update some snapshot tests, you can use the environment variable `UPDATE_SNAPS` to do so:\n\n```shell\nUPDATE_SNAPS=true go test -v ./internal/...\n```\n\nInstead, if there are some **obsolete snapshots**, you can `UPDATE_SNAPS=clean`:\n\n```shell\nUPDATE_SNAPS=clean go test -v ./internal/...\n```\n\n\n### Adding new test cases\n\nThe printer tests emit only snapshots. Go to `printer_test.go` and add a new test case:\n\n```go\n{\n\tname: \"New name for this test\"\n\tcode: \"<div></div>\"\n}\n```\n\nThen run the below command, and a new snapshot named `new_name_for_this_test.snap` should appear in the snapshot folder.\n\n```shell\ngo test -v ./internal/printer/printer_test.go\n```\n\nOther tests, like tokenizer and scanner be found in `internal/token_test.go`, `internal/js_scanner_test.go` and respectively.\n\nThose tests don't emit any snapshot, and you'll have to add a `want` field:\n\n```go\n{\n\tname: \"New name for this test\"\n\tcode: \"<div></div>\",\n\twant: want{\n\t\tcode: \"<div></div>\"\n\t}\n}\n```\n\n\n[homebrew]: https://brew.sh/\n[go]: https://golang.org/\n[go-vscode]: https://marketplace.visualstudio.com/items?itemName=golang.go\n[node]: https://nodejs.org/\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 [Astro contributors](https://github.com/withastro/compiler/graphs/contributors)\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 all\ncopies 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 THE\nSOFTWARE.\n\n\"\"\"\nThis license applies to parts of the `internal/` subdirectory originating from \nthe https://cs.opensource.google/go/x/net/+/master:html/ repository:\n\nCopyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Makefile",
    "content": "GO_FLAGS += \"-ldflags=-s -w\"\n\n# Avoid embedding the build path in the executable for more reproducible builds\nGO_FLAGS += -trimpath\n\n\nwasm: internal/*/*.go go.mod\n\tCGO_ENABLED=0 GOOS=js GOARCH=wasm go build $(GO_FLAGS) -o ./packages/compiler/wasm/astro.wasm ./cmd/astro-wasm/astro-wasm.go\n\n\npublish-node:\n\tmake wasm\n\tcd packages/compiler && pnpm run build\n\nclean:\n\tgit clean -dxf\n"
  },
  {
    "path": "SYNTAX_SPEC.md",
    "content": "# The `.astro` File Format - Syntax Specification\n\n**Version:** 1.0\n**Status:** Draft\n**Date:** 2026-02-03\n\n---\n\n## Table of Contents\n\n1. [File Structure](#1-file-structure)\n2. [Component Script (Frontmatter)](#2-component-script-frontmatter)\n3. [Template](#3-template)\n4. [Style Blocks](#4-style-blocks)\n5. [Script Blocks](#5-script-blocks)\n\n---\n\n## 1. File Structure\n\nAn `.astro` file is composed of up to two sections described below. All are optional. When present, they must appear in this order:\n\n```\n┌──────────────────────────────────┐\n│  ---                             │\n│  Component Script                │\n│  ---                             │\n├──────────────────────────────────┤\n│  Template                        │\n└──────────────────────────────────┘\n```\n\n### 1.1 Minimal examples\n\n```astro\n<!-- A comment! -->\n<h1>Hello, World!</h1>\n```\n\n```astro\n---\nconst greeting = \"Hello\";\n---\n\n<h1>{greeting}, World!</h1>\n\n<style>\n  h1 { color: royalblue; }\n</style>\n```\n\n---\n\n## 2. Component Script (Frontmatter)\n\nThe region between the two `---` fences.\n\n- The opening and closing fences are not required on their own line. Code may appear on the same line as both fences.\n- Only one component script is allowed per file.\n- Any amount of whitespace may appear before the opening fence or after the closing fence.\n- Any content may appear before the opening fence, but is customarily ignored.\n\nThe component script is TypeScript. All standard TypeScript syntax is valid, apart from the exceptions and additions outlined in §2.1.\n\n### 2.1 Top-level return\n\n`return` may be used at the top level:\n\n```astro\n---\nimport { getUser } from \"../lib/auth.js\";\n\nconst user = await getUser();\nif (!user) {\n  return Astro.redirect(\"/login\");\n}\n---\n```\n\n---\n\n## 3. Template\n\nThe template is considered to be everything after the closing fence of the component script, or the entire file when there is no component script.\n\nThe template mostly follows the [JSX specification](https://facebook.github.io/jsx/), with the differences and additions outlined in §3.2.\n\n### 3.1 Whitespace between the component script and template is ignored\n\nAny amount of whitespace (spaces, tabs, newlines) between the closing fence of the component script and the start of the template is ignored and does not produce text nodes.\n\n```astro\n---\nconst greeting = \"Hello\";\n---\n\n\n\n<h1>{greeting}, World!</h1>\n```\n\n### 3.2 Differences from JSX\n\nUnless mentioned otherwise, these differences apply both within the template and within expressions inside the template.\n\n#### HTML comments\n\nHTML comments `<!-- … -->` are allowed.\n\n```astro\n<!-- This is an HTML comment -->\n{\n\t<!-- This is an HTML comment inside an expression -->\n}\n```\n\n#### <Fragment>\n\nIn addition to the standard JSX fragment syntax `<>…</>`, `Fragment` is supported as the tag name for fragments, i.e. `<Fragment>…</Fragment>`.\n\n```astro\n<Fragment>\n\t<div>Item 1</div>\t\n\t<div>Item 2</div>\n</Fragment>\n```\n\nThis form may accept attributes, unlike the shorthand syntax.\n\n#### `is:raw` Directive\n\nThe `is:raw` attribute on any element allows the content to be treated as raw text instead of JSX.\n\n```astro\n<Component is:raw>{<% non-JS content %>}</Component>\n\n<div is:raw>\n\t{not an expression, just text}\n</div>\n```\n\n#### HTML doctype\n\nThe [HTML doctype declaration](https://html.spec.whatwg.org/multipage/syntax.html#the-doctype) is allowed.\n\n```astro\n<!DOCTYPE html>\n```\n\n##### Top-level text nodes\n\nTop-level text inside the template is treated as text nodes.\n\n```astro\nHello, World!\n```\n\n#### Whitespace in expressions\n\nWhitespace inside expressions `{ }` is preserved as text nodes, unlike JSX, where whitespace inside expression containers is ignored:\n\n```astro\n<!-- Whitespace around element -->\n{\n    <div>Hello</div>\n}\n\n<!-- Leading/trailing spaces -->\n{   <div>test</div>   }\n\n<!-- Whitespace-only expression -->\n{   }\n```\n\nIn Astro, all of these produce text nodes for the whitespace, whereas in JSX:\n\n- Whitespace around elements inside `{ }` is ignored\n- Whitespace-only expressions result in an empty expression, with no text nodes.\n\n#### Multiple root elements\n\nUnlike JSX, no single root element is required:\n\n```astro\n<header>…</header>\n<main>…</main>\n<footer>…</footer>\n\n<!-- or inside an expression: -->\n{\n  <div>1</div>\n  <div>2</div>\n  <div>3</div>\n}\n```\n\n#### Attribute names\n\nAttribute names [follow the HTML conventions](https://html.spec.whatwg.org/multipage/syntax.html#syntax-attribute-name) and are not required to be valid JavaScript identifiers. For example, characters like hyphens and colons are allowed in attribute names:\n\n```astro\n<div @click=\"handler\" x.data=\"value\" :class=\"my-class\" />\n```\n\n#### Namespace in component names is not supported\n\nColons in component names are not treated as namespace separators. For example:\n\n```astro\n<Namespace:Component />\n```\n\nWill be treated as a single component name (i.e. `Namespace:Component`). Spaces are not allowed in component names, so the following:\n\n```astro\n<Namespace : Component />\n```\n\nWould result in the component's name being Namespace, an attribute named `:` with no value, and an attribute named `Component` with no value.\n\n#### Attribute shorthand\n\nAttributes can use a shorthand syntax where `{prop}` is equivalent to `prop={prop}`:\n\n```astro\n<Component {prop} />\n<!-- equivalent to: -->\n<Component prop={prop} />\n```\n\n#### Template literal attributes\n\nAttributes can use backticks for interpolation without opening an expression:\n\n```astro\n<Component attribute=`hello ${value}` />\n```\n\n#### Empty expressions inside attributes\n\nEmpty expressions `{}` inside attributes are allowed:\n\n```astro\n<Component attribute={} />\n```\n\n#### Comments inside opening tags\n\nComments are allowed inside the opening tag of an element:\n\n```astro\n<div\n\t{/* Hello */}\n\tclass=\"my-class\"\n></div>\n```\n\n#### Less-than signs in text nodes\n\nLess-than signs `<` in text nodes are parsed following HTML rules, meaning they do not need to be escaped:\n\n```astro\n<p>5 < 10</p>\n```\n\n#### Non-ASCII tag names are not supported\n\nTag names must use ASCII characters only. Non-ASCII tag names (e.g. `<日本>`) are not supported and are treated as text nodes.\n\n#### Unquoted attribute values\n\nAttribute values do not need to be quoted if they contain only alphanumeric characters, hyphens, underscores, and periods:\n\n```astro\n<Component data-id=12345 class=my-class />\n```\n\n#### Unclosed HTML tags\n\nLike HTML, tags do not need to be explicitly closed.\n\n```astro\n<p>Hello\n<p>World\n```\n\nIt is up to the parser to optionally try to infer where tags close based on HTML parsing rules, or leave them unclosed.\n\n##### Void elements\n\nHTML void elements do not need to be self-closed:\n\n```astro\n<input type=\"text\">\n<br>\n<img src=\"image.png\">\n```\n\n#### Element-specific parsing rules\n\nCertain HTML elements have special parsing rules that differ from the general rules outlined above. These include:\n\n- `<script>` - contains JavaScript/TypeScript (see §5)\n- `<style>` - contains CSS (see §4)\n\n##### Elements that disable expression parsing\n\nThe following elements disable expression parsing entirely. Inside these elements and their descendants, curly braces `{` and `}` are treated as literal text characters, not expression delimiters:\n\n- `<math>`\n- `<iframe>`\n- `<noembed>`\n- `<noframes>`\n- `<plaintext>`\n- `<xmp>`\n\nExample with `<math>`:\n\n```astro\n<math xmlns=\"http://www.w3.org/1998/Math/MathML\">\n  <semantics>\n    <annotation encoding=\"application/x-tex\">\n      f\\colon X \\to \\mathbb{R}^{2x}\n    </annotation>\n  </semantics>\n</math>\n```\n\nIn this example, `{R}` and `{2x}` are treated as literal text, not expressions.\n\n##### Raw text elements that still support expressions\n\nThe `<title>` and `<textarea>` elements have special parsing where HTML tags inside them are treated as literal text rather than elements, but expressions still work.\n\n```astro\n<title>{pageTitle} - Site with <b>bold</b></title>\n<textarea>{defaultValue} with <div>tags</div></textarea>\n```\n\nIn this example:\n- `{pageTitle}` and `{defaultValue}` are expressions that will be evaluated\n- The `<b>bold</b>` and `<div>tags</div>` are treated as literal text, not HTML elements\n\n---\n\n## 4. Style Blocks\n\n```astro\n<style>\n  h1 { color: red; }\n</style>\n```\n\nMultiple `<style>` blocks are allowed per file.\n\n### 4.1 Language\n\nBy default, `<style>` blocks can contain CSS. The content adheres to standard CSS syntax as defined by the [CSS Syntax Module](https://www.w3.org/TR/css-syntax-3/).\n\n### 4.2 `lang` attribute\n\nSpecifies a preprocessor language:\n\n```astro\n<style lang=\"scss\">\n  $accent: #1d4ed8;\n  .card { border-color: $accent; }\n</style>\n```\n\nThe syntax then follows the rules of the specified preprocessor instead of standard CSS.\n\n---\n\n## 5. Script Blocks\n\n```astro\n<script>\n  console.log(\"Hello\");\n</script>\n```\n\nMultiple `<script>` blocks are allowed per file.\n\n### 5.1 Language\n\nA bare `<script>` tag with no attributes can contain TypeScript. The content adheres to standard TypeScript syntax.\n\n```astro\n<script>\n  interface User {\n    id: number;\n    name: string;\n  }\n\n  // ...\n</script>\n```\n\nIf any attributes are present, the content instead follows standard [HTML `<script>` element](https://html.spec.whatwg.org/multipage/scripting.html#the-script-element) rules.\n\n```astro\n<script defer>\n\t// JavaScript\n</script>\n\n<script type=\"module\">\n  // JavaScript module\n  import { foo } from \"./foo.js\";\n</script>\n\n<script type=\"application/json\">\n  { \"key\": \"value\" }\n</script>\n```\n"
  },
  {
    "path": "biome.json",
    "content": "{\n  \"$schema\": \"https://biomejs.dev/schemas/1.8.1/schema.json\",\n  \"files\": {\n    \"ignore\": [\"**/dist/**\", \"**/pnpm-lock.yaml\", \"wasm_exec.ts\"],\n    \"include\": [\"packages/**\"]\n  },\n  \"formatter\": {\n    \"enabled\": true,\n    \"indentStyle\": \"tab\",\n    \"indentWidth\": 2,\n    \"lineWidth\": 100\n  },\n  \"organizeImports\": {\n    \"enabled\": true\n  },\n  \"linter\": {\n    \"enabled\": true,\n    \"rules\": {\n      \"recommended\": true,\n      \"suspicious\": {\n        \"noExplicitAny\": \"info\",\n        \"noConsoleLog\": \"info\"\n      },\n      \"style\": {\n        \"useTemplate\": {\n          \"level\": \"error\",\n          \"fix\": \"safe\"\n        },\n        \"noUnusedTemplateLiteral\": {\n          \"level\": \"error\",\n          \"fix\": \"safe\"\n        }\n      }\n    }\n  },\n  \"javascript\": {\n    \"formatter\": {\n      \"trailingCommas\": \"es5\",\n      \"quoteStyle\": \"single\",\n      \"semicolons\": \"always\"\n    }\n  },\n  \"json\": {\n    \"parser\": {\n      \"allowComments\": true,\n      \"allowTrailingCommas\": true\n    },\n    \"formatter\": {\n      \"indentStyle\": \"space\",\n      \"trailingCommas\": \"none\"\n    }\n  },\n  \"overrides\": [\n    {\n      \"include\": [\"**/stress/**\"],\n      \"linter\": {\n        \"rules\": {\n          \"suspicious\": {\n            \"noConsoleLog\": \"off\"\n          }\n        }\n      }\n    },\n    {\n      \"include\": [\"package.json\"],\n      \"json\": {\n        \"formatter\": {\n          \"lineWidth\": 1\n        }\n      }\n    }\n  ]\n}\n"
  },
  {
    "path": "cmd/astro-wasm/astro-wasm.go",
    "content": "//go:build js && wasm\n\npackage main\n\nimport (\n\t\"encoding/base64\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"syscall/js\"\n\t\"unicode\"\n\n\t\"github.com/norunners/vert\"\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"github.com/withastro/compiler/internal/printer\"\n\t\"github.com/withastro/compiler/internal/sourcemap\"\n\tt \"github.com/withastro/compiler/internal/t\"\n\t\"github.com/withastro/compiler/internal/transform\"\n\twasm_utils \"github.com/withastro/compiler/internal_wasm/utils\"\n)\n\nfunc main() {\n\tjs.Global().Set(\"@astrojs/compiler\", js.ValueOf(make(map[string]interface{})))\n\tmodule := js.Global().Get(\"@astrojs/compiler\")\n\tmodule.Set(\"transform\", Transform())\n\tmodule.Set(\"parse\", Parse())\n\tmodule.Set(\"convertToTSX\", ConvertToTSX())\n\n\t<-make(chan struct{})\n}\n\nfunc jsString(j js.Value) string {\n\tif j.Equal(js.Undefined()) || j.Equal(js.Null()) {\n\t\treturn \"\"\n\t}\n\treturn j.String()\n}\n\nfunc jsBoolOptional(j js.Value, defaultValue bool) bool {\n\tif j.Equal(js.Undefined()) || j.Equal(js.Null()) {\n\t\treturn defaultValue\n\t}\n\treturn j.Bool()\n}\n\nfunc jsBool(j js.Value) bool {\n\tif j.Equal(js.Undefined()) || j.Equal(js.Null()) {\n\t\treturn false\n\t}\n\treturn j.Bool()\n}\n\nfunc makeParseOptions(options js.Value) t.ParseOptions {\n\tposition := true\n\n\tpos := options.Get(\"position\")\n\tif !pos.IsNull() && !pos.IsUndefined() {\n\t\tposition = pos.Bool()\n\t}\n\n\tfilename := jsString(options.Get(\"filename\"))\n\tif filename == \"\" {\n\t\tfilename = \"<stdin>\"\n\t}\n\n\treturn t.ParseOptions{\n\t\tFilename: filename,\n\t\tPosition: position,\n\t}\n}\n\nfunc makeTransformOptions(options js.Value) transform.TransformOptions {\n\tfilename := jsString(options.Get(\"filename\"))\n\tif filename == \"\" {\n\t\tfilename = \"<stdin>\"\n\t}\n\n\tnormalizedFilename := jsString(options.Get(\"normalizedFilename\"))\n\tif normalizedFilename == \"\" {\n\t\tnormalizedFilename = filename\n\t}\n\n\tinternalURL := jsString(options.Get(\"internalURL\"))\n\tif internalURL == \"\" {\n\t\tinternalURL = \"astro/runtime/server/index.js\"\n\t}\n\n\tsourcemap := jsString(options.Get(\"sourcemap\"))\n\tif sourcemap == \"<boolean: true>\" {\n\t\tsourcemap = \"both\"\n\t}\n\n\tastroGlobalArgs := jsString(options.Get(\"astroGlobalArgs\"))\n\n\tcompact := false\n\tif jsBool(options.Get(\"compact\")) {\n\t\tcompact = true\n\t}\n\n\tscopedSlot := false\n\tif jsBool(options.Get(\"resultScopedSlot\")) {\n\t\tscopedSlot = true\n\t}\n\n\ttransitionsAnimationURL := jsString(options.Get(\"transitionsAnimationURL\"))\n\tif transitionsAnimationURL == \"\" {\n\t\ttransitionsAnimationURL = \"astro/components/viewtransitions.css\"\n\t}\n\n\tannotateSourceFile := false\n\tif jsBool(options.Get(\"annotateSourceFile\")) {\n\t\tannotateSourceFile = true\n\t}\n\n\tvar resolvePath any = options.Get(\"resolvePath\")\n\tvar resolvePathFn func(string) string\n\tif resolvePath.(js.Value).Type() == js.TypeFunction {\n\t\tresolvePathFn = func(id string) string {\n\t\t\tresult, _ := wasm_utils.Await(resolvePath.(js.Value).Invoke(id))\n\t\t\tif result[0].Equal(js.Undefined()) || result[0].Equal(js.Null()) {\n\t\t\t\treturn id\n\t\t\t} else {\n\t\t\t\treturn result[0].String()\n\t\t\t}\n\t\t}\n\t}\n\n\tpreprocessStyle := options.Get(\"preprocessStyle\")\n\n\tscopedStyleStrategy := jsString(options.Get(\"scopedStyleStrategy\"))\n\tif scopedStyleStrategy == \"\" {\n\t\tscopedStyleStrategy = \"where\"\n\t}\n\n\treturn transform.TransformOptions{\n\t\tFilename:                filename,\n\t\tNormalizedFilename:      normalizedFilename,\n\t\tInternalURL:             internalURL,\n\t\tSourceMap:               sourcemap,\n\t\tAstroGlobalArgs:         astroGlobalArgs,\n\t\tCompact:                 compact,\n\t\tResolvePath:             resolvePathFn,\n\t\tPreprocessStyle:         preprocessStyle,\n\t\tResultScopedSlot:        scopedSlot,\n\t\tScopedStyleStrategy:     scopedStyleStrategy,\n\t\tTransitionsAnimationURL: transitionsAnimationURL,\n\t\tAnnotateSourceFile:      annotateSourceFile,\n\t}\n}\n\nfunc makeTSXOptions(options js.Value) printer.TSXOptions {\n\tincludeScripts := jsBoolOptional(options.Get(\"includeScripts\"), true)\n\tincludeStyles := jsBoolOptional(options.Get(\"includeStyles\"), true)\n\n\treturn printer.TSXOptions{\n\t\tIncludeScripts: includeScripts,\n\t\tIncludeStyles:  includeStyles,\n\t}\n}\n\ntype RawSourceMap struct {\n\tFile           string   `js:\"file\"`\n\tMappings       string   `js:\"mappings\"`\n\tNames          []string `js:\"names\"`\n\tSources        []string `js:\"sources\"`\n\tSourcesContent []string `js:\"sourcesContent\"`\n\tVersion        int      `js:\"version\"`\n}\n\ntype HoistedScript struct {\n\tCode string `js:\"code\"`\n\tSrc  string `js:\"src\"`\n\tType string `js:\"type\"`\n\tMap  string `js:\"map\"`\n}\n\ntype HydratedComponent struct {\n\tExportName   string `js:\"exportName\"`\n\tLocalName    string `js:\"localName\"`\n\tSpecifier    string `js:\"specifier\"`\n\tResolvedPath string `js:\"resolvedPath\"`\n}\n\ntype ParseResult struct {\n\tAST         string                  `js:\"ast\"`\n\tDiagnostics []loc.DiagnosticMessage `js:\"diagnostics\"`\n}\n\ntype TSXResult struct {\n\tCode        string                  `js:\"code\"`\n\tMap         string                  `js:\"map\"`\n\tDiagnostics []loc.DiagnosticMessage `js:\"diagnostics\"`\n\tRanges      printer.TSXRanges       `js:\"metaRanges\"`\n}\n\ntype TransformResult struct {\n\tCode                 string                  `js:\"code\"`\n\tDiagnostics          []loc.DiagnosticMessage `js:\"diagnostics\"`\n\tMap                  string                  `js:\"map\"`\n\tScope                string                  `js:\"scope\"`\n\tCSS                  []string                `js:\"css\"`\n\tScripts              []HoistedScript         `js:\"scripts\"`\n\tHydratedComponents   []HydratedComponent     `js:\"hydratedComponents\"`\n\tClientOnlyComponents []HydratedComponent     `js:\"clientOnlyComponents\"`\n\tServerComponents     []HydratedComponent     `js:\"serverComponents\"`\n\tContainsHead         bool                    `js:\"containsHead\"`\n\tStyleError           []string                `js:\"styleError\"`\n\tPropagation          bool                    `js:\"propagation\"`\n}\n\n// This is spawned as a goroutine to preprocess style nodes using an async function passed from JS\nfunc preprocessStyle(i int, style *astro.Node, transformOptions transform.TransformOptions, styleError *[]string, cb func()) {\n\tdefer cb()\n\tif style.FirstChild == nil {\n\t\treturn\n\t}\n\tattrs := wasm_utils.GetAttrs(style)\n\tdata, _ := wasm_utils.Await(transformOptions.PreprocessStyle.(js.Value).Invoke(style.FirstChild.Data, attrs))\n\t// note: Rollup (and by extension our Astro Vite plugin) allows for \"undefined\" and \"null\" responses if a transform wishes to skip this occurrence\n\tif data[0].Equal(js.Undefined()) || data[0].Equal(js.Null()) {\n\t\treturn\n\t}\n\t// If an error return, override the style's CSS so the compiler doesn't hang\n\t// And return a styleError. The caller will use this to know that style processing failed.\n\tif err := jsString(data[0].Get(\"error\")); err != \"\" {\n\t\tstyle.FirstChild.Data = \"\"\n\t\t//*styleError = err\n\t\t*styleError = append(*styleError, err)\n\t\treturn\n\t}\n\tstr := jsString(data[0].Get(\"code\"))\n\tif str == \"\" {\n\t\treturn\n\t}\n\tstyle.FirstChild.Data = str\n}\n\nfunc Parse() any {\n\treturn js.FuncOf(func(this js.Value, args []js.Value) any {\n\t\tsource := jsString(args[0])\n\t\tparseOptions := makeParseOptions(js.Value(args[1]))\n\t\ttransformOptions := makeTransformOptions(js.Value(args[1]))\n\t\ttransformOptions.Scope = \"xxxxxx\"\n\t\th := handler.NewHandler(source, parseOptions.Filename)\n\n\t\tvar doc *astro.Node\n\t\tdoc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true))\n\t\tif err != nil {\n\t\t\th.AppendError(err)\n\t\t}\n\t\tresult := printer.PrintToJSON(source, doc, parseOptions)\n\n\t\t// AFTER printing, exec transformations to pickup any errors/warnings\n\t\ttransform.Transform(doc, transformOptions, h)\n\n\t\treturn vert.ValueOf(ParseResult{\n\t\t\tAST:         string(result.Output),\n\t\t\tDiagnostics: h.Diagnostics(),\n\t\t}).Value\n\t})\n}\n\nfunc ConvertToTSX() any {\n\treturn js.FuncOf(func(this js.Value, args []js.Value) any {\n\t\tsource := jsString(args[0])\n\t\ttransformOptions := makeTransformOptions(js.Value(args[1]))\n\t\ttransformOptions.Scope = \"xxxxxx\"\n\t\th := handler.NewHandler(source, transformOptions.Filename)\n\n\t\tvar doc *astro.Node\n\t\tdoc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true))\n\t\tif err != nil {\n\t\t\th.AppendError(err)\n\t\t}\n\n\t\ttsxOptions := makeTSXOptions(js.Value(args[1]))\n\n\t\tresult := printer.PrintToTSX(source, doc, tsxOptions, transformOptions, h)\n\n\t\t// AFTER printing, exec transformations to pickup any errors/warnings\n\t\ttransform.Transform(doc, transformOptions, h)\n\n\t\tsourcemapString := createSourceMapString(source, result, transformOptions)\n\t\tcode := string(result.Output)\n\t\tif transformOptions.SourceMap != \"external\" {\n\t\t\tinlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))\n\t\t\tcode += \"\\n\" + inlineSourcemap\n\t\t}\n\n\t\treturn vert.ValueOf(TSXResult{\n\t\t\tCode:        code,\n\t\t\tMap:         sourcemapString,\n\t\t\tDiagnostics: h.Diagnostics(),\n\t\t\tRanges:      result.TSXRanges,\n\t\t}).Value\n\t})\n}\n\nfunc Transform() any {\n\treturn js.FuncOf(func(this js.Value, args []js.Value) any {\n\t\tsource := strings.TrimRightFunc(jsString(args[0]), unicode.IsSpace)\n\n\t\ttransformOptions := makeTransformOptions(js.Value(args[1]))\n\t\tscopeStr := transformOptions.NormalizedFilename\n\t\tif scopeStr == \"<stdin>\" {\n\t\t\tscopeStr = source\n\t\t}\n\t\ttransformOptions.Scope = astro.HashString(scopeStr)\n\t\th := handler.NewHandler(source, transformOptions.Filename)\n\n\t\tstyleError := []string{}\n\t\tpromiseHandle := js.FuncOf(func(this js.Value, args []js.Value) any {\n\t\t\tresolve := args[0]\n\t\t\treject := args[1]\n\n\t\t\tgo func() {\n\t\t\t\tvar doc *astro.Node\n\t\t\t\tdefer func() {\n\t\t\t\t\tif err := recover(); err != nil {\n\t\t\t\t\t\treject.Invoke(wasm_utils.ErrorToJSError(h, err.(error)))\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}()\n\n\t\t\t\tdoc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h))\n\t\t\t\tif err != nil {\n\t\t\t\t\treject.Invoke(wasm_utils.ErrorToJSError(h, err))\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// Hoist styles and scripts to the top-level\n\t\t\t\ttransform.ExtractStyles(doc, &transformOptions)\n\n\t\t\t\t// Pre-process styles\n\t\t\t\t// Important! These goroutines need to be spawned from this file or they don't work\n\t\t\t\tvar wg sync.WaitGroup\n\t\t\t\tif len(doc.Styles) > 0 {\n\t\t\t\t\tif transformOptions.PreprocessStyle.(js.Value).Type() == js.TypeFunction {\n\t\t\t\t\t\tfor i, style := range doc.Styles {\n\t\t\t\t\t\t\twg.Add(1)\n\t\t\t\t\t\t\ti := i\n\t\t\t\t\t\t\tgo preprocessStyle(i, style, transformOptions, &styleError, wg.Done)\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Wait for all the style goroutines to finish\n\t\t\t\twg.Wait()\n\n\t\t\t\t// Perform CSS and element scoping as needed\n\t\t\t\ttransform.Transform(doc, transformOptions, h)\n\n\t\t\t\tcss := []string{}\n\t\t\t\tscripts := []HoistedScript{}\n\t\t\t\thydratedComponents := []HydratedComponent{}\n\t\t\t\tclientOnlyComponents := []HydratedComponent{}\n\t\t\t\tserverComponents := []HydratedComponent{}\n\t\t\t\tcss_result := printer.PrintCSS(source, doc, transformOptions)\n\t\t\t\tfor _, bytes := range css_result.Output {\n\t\t\t\t\tcss = append(css, string(bytes))\n\t\t\t\t}\n\n\t\t\t\t// Append hoisted scripts\n\t\t\t\tfor _, node := range doc.Scripts {\n\t\t\t\t\tsrc := astro.GetAttribute(node, \"src\")\n\t\t\t\t\tscript := HoistedScript{\n\t\t\t\t\t\tSrc:  \"\",\n\t\t\t\t\t\tCode: \"\",\n\t\t\t\t\t\tType: \"\",\n\t\t\t\t\t\tMap:  \"\",\n\t\t\t\t\t}\n\n\t\t\t\t\tif src != nil {\n\t\t\t\t\t\tscript.Type = \"external\"\n\t\t\t\t\t\tscript.Src = src.Val\n\t\t\t\t\t} else if node.FirstChild != nil {\n\t\t\t\t\t\tscript.Type = \"inline\"\n\n\t\t\t\t\t\tif transformOptions.SourceMap != \"\" {\n\t\t\t\t\t\t\tisLine := func(r rune) bool { return r == '\\r' || r == '\\n' }\n\t\t\t\t\t\t\tisNotLine := func(r rune) bool { return !(r == '\\r' || r == '\\n') }\n\t\t\t\t\t\t\toutput := make([]byte, 0)\n\t\t\t\t\t\t\tbuilder := sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(source, len(strings.Split(source, \"\\n\"))))\n\t\t\t\t\t\t\tsourcesContent, _ := json.Marshal(source)\n\t\t\t\t\t\t\tif len(node.FirstChild.Loc) > 0 {\n\t\t\t\t\t\t\t\ti := node.FirstChild.Loc[0].Start\n\t\t\t\t\t\t\t\tnonWS := strings.IndexFunc(node.FirstChild.Data, isNotLine)\n\t\t\t\t\t\t\t\ti += nonWS\n\t\t\t\t\t\t\t\tfor _, ln := range strings.Split(strings.TrimFunc(node.FirstChild.Data, isLine), \"\\n\") {\n\t\t\t\t\t\t\t\t\tcontent := []byte(ln)\n\t\t\t\t\t\t\t\t\tcontent = append(content, '\\n')\n\t\t\t\t\t\t\t\t\tfor j, b := range content {\n\t\t\t\t\t\t\t\t\t\tif j == 0 || !unicode.IsSpace(rune(b)) {\n\t\t\t\t\t\t\t\t\t\t\tbuilder.AddSourceMapping(loc.Loc{Start: i}, output)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\toutput = append(output, b)\n\t\t\t\t\t\t\t\t\t\ti += 1\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\toutput = append(output, '\\n')\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\toutput = append(output, []byte(strings.TrimSpace(node.FirstChild.Data))...)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsourcemap := fmt.Sprintf(\n\t\t\t\t\t\t\t\t`{ \"version\": 3, \"sources\": [\"%s\"], \"sourcesContent\": [%s], \"mappings\": \"%s\", \"names\": [] }`,\n\t\t\t\t\t\t\t\ttransformOptions.Filename,\n\t\t\t\t\t\t\t\tstring(sourcesContent),\n\t\t\t\t\t\t\t\tstring(builder.GenerateChunk(output).Buffer),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\tscript.Map = sourcemap\n\t\t\t\t\t\t\tscript.Code = string(output)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tscript.Code = node.FirstChild.Data\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// sourcemapString := createSourceMapString(source, result, transformOptions)\n\t\t\t\t\t// inlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))\n\t\t\t\t\tscripts = append(scripts, script)\n\t\t\t\t}\n\n\t\t\t\tfor _, c := range doc.HydratedComponents {\n\t\t\t\t\thydratedComponents = append(hydratedComponents, HydratedComponent{\n\t\t\t\t\t\tExportName:   c.ExportName,\n\t\t\t\t\t\tSpecifier:    c.Specifier,\n\t\t\t\t\t\tResolvedPath: c.ResolvedPath,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tfor _, c := range doc.ClientOnlyComponents {\n\t\t\t\t\tclientOnlyComponents = append(clientOnlyComponents, HydratedComponent{\n\t\t\t\t\t\tExportName:   c.ExportName,\n\t\t\t\t\t\tSpecifier:    c.Specifier,\n\t\t\t\t\t\tResolvedPath: c.ResolvedPath,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tfor _, c := range doc.ServerComponents {\n\t\t\t\t\tserverComponents = append(serverComponents, HydratedComponent{\n\t\t\t\t\t\tExportName:   c.ExportName,\n\t\t\t\t\t\tLocalName:    c.LocalName,\n\t\t\t\t\t\tSpecifier:    c.Specifier,\n\t\t\t\t\t\tResolvedPath: c.ResolvedPath,\n\t\t\t\t\t})\n\t\t\t\t}\n\n\t\t\t\tvar value vert.Value\n\t\t\t\tresult := printer.PrintToJS(source, doc, len(css), transformOptions, h)\n\t\t\t\ttransformResult := &TransformResult{\n\t\t\t\t\tCSS:                  css,\n\t\t\t\t\tScope:                transformOptions.Scope,\n\t\t\t\t\tScripts:              scripts,\n\t\t\t\t\tHydratedComponents:   hydratedComponents,\n\t\t\t\t\tClientOnlyComponents: clientOnlyComponents,\n\t\t\t\t\tServerComponents:     serverComponents,\n\t\t\t\t\tContainsHead:         doc.ContainsHead,\n\t\t\t\t\tStyleError:           styleError,\n\t\t\t\t\tPropagation:          doc.HeadPropagation,\n\t\t\t\t}\n\t\t\t\tswitch transformOptions.SourceMap {\n\t\t\t\tcase \"external\":\n\t\t\t\t\tvalue = createExternalSourceMap(source, transformResult, result, transformOptions)\n\t\t\t\tcase \"both\":\n\t\t\t\t\tvalue = createBothSourceMap(source, transformResult, result, transformOptions)\n\t\t\t\tcase \"inline\":\n\t\t\t\t\tvalue = createInlineSourceMap(source, transformResult, result, transformOptions)\n\t\t\t\tdefault:\n\t\t\t\t\ttransformResult.Code = string(result.Output)\n\t\t\t\t\ttransformResult.Map = \"\"\n\t\t\t\t\tvalue = vert.ValueOf(transformResult)\n\t\t\t\t}\n\t\t\t\tvalue.Set(\"diagnostics\", vert.ValueOf(h.Diagnostics()).Value)\n\t\t\t\tresolve.Invoke(value.Value)\n\t\t\t}()\n\n\t\t\treturn nil\n\t\t})\n\t\tdefer promiseHandle.Release()\n\n\t\t// Create and return the Promise object\n\t\tpromiseConstructor := js.Global().Get(\"Promise\")\n\t\treturn promiseConstructor.New(promiseHandle)\n\t})\n}\n\nfunc createSourceMapString(source string, result printer.PrintResult, transformOptions transform.TransformOptions) string {\n\tsourcesContent, _ := json.Marshal(source)\n\tsourcemap := RawSourceMap{\n\t\tVersion:        3,\n\t\tSources:        []string{transformOptions.Filename},\n\t\tSourcesContent: []string{string(sourcesContent)},\n\t\tMappings:       string(result.SourceMapChunk.Buffer),\n\t}\n\treturn fmt.Sprintf(`{\n  \"version\": 3,\n  \"sources\": [\"%s\"],\n  \"sourcesContent\": [%s],\n  \"mappings\": \"%s\",\n  \"names\": []\n}`, sourcemap.Sources[0], sourcemap.SourcesContent[0], sourcemap.Mappings)\n}\n\nfunc createExternalSourceMap(source string, transformResult *TransformResult, result printer.PrintResult, transformOptions transform.TransformOptions) vert.Value {\n\ttransformResult.Code = string(result.Output)\n\ttransformResult.Map = createSourceMapString(source, result, transformOptions)\n\treturn vert.ValueOf(transformResult)\n}\n\nfunc createInlineSourceMap(source string, transformResult *TransformResult, result printer.PrintResult, transformOptions transform.TransformOptions) vert.Value {\n\tsourcemapString := createSourceMapString(source, result, transformOptions)\n\tinlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))\n\ttransformResult.Code = string(result.Output) + \"\\n\" + inlineSourcemap\n\ttransformResult.Map = \"\"\n\treturn vert.ValueOf(transformResult)\n}\n\nfunc createBothSourceMap(source string, transformResult *TransformResult, result printer.PrintResult, transformOptions transform.TransformOptions) vert.Value {\n\tsourcemapString := createSourceMapString(source, result, transformOptions)\n\tinlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))\n\ttransformResult.Code = string(result.Output) + \"\\n\" + inlineSourcemap\n\ttransformResult.Map = sourcemapString\n\treturn vert.ValueOf(transformResult)\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/withastro/compiler\n\ngo 1.21\n\nrequire (\n\tgithub.com/gkampitakis/go-snaps v0.5.2\n\tgithub.com/google/go-cmp v0.5.9\n\tgithub.com/iancoleman/strcase v0.2.0\n\tgithub.com/lithammer/dedent v1.1.0\n\tgithub.com/norunners/vert v0.0.0-20221203075838-106a353d42dd\n\tgithub.com/tdewolff/parse/v2 v2.6.4\n\tgolang.org/x/net v0.0.0-20221004154528-8021a29435af\n\tgolang.org/x/sys v0.0.0-20221010170243-090e33056c14\n)\n\nrequire (\n\tgithub.com/gkampitakis/ciinfo v0.3.0 // indirect\n\tgithub.com/gkampitakis/go-diff v1.3.2 // indirect\n\tgithub.com/kr/pretty v0.3.1 // indirect\n\tgithub.com/kr/text v0.2.0 // indirect\n\tgithub.com/maruel/natural v1.1.1 // indirect\n\tgithub.com/rogpeppe/go-internal v1.12.0 // indirect\n\tgithub.com/tidwall/gjson v1.17.0 // indirect\n\tgithub.com/tidwall/match v1.1.1 // indirect\n\tgithub.com/tidwall/pretty v1.2.1 // indirect\n\tgithub.com/tidwall/sjson v1.2.5 // indirect\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=\ngithub.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8=\ngithub.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=\ngithub.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=\ngithub.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=\ngithub.com/gkampitakis/go-snaps v0.5.2 h1:ay/6f7WHwRkOgpBec9DjMLRBAApziJommZ21NkOOCwY=\ngithub.com/gkampitakis/go-snaps v0.5.2/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=\ngithub.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=\ngithub.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=\ngithub.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=\ngithub.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=\ngithub.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=\ngithub.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=\ngithub.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=\ngithub.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=\ngithub.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=\ngithub.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=\ngithub.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=\ngithub.com/norunners/vert v0.0.0-20221203075838-106a353d42dd h1:tHn7K76q9eJ2rXLH/OoxHkdprM3l2A+0kdxOrKYcV7U=\ngithub.com/norunners/vert v0.0.0-20221203075838-106a353d42dd/go.mod h1:8iuQLyTSvuzwy6R6l6w6J+i9c/6xPEVoVdcMz9E8FEw=\ngithub.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=\ngithub.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=\ngithub.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=\ngithub.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=\ngithub.com/tdewolff/parse/v2 v2.6.4 h1:KCkDvNUMof10e3QExio9OPZJT8SbdKojLBumw8YZycQ=\ngithub.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=\ngithub.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=\ngithub.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=\ngithub.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=\ngithub.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=\ngithub.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=\ngithub.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=\ngithub.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=\ngithub.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=\ngithub.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=\ngithub.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=\ngithub.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=\ngithub.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=\ngolang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=\ngolang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=\ngolang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc=\ngolang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\n"
  },
  {
    "path": "internal/const.go",
    "content": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\nimport a \"golang.org/x/net/html/atom\"\n\n// Section 12.2.4.2 of the HTML5 specification says \"The following elements\n// have varying levels of special parsing rules\".\n// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements\nvar isSpecialElementMap = map[string]bool{\n\t\"address\":    true,\n\t\"applet\":     true,\n\t\"area\":       true,\n\t\"article\":    true,\n\t\"aside\":      true,\n\t\"base\":       true,\n\t\"basefont\":   true,\n\t\"bgsound\":    true,\n\t\"blockquote\": true,\n\t\"body\":       true,\n\t\"br\":         true,\n\t\"button\":     true,\n\t\"caption\":    true,\n\t\"center\":     true,\n\t\"col\":        true,\n\t\"colgroup\":   true,\n\t\"dd\":         true,\n\t\"details\":    true,\n\t\"dir\":        true,\n\t\"div\":        true,\n\t\"dl\":         true,\n\t\"dt\":         true,\n\t\"embed\":      true,\n\t\"fieldset\":   true,\n\t\"figcaption\": true,\n\t\"figure\":     true,\n\t\"footer\":     true,\n\t\"form\":       true,\n\t\"frame\":      true,\n\t\"frameset\":   true,\n\t\"h1\":         true,\n\t\"h2\":         true,\n\t\"h3\":         true,\n\t\"h4\":         true,\n\t\"h5\":         true,\n\t\"h6\":         true,\n\t\"head\":       true,\n\t\"header\":     true,\n\t\"hgroup\":     true,\n\t\"hr\":         true,\n\t\"html\":       true,\n\t\"iframe\":     true,\n\t\"img\":        true,\n\t\"input\":      true,\n\t\"keygen\":     true, // \"keygen\" has been removed from the spec, but are kept here for backwards compatibility.\n\t\"li\":         true,\n\t\"link\":       true,\n\t\"listing\":    true,\n\t\"main\":       true,\n\t\"marquee\":    true,\n\t\"menu\":       true,\n\t\"meta\":       true,\n\t\"nav\":        true,\n\t\"noembed\":    true,\n\t\"noframes\":   true,\n\t\"noscript\":   true,\n\t\"object\":     true,\n\t\"ol\":         true,\n\t\"p\":          true,\n\t\"param\":      true,\n\t\"plaintext\":  true,\n\t\"pre\":        true,\n\t\"script\":     true,\n\t\"section\":    true,\n\t\"select\":     true,\n\t\"source\":     true,\n\t\"style\":      true,\n\t\"summary\":    true,\n\t\"table\":      true,\n\t\"tbody\":      true,\n\t\"td\":         true,\n\t\"template\":   true,\n\t\"textarea\":   true,\n\t\"tfoot\":      true,\n\t\"th\":         true,\n\t\"thead\":      true,\n\t\"title\":      true,\n\t\"tr\":         true,\n\t\"track\":      true,\n\t\"ul\":         true,\n\t\"wbr\":        true,\n\t\"xmp\":        true,\n}\n\nfunc isSpecialElement(element *Node) bool {\n\tswitch element.Namespace {\n\tcase \"\", \"html\":\n\t\treturn isSpecialElementMap[element.Data]\n\tcase \"math\":\n\t\tswitch element.Data {\n\t\tcase \"mi\", \"mo\", \"mn\", \"ms\", \"mtext\", \"annotation-xml\":\n\t\t\treturn true\n\t\t}\n\tcase \"svg\":\n\t\tswitch element.Data {\n\t\tcase \"foreignObject\", \"desc\", \"title\":\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nvar knownDirectiveMap = map[string]bool{\n\t\"client:load\":    true,\n\t\"client:idle\":    true,\n\t\"client:visible\": true,\n\t\"client:only\":    true,\n\t\"class:list\":     true,\n\t\"set:text\":       true,\n\t\"set:html\":       true,\n}\n\nfunc IsKnownDirective(element *Node, attr *Attribute) bool {\n\tif knownDirectiveMap[attr.Key] {\n\t\treturn true\n\t}\n\tif element.DataAtom == a.Script {\n\t\treturn attr.Key == \"hoist\"\n\t}\n\tif element.DataAtom == a.Style {\n\t\treturn attr.Key == \"global\"\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "internal/doc.go",
    "content": "// Copyright 2012 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\n// This example demonstrates parsing HTML data and walking the resulting tree.\npackage astro\n"
  },
  {
    "path": "internal/doctype.go",
    "content": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\nimport (\n\t\"strings\"\n)\n\n// parseDoctype parses the data from a DoctypeToken into a name,\n// public identifier, and system identifier. It returns a Node whose Type\n// is DoctypeNode, whose Data is the name, and which has attributes\n// named \"system\" and \"public\" for the two identifiers if they were present.\n// quirks is whether the document should be parsed in \"quirks mode\".\nfunc parseDoctype(s string) (n *Node, quirks bool) {\n\tn = &Node{Type: DoctypeNode}\n\n\t// Find the name.\n\tspace := strings.IndexAny(s, whitespace)\n\tif space == -1 {\n\t\tspace = len(s)\n\t}\n\tn.Data = s[:space]\n\t// The comparison to \"html\" is case-sensitive.\n\tif n.Data != \"html\" {\n\t\tquirks = true\n\t}\n\tn.Data = strings.ToLower(n.Data)\n\ts = strings.TrimLeft(s[space:], whitespace)\n\n\tif len(s) < 6 {\n\t\t// It can't start with \"PUBLIC\" or \"SYSTEM\".\n\t\t// Ignore the rest of the string.\n\t\treturn n, quirks || s != \"\"\n\t}\n\n\tkey := strings.ToLower(s[:6])\n\ts = s[6:]\n\tfor key == \"public\" || key == \"system\" {\n\t\ts = strings.TrimLeft(s, whitespace)\n\t\tif s == \"\" {\n\t\t\tbreak\n\t\t}\n\t\tquote := s[0]\n\t\tif quote != '\"' && quote != '\\'' {\n\t\t\tbreak\n\t\t}\n\t\ts = s[1:]\n\t\tq := strings.IndexRune(s, rune(quote))\n\t\tvar id string\n\t\tif q == -1 {\n\t\t\tid = s\n\t\t\ts = \"\"\n\t\t} else {\n\t\t\tid = s[:q]\n\t\t\ts = s[q+1:]\n\t\t}\n\t\tn.Attr = append(n.Attr, Attribute{Key: key, Val: id})\n\t\tif key == \"public\" {\n\t\t\tkey = \"system\"\n\t\t} else {\n\t\t\tkey = \"\"\n\t\t}\n\t}\n\n\tif key != \"\" || s != \"\" {\n\t\tquirks = true\n\t} else if len(n.Attr) > 0 {\n\t\tif n.Attr[0].Key == \"public\" {\n\t\t\tpublic := strings.ToLower(n.Attr[0].Val)\n\t\t\tswitch public {\n\t\t\tcase \"-//w3o//dtd w3 html strict 3.0//en//\", \"-/w3d/dtd html 4.0 transitional/en\", \"html\":\n\t\t\t\tquirks = true\n\t\t\tdefault:\n\t\t\t\tfor _, q := range quirkyIDs {\n\t\t\t\t\tif strings.HasPrefix(public, q) {\n\t\t\t\t\t\tquirks = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// The following two public IDs only cause quirks mode if there is no system ID.\n\t\t\tif len(n.Attr) == 1 && (strings.HasPrefix(public, \"-//w3c//dtd html 4.01 frameset//\") ||\n\t\t\t\tstrings.HasPrefix(public, \"-//w3c//dtd html 4.01 transitional//\")) {\n\t\t\t\tquirks = true\n\t\t\t}\n\t\t}\n\t\tif lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == \"system\" &&\n\t\t\tstrings.ToLower(lastAttr.Val) == \"http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd\" {\n\t\t\tquirks = true\n\t\t}\n\t}\n\n\treturn n, quirks\n}\n\n// quirkyIDs is a list of public doctype identifiers that cause a document\n// to be interpreted in quirks mode. The identifiers should be in lower case.\nvar quirkyIDs = []string{\n\t\"+//silmaril//dtd html pro v0r11 19970101//\",\n\t\"-//advasoft ltd//dtd html 3.0 aswedit + extensions//\",\n\t\"-//as//dtd html 3.0 aswedit + extensions//\",\n\t\"-//ietf//dtd html 2.0 level 1//\",\n\t\"-//ietf//dtd html 2.0 level 2//\",\n\t\"-//ietf//dtd html 2.0 strict level 1//\",\n\t\"-//ietf//dtd html 2.0 strict level 2//\",\n\t\"-//ietf//dtd html 2.0 strict//\",\n\t\"-//ietf//dtd html 2.0//\",\n\t\"-//ietf//dtd html 2.1e//\",\n\t\"-//ietf//dtd html 3.0//\",\n\t\"-//ietf//dtd html 3.2 final//\",\n\t\"-//ietf//dtd html 3.2//\",\n\t\"-//ietf//dtd html 3//\",\n\t\"-//ietf//dtd html level 0//\",\n\t\"-//ietf//dtd html level 1//\",\n\t\"-//ietf//dtd html level 2//\",\n\t\"-//ietf//dtd html level 3//\",\n\t\"-//ietf//dtd html strict level 0//\",\n\t\"-//ietf//dtd html strict level 1//\",\n\t\"-//ietf//dtd html strict level 2//\",\n\t\"-//ietf//dtd html strict level 3//\",\n\t\"-//ietf//dtd html strict//\",\n\t\"-//ietf//dtd html//\",\n\t\"-//metrius//dtd metrius presentational//\",\n\t\"-//microsoft//dtd internet explorer 2.0 html strict//\",\n\t\"-//microsoft//dtd internet explorer 2.0 html//\",\n\t\"-//microsoft//dtd internet explorer 2.0 tables//\",\n\t\"-//microsoft//dtd internet explorer 3.0 html strict//\",\n\t\"-//microsoft//dtd internet explorer 3.0 html//\",\n\t\"-//microsoft//dtd internet explorer 3.0 tables//\",\n\t\"-//netscape comm. corp.//dtd html//\",\n\t\"-//netscape comm. corp.//dtd strict html//\",\n\t\"-//o'reilly and associates//dtd html 2.0//\",\n\t\"-//o'reilly and associates//dtd html extended 1.0//\",\n\t\"-//o'reilly and associates//dtd html extended relaxed 1.0//\",\n\t\"-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//\",\n\t\"-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//\",\n\t\"-//spyglass//dtd html 2.0 extended//\",\n\t\"-//sq//dtd html 2.0 hotmetal + extensions//\",\n\t\"-//sun microsystems corp.//dtd hotjava html//\",\n\t\"-//sun microsystems corp.//dtd hotjava strict html//\",\n\t\"-//w3c//dtd html 3 1995-03-24//\",\n\t\"-//w3c//dtd html 3.2 draft//\",\n\t\"-//w3c//dtd html 3.2 final//\",\n\t\"-//w3c//dtd html 3.2//\",\n\t\"-//w3c//dtd html 3.2s draft//\",\n\t\"-//w3c//dtd html 4.0 frameset//\",\n\t\"-//w3c//dtd html 4.0 transitional//\",\n\t\"-//w3c//dtd html experimental 19960712//\",\n\t\"-//w3c//dtd html experimental 970421//\",\n\t\"-//w3c//dtd w3 html//\",\n\t\"-//w3o//dtd w3 html 3.0//\",\n\t\"-//webtechs//dtd mozilla html 2.0//\",\n\t\"-//webtechs//dtd mozilla html//\",\n}\n"
  },
  {
    "path": "internal/entity.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\n// All entities that do not end with ';' are 6 or fewer bytes long.\nconst longestEntityWithoutSemicolon = 6\n\n// entity is a map from HTML entity names to their values. The semicolon matters:\n// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references\n// lists both \"amp\" and \"amp;\" as two separate entries.\n//\n// Note that the HTML5 list is larger than the HTML4 list at\n// http://www.w3.org/TR/html4/sgml/entities.html\nvar entity = map[string]rune{\n\t\"AElig;\":                           '\\U000000C6',\n\t\"AMP;\":                             '\\U00000026',\n\t\"Aacute;\":                          '\\U000000C1',\n\t\"Abreve;\":                          '\\U00000102',\n\t\"Acirc;\":                           '\\U000000C2',\n\t\"Acy;\":                             '\\U00000410',\n\t\"Afr;\":                             '\\U0001D504',\n\t\"Agrave;\":                          '\\U000000C0',\n\t\"Alpha;\":                           '\\U00000391',\n\t\"Amacr;\":                           '\\U00000100',\n\t\"And;\":                             '\\U00002A53',\n\t\"Aogon;\":                           '\\U00000104',\n\t\"Aopf;\":                            '\\U0001D538',\n\t\"ApplyFunction;\":                   '\\U00002061',\n\t\"Aring;\":                           '\\U000000C5',\n\t\"Ascr;\":                            '\\U0001D49C',\n\t\"Assign;\":                          '\\U00002254',\n\t\"Atilde;\":                          '\\U000000C3',\n\t\"Auml;\":                            '\\U000000C4',\n\t\"Backslash;\":                       '\\U00002216',\n\t\"Barv;\":                            '\\U00002AE7',\n\t\"Barwed;\":                          '\\U00002306',\n\t\"Bcy;\":                             '\\U00000411',\n\t\"Because;\":                         '\\U00002235',\n\t\"Bernoullis;\":                      '\\U0000212C',\n\t\"Beta;\":                            '\\U00000392',\n\t\"Bfr;\":                             '\\U0001D505',\n\t\"Bopf;\":                            '\\U0001D539',\n\t\"Breve;\":                           '\\U000002D8',\n\t\"Bscr;\":                            '\\U0000212C',\n\t\"Bumpeq;\":                          '\\U0000224E',\n\t\"CHcy;\":                            '\\U00000427',\n\t\"COPY;\":                            '\\U000000A9',\n\t\"Cacute;\":                          '\\U00000106',\n\t\"Cap;\":                             '\\U000022D2',\n\t\"CapitalDifferentialD;\":            '\\U00002145',\n\t\"Cayleys;\":                         '\\U0000212D',\n\t\"Ccaron;\":                          '\\U0000010C',\n\t\"Ccedil;\":                          '\\U000000C7',\n\t\"Ccirc;\":                           '\\U00000108',\n\t\"Cconint;\":                         '\\U00002230',\n\t\"Cdot;\":                            '\\U0000010A',\n\t\"Cedilla;\":                         '\\U000000B8',\n\t\"CenterDot;\":                       '\\U000000B7',\n\t\"Cfr;\":                             '\\U0000212D',\n\t\"Chi;\":                             '\\U000003A7',\n\t\"CircleDot;\":                       '\\U00002299',\n\t\"CircleMinus;\":                     '\\U00002296',\n\t\"CirclePlus;\":                      '\\U00002295',\n\t\"CircleTimes;\":                     '\\U00002297',\n\t\"ClockwiseContourIntegral;\":        '\\U00002232',\n\t\"CloseCurlyDoubleQuote;\":           '\\U0000201D',\n\t\"CloseCurlyQuote;\":                 '\\U00002019',\n\t\"Colon;\":                           '\\U00002237',\n\t\"Colone;\":                          '\\U00002A74',\n\t\"Congruent;\":                       '\\U00002261',\n\t\"Conint;\":                          '\\U0000222F',\n\t\"ContourIntegral;\":                 '\\U0000222E',\n\t\"Copf;\":                            '\\U00002102',\n\t\"Coproduct;\":                       '\\U00002210',\n\t\"CounterClockwiseContourIntegral;\": '\\U00002233',\n\t\"Cross;\":                           '\\U00002A2F',\n\t\"Cscr;\":                            '\\U0001D49E',\n\t\"Cup;\":                             '\\U000022D3',\n\t\"CupCap;\":                          '\\U0000224D',\n\t\"DD;\":                              '\\U00002145',\n\t\"DDotrahd;\":                        '\\U00002911',\n\t\"DJcy;\":                            '\\U00000402',\n\t\"DScy;\":                            '\\U00000405',\n\t\"DZcy;\":                            '\\U0000040F',\n\t\"Dagger;\":                          '\\U00002021',\n\t\"Darr;\":                            '\\U000021A1',\n\t\"Dashv;\":                           '\\U00002AE4',\n\t\"Dcaron;\":                          '\\U0000010E',\n\t\"Dcy;\":                             '\\U00000414',\n\t\"Del;\":                             '\\U00002207',\n\t\"Delta;\":                           '\\U00000394',\n\t\"Dfr;\":                             '\\U0001D507',\n\t\"DiacriticalAcute;\":                '\\U000000B4',\n\t\"DiacriticalDot;\":                  '\\U000002D9',\n\t\"DiacriticalDoubleAcute;\":          '\\U000002DD',\n\t\"DiacriticalGrave;\":                '\\U00000060',\n\t\"DiacriticalTilde;\":                '\\U000002DC',\n\t\"Diamond;\":                         '\\U000022C4',\n\t\"DifferentialD;\":                   '\\U00002146',\n\t\"Dopf;\":                            '\\U0001D53B',\n\t\"Dot;\":                             '\\U000000A8',\n\t\"DotDot;\":                          '\\U000020DC',\n\t\"DotEqual;\":                        '\\U00002250',\n\t\"DoubleContourIntegral;\":           '\\U0000222F',\n\t\"DoubleDot;\":                       '\\U000000A8',\n\t\"DoubleDownArrow;\":                 '\\U000021D3',\n\t\"DoubleLeftArrow;\":                 '\\U000021D0',\n\t\"DoubleLeftRightArrow;\":            '\\U000021D4',\n\t\"DoubleLeftTee;\":                   '\\U00002AE4',\n\t\"DoubleLongLeftArrow;\":             '\\U000027F8',\n\t\"DoubleLongLeftRightArrow;\":        '\\U000027FA',\n\t\"DoubleLongRightArrow;\":            '\\U000027F9',\n\t\"DoubleRightArrow;\":                '\\U000021D2',\n\t\"DoubleRightTee;\":                  '\\U000022A8',\n\t\"DoubleUpArrow;\":                   '\\U000021D1',\n\t\"DoubleUpDownArrow;\":               '\\U000021D5',\n\t\"DoubleVerticalBar;\":               '\\U00002225',\n\t\"DownArrow;\":                       '\\U00002193',\n\t\"DownArrowBar;\":                    '\\U00002913',\n\t\"DownArrowUpArrow;\":                '\\U000021F5',\n\t\"DownBreve;\":                       '\\U00000311',\n\t\"DownLeftRightVector;\":             '\\U00002950',\n\t\"DownLeftTeeVector;\":               '\\U0000295E',\n\t\"DownLeftVector;\":                  '\\U000021BD',\n\t\"DownLeftVectorBar;\":               '\\U00002956',\n\t\"DownRightTeeVector;\":              '\\U0000295F',\n\t\"DownRightVector;\":                 '\\U000021C1',\n\t\"DownRightVectorBar;\":              '\\U00002957',\n\t\"DownTee;\":                         '\\U000022A4',\n\t\"DownTeeArrow;\":                    '\\U000021A7',\n\t\"Downarrow;\":                       '\\U000021D3',\n\t\"Dscr;\":                            '\\U0001D49F',\n\t\"Dstrok;\":                          '\\U00000110',\n\t\"ENG;\":                             '\\U0000014A',\n\t\"ETH;\":                             '\\U000000D0',\n\t\"Eacute;\":                          '\\U000000C9',\n\t\"Ecaron;\":                          '\\U0000011A',\n\t\"Ecirc;\":                           '\\U000000CA',\n\t\"Ecy;\":                             '\\U0000042D',\n\t\"Edot;\":                            '\\U00000116',\n\t\"Efr;\":                             '\\U0001D508',\n\t\"Egrave;\":                          '\\U000000C8',\n\t\"Element;\":                         '\\U00002208',\n\t\"Emacr;\":                           '\\U00000112',\n\t\"EmptySmallSquare;\":                '\\U000025FB',\n\t\"EmptyVerySmallSquare;\":            '\\U000025AB',\n\t\"Eogon;\":                           '\\U00000118',\n\t\"Eopf;\":                            '\\U0001D53C',\n\t\"Epsilon;\":                         '\\U00000395',\n\t\"Equal;\":                           '\\U00002A75',\n\t\"EqualTilde;\":                      '\\U00002242',\n\t\"Equilibrium;\":                     '\\U000021CC',\n\t\"Escr;\":                            '\\U00002130',\n\t\"Esim;\":                            '\\U00002A73',\n\t\"Eta;\":                             '\\U00000397',\n\t\"Euml;\":                            '\\U000000CB',\n\t\"Exists;\":                          '\\U00002203',\n\t\"ExponentialE;\":                    '\\U00002147',\n\t\"Fcy;\":                             '\\U00000424',\n\t\"Ffr;\":                             '\\U0001D509',\n\t\"FilledSmallSquare;\":               '\\U000025FC',\n\t\"FilledVerySmallSquare;\":           '\\U000025AA',\n\t\"Fopf;\":                            '\\U0001D53D',\n\t\"ForAll;\":                          '\\U00002200',\n\t\"Fouriertrf;\":                      '\\U00002131',\n\t\"Fscr;\":                            '\\U00002131',\n\t\"GJcy;\":                            '\\U00000403',\n\t\"GT;\":                              '\\U0000003E',\n\t\"Gamma;\":                           '\\U00000393',\n\t\"Gammad;\":                          '\\U000003DC',\n\t\"Gbreve;\":                          '\\U0000011E',\n\t\"Gcedil;\":                          '\\U00000122',\n\t\"Gcirc;\":                           '\\U0000011C',\n\t\"Gcy;\":                             '\\U00000413',\n\t\"Gdot;\":                            '\\U00000120',\n\t\"Gfr;\":                             '\\U0001D50A',\n\t\"Gg;\":                              '\\U000022D9',\n\t\"Gopf;\":                            '\\U0001D53E',\n\t\"GreaterEqual;\":                    '\\U00002265',\n\t\"GreaterEqualLess;\":                '\\U000022DB',\n\t\"GreaterFullEqual;\":                '\\U00002267',\n\t\"GreaterGreater;\":                  '\\U00002AA2',\n\t\"GreaterLess;\":                     '\\U00002277',\n\t\"GreaterSlantEqual;\":               '\\U00002A7E',\n\t\"GreaterTilde;\":                    '\\U00002273',\n\t\"Gscr;\":                            '\\U0001D4A2',\n\t\"Gt;\":                              '\\U0000226B',\n\t\"HARDcy;\":                          '\\U0000042A',\n\t\"Hacek;\":                           '\\U000002C7',\n\t\"Hat;\":                             '\\U0000005E',\n\t\"Hcirc;\":                           '\\U00000124',\n\t\"Hfr;\":                             '\\U0000210C',\n\t\"HilbertSpace;\":                    '\\U0000210B',\n\t\"Hopf;\":                            '\\U0000210D',\n\t\"HorizontalLine;\":                  '\\U00002500',\n\t\"Hscr;\":                            '\\U0000210B',\n\t\"Hstrok;\":                          '\\U00000126',\n\t\"HumpDownHump;\":                    '\\U0000224E',\n\t\"HumpEqual;\":                       '\\U0000224F',\n\t\"IEcy;\":                            '\\U00000415',\n\t\"IJlig;\":                           '\\U00000132',\n\t\"IOcy;\":                            '\\U00000401',\n\t\"Iacute;\":                          '\\U000000CD',\n\t\"Icirc;\":                           '\\U000000CE',\n\t\"Icy;\":                             '\\U00000418',\n\t\"Idot;\":                            '\\U00000130',\n\t\"Ifr;\":                             '\\U00002111',\n\t\"Igrave;\":                          '\\U000000CC',\n\t\"Im;\":                              '\\U00002111',\n\t\"Imacr;\":                           '\\U0000012A',\n\t\"ImaginaryI;\":                      '\\U00002148',\n\t\"Implies;\":                         '\\U000021D2',\n\t\"Int;\":                             '\\U0000222C',\n\t\"Integral;\":                        '\\U0000222B',\n\t\"Intersection;\":                    '\\U000022C2',\n\t\"InvisibleComma;\":                  '\\U00002063',\n\t\"InvisibleTimes;\":                  '\\U00002062',\n\t\"Iogon;\":                           '\\U0000012E',\n\t\"Iopf;\":                            '\\U0001D540',\n\t\"Iota;\":                            '\\U00000399',\n\t\"Iscr;\":                            '\\U00002110',\n\t\"Itilde;\":                          '\\U00000128',\n\t\"Iukcy;\":                           '\\U00000406',\n\t\"Iuml;\":                            '\\U000000CF',\n\t\"Jcirc;\":                           '\\U00000134',\n\t\"Jcy;\":                             '\\U00000419',\n\t\"Jfr;\":                             '\\U0001D50D',\n\t\"Jopf;\":                            '\\U0001D541',\n\t\"Jscr;\":                            '\\U0001D4A5',\n\t\"Jsercy;\":                          '\\U00000408',\n\t\"Jukcy;\":                           '\\U00000404',\n\t\"KHcy;\":                            '\\U00000425',\n\t\"KJcy;\":                            '\\U0000040C',\n\t\"Kappa;\":                           '\\U0000039A',\n\t\"Kcedil;\":                          '\\U00000136',\n\t\"Kcy;\":                             '\\U0000041A',\n\t\"Kfr;\":                             '\\U0001D50E',\n\t\"Kopf;\":                            '\\U0001D542',\n\t\"Kscr;\":                            '\\U0001D4A6',\n\t\"LJcy;\":                            '\\U00000409',\n\t\"LT;\":                              '\\U0000003C',\n\t\"Lacute;\":                          '\\U00000139',\n\t\"Lambda;\":                          '\\U0000039B',\n\t\"Lang;\":                            '\\U000027EA',\n\t\"Laplacetrf;\":                      '\\U00002112',\n\t\"Larr;\":                            '\\U0000219E',\n\t\"Lcaron;\":                          '\\U0000013D',\n\t\"Lcedil;\":                          '\\U0000013B',\n\t\"Lcy;\":                             '\\U0000041B',\n\t\"LeftAngleBracket;\":                '\\U000027E8',\n\t\"LeftArrow;\":                       '\\U00002190',\n\t\"LeftArrowBar;\":                    '\\U000021E4',\n\t\"LeftArrowRightArrow;\":             '\\U000021C6',\n\t\"LeftCeiling;\":                     '\\U00002308',\n\t\"LeftDoubleBracket;\":               '\\U000027E6',\n\t\"LeftDownTeeVector;\":               '\\U00002961',\n\t\"LeftDownVector;\":                  '\\U000021C3',\n\t\"LeftDownVectorBar;\":               '\\U00002959',\n\t\"LeftFloor;\":                       '\\U0000230A',\n\t\"LeftRightArrow;\":                  '\\U00002194',\n\t\"LeftRightVector;\":                 '\\U0000294E',\n\t\"LeftTee;\":                         '\\U000022A3',\n\t\"LeftTeeArrow;\":                    '\\U000021A4',\n\t\"LeftTeeVector;\":                   '\\U0000295A',\n\t\"LeftTriangle;\":                    '\\U000022B2',\n\t\"LeftTriangleBar;\":                 '\\U000029CF',\n\t\"LeftTriangleEqual;\":               '\\U000022B4',\n\t\"LeftUpDownVector;\":                '\\U00002951',\n\t\"LeftUpTeeVector;\":                 '\\U00002960',\n\t\"LeftUpVector;\":                    '\\U000021BF',\n\t\"LeftUpVectorBar;\":                 '\\U00002958',\n\t\"LeftVector;\":                      '\\U000021BC',\n\t\"LeftVectorBar;\":                   '\\U00002952',\n\t\"Leftarrow;\":                       '\\U000021D0',\n\t\"Leftrightarrow;\":                  '\\U000021D4',\n\t\"LessEqualGreater;\":                '\\U000022DA',\n\t\"LessFullEqual;\":                   '\\U00002266',\n\t\"LessGreater;\":                     '\\U00002276',\n\t\"LessLess;\":                        '\\U00002AA1',\n\t\"LessSlantEqual;\":                  '\\U00002A7D',\n\t\"LessTilde;\":                       '\\U00002272',\n\t\"Lfr;\":                             '\\U0001D50F',\n\t\"Ll;\":                              '\\U000022D8',\n\t\"Lleftarrow;\":                      '\\U000021DA',\n\t\"Lmidot;\":                          '\\U0000013F',\n\t\"LongLeftArrow;\":                   '\\U000027F5',\n\t\"LongLeftRightArrow;\":              '\\U000027F7',\n\t\"LongRightArrow;\":                  '\\U000027F6',\n\t\"Longleftarrow;\":                   '\\U000027F8',\n\t\"Longleftrightarrow;\":              '\\U000027FA',\n\t\"Longrightarrow;\":                  '\\U000027F9',\n\t\"Lopf;\":                            '\\U0001D543',\n\t\"LowerLeftArrow;\":                  '\\U00002199',\n\t\"LowerRightArrow;\":                 '\\U00002198',\n\t\"Lscr;\":                            '\\U00002112',\n\t\"Lsh;\":                             '\\U000021B0',\n\t\"Lstrok;\":                          '\\U00000141',\n\t\"Lt;\":                              '\\U0000226A',\n\t\"Map;\":                             '\\U00002905',\n\t\"Mcy;\":                             '\\U0000041C',\n\t\"MediumSpace;\":                     '\\U0000205F',\n\t\"Mellintrf;\":                       '\\U00002133',\n\t\"Mfr;\":                             '\\U0001D510',\n\t\"MinusPlus;\":                       '\\U00002213',\n\t\"Mopf;\":                            '\\U0001D544',\n\t\"Mscr;\":                            '\\U00002133',\n\t\"Mu;\":                              '\\U0000039C',\n\t\"NJcy;\":                            '\\U0000040A',\n\t\"Nacute;\":                          '\\U00000143',\n\t\"Ncaron;\":                          '\\U00000147',\n\t\"Ncedil;\":                          '\\U00000145',\n\t\"Ncy;\":                             '\\U0000041D',\n\t\"NegativeMediumSpace;\":             '\\U0000200B',\n\t\"NegativeThickSpace;\":              '\\U0000200B',\n\t\"NegativeThinSpace;\":               '\\U0000200B',\n\t\"NegativeVeryThinSpace;\":           '\\U0000200B',\n\t\"NestedGreaterGreater;\":            '\\U0000226B',\n\t\"NestedLessLess;\":                  '\\U0000226A',\n\t\"NewLine;\":                         '\\U0000000A',\n\t\"Nfr;\":                             '\\U0001D511',\n\t\"NoBreak;\":                         '\\U00002060',\n\t\"NonBreakingSpace;\":                '\\U000000A0',\n\t\"Nopf;\":                            '\\U00002115',\n\t\"Not;\":                             '\\U00002AEC',\n\t\"NotCongruent;\":                    '\\U00002262',\n\t\"NotCupCap;\":                       '\\U0000226D',\n\t\"NotDoubleVerticalBar;\":            '\\U00002226',\n\t\"NotElement;\":                      '\\U00002209',\n\t\"NotEqual;\":                        '\\U00002260',\n\t\"NotExists;\":                       '\\U00002204',\n\t\"NotGreater;\":                      '\\U0000226F',\n\t\"NotGreaterEqual;\":                 '\\U00002271',\n\t\"NotGreaterLess;\":                  '\\U00002279',\n\t\"NotGreaterTilde;\":                 '\\U00002275',\n\t\"NotLeftTriangle;\":                 '\\U000022EA',\n\t\"NotLeftTriangleEqual;\":            '\\U000022EC',\n\t\"NotLess;\":                         '\\U0000226E',\n\t\"NotLessEqual;\":                    '\\U00002270',\n\t\"NotLessGreater;\":                  '\\U00002278',\n\t\"NotLessTilde;\":                    '\\U00002274',\n\t\"NotPrecedes;\":                     '\\U00002280',\n\t\"NotPrecedesSlantEqual;\":           '\\U000022E0',\n\t\"NotReverseElement;\":               '\\U0000220C',\n\t\"NotRightTriangle;\":                '\\U000022EB',\n\t\"NotRightTriangleEqual;\":           '\\U000022ED',\n\t\"NotSquareSubsetEqual;\":            '\\U000022E2',\n\t\"NotSquareSupersetEqual;\":          '\\U000022E3',\n\t\"NotSubsetEqual;\":                  '\\U00002288',\n\t\"NotSucceeds;\":                     '\\U00002281',\n\t\"NotSucceedsSlantEqual;\":           '\\U000022E1',\n\t\"NotSupersetEqual;\":                '\\U00002289',\n\t\"NotTilde;\":                        '\\U00002241',\n\t\"NotTildeEqual;\":                   '\\U00002244',\n\t\"NotTildeFullEqual;\":               '\\U00002247',\n\t\"NotTildeTilde;\":                   '\\U00002249',\n\t\"NotVerticalBar;\":                  '\\U00002224',\n\t\"Nscr;\":                            '\\U0001D4A9',\n\t\"Ntilde;\":                          '\\U000000D1',\n\t\"Nu;\":                              '\\U0000039D',\n\t\"OElig;\":                           '\\U00000152',\n\t\"Oacute;\":                          '\\U000000D3',\n\t\"Ocirc;\":                           '\\U000000D4',\n\t\"Ocy;\":                             '\\U0000041E',\n\t\"Odblac;\":                          '\\U00000150',\n\t\"Ofr;\":                             '\\U0001D512',\n\t\"Ograve;\":                          '\\U000000D2',\n\t\"Omacr;\":                           '\\U0000014C',\n\t\"Omega;\":                           '\\U000003A9',\n\t\"Omicron;\":                         '\\U0000039F',\n\t\"Oopf;\":                            '\\U0001D546',\n\t\"OpenCurlyDoubleQuote;\":            '\\U0000201C',\n\t\"OpenCurlyQuote;\":                  '\\U00002018',\n\t\"Or;\":                              '\\U00002A54',\n\t\"Oscr;\":                            '\\U0001D4AA',\n\t\"Oslash;\":                          '\\U000000D8',\n\t\"Otilde;\":                          '\\U000000D5',\n\t\"Otimes;\":                          '\\U00002A37',\n\t\"Ouml;\":                            '\\U000000D6',\n\t\"OverBar;\":                         '\\U0000203E',\n\t\"OverBrace;\":                       '\\U000023DE',\n\t\"OverBracket;\":                     '\\U000023B4',\n\t\"OverParenthesis;\":                 '\\U000023DC',\n\t\"PartialD;\":                        '\\U00002202',\n\t\"Pcy;\":                             '\\U0000041F',\n\t\"Pfr;\":                             '\\U0001D513',\n\t\"Phi;\":                             '\\U000003A6',\n\t\"Pi;\":                              '\\U000003A0',\n\t\"PlusMinus;\":                       '\\U000000B1',\n\t\"Poincareplane;\":                   '\\U0000210C',\n\t\"Popf;\":                            '\\U00002119',\n\t\"Pr;\":                              '\\U00002ABB',\n\t\"Precedes;\":                        '\\U0000227A',\n\t\"PrecedesEqual;\":                   '\\U00002AAF',\n\t\"PrecedesSlantEqual;\":              '\\U0000227C',\n\t\"PrecedesTilde;\":                   '\\U0000227E',\n\t\"Prime;\":                           '\\U00002033',\n\t\"Product;\":                         '\\U0000220F',\n\t\"Proportion;\":                      '\\U00002237',\n\t\"Proportional;\":                    '\\U0000221D',\n\t\"Pscr;\":                            '\\U0001D4AB',\n\t\"Psi;\":                             '\\U000003A8',\n\t\"QUOT;\":                            '\\U00000022',\n\t\"Qfr;\":                             '\\U0001D514',\n\t\"Qopf;\":                            '\\U0000211A',\n\t\"Qscr;\":                            '\\U0001D4AC',\n\t\"RBarr;\":                           '\\U00002910',\n\t\"REG;\":                             '\\U000000AE',\n\t\"Racute;\":                          '\\U00000154',\n\t\"Rang;\":                            '\\U000027EB',\n\t\"Rarr;\":                            '\\U000021A0',\n\t\"Rarrtl;\":                          '\\U00002916',\n\t\"Rcaron;\":                          '\\U00000158',\n\t\"Rcedil;\":                          '\\U00000156',\n\t\"Rcy;\":                             '\\U00000420',\n\t\"Re;\":                              '\\U0000211C',\n\t\"ReverseElement;\":                  '\\U0000220B',\n\t\"ReverseEquilibrium;\":              '\\U000021CB',\n\t\"ReverseUpEquilibrium;\":            '\\U0000296F',\n\t\"Rfr;\":                             '\\U0000211C',\n\t\"Rho;\":                             '\\U000003A1',\n\t\"RightAngleBracket;\":               '\\U000027E9',\n\t\"RightArrow;\":                      '\\U00002192',\n\t\"RightArrowBar;\":                   '\\U000021E5',\n\t\"RightArrowLeftArrow;\":             '\\U000021C4',\n\t\"RightCeiling;\":                    '\\U00002309',\n\t\"RightDoubleBracket;\":              '\\U000027E7',\n\t\"RightDownTeeVector;\":              '\\U0000295D',\n\t\"RightDownVector;\":                 '\\U000021C2',\n\t\"RightDownVectorBar;\":              '\\U00002955',\n\t\"RightFloor;\":                      '\\U0000230B',\n\t\"RightTee;\":                        '\\U000022A2',\n\t\"RightTeeArrow;\":                   '\\U000021A6',\n\t\"RightTeeVector;\":                  '\\U0000295B',\n\t\"RightTriangle;\":                   '\\U000022B3',\n\t\"RightTriangleBar;\":                '\\U000029D0',\n\t\"RightTriangleEqual;\":              '\\U000022B5',\n\t\"RightUpDownVector;\":               '\\U0000294F',\n\t\"RightUpTeeVector;\":                '\\U0000295C',\n\t\"RightUpVector;\":                   '\\U000021BE',\n\t\"RightUpVectorBar;\":                '\\U00002954',\n\t\"RightVector;\":                     '\\U000021C0',\n\t\"RightVectorBar;\":                  '\\U00002953',\n\t\"Rightarrow;\":                      '\\U000021D2',\n\t\"Ropf;\":                            '\\U0000211D',\n\t\"RoundImplies;\":                    '\\U00002970',\n\t\"Rrightarrow;\":                     '\\U000021DB',\n\t\"Rscr;\":                            '\\U0000211B',\n\t\"Rsh;\":                             '\\U000021B1',\n\t\"RuleDelayed;\":                     '\\U000029F4',\n\t\"SHCHcy;\":                          '\\U00000429',\n\t\"SHcy;\":                            '\\U00000428',\n\t\"SOFTcy;\":                          '\\U0000042C',\n\t\"Sacute;\":                          '\\U0000015A',\n\t\"Sc;\":                              '\\U00002ABC',\n\t\"Scaron;\":                          '\\U00000160',\n\t\"Scedil;\":                          '\\U0000015E',\n\t\"Scirc;\":                           '\\U0000015C',\n\t\"Scy;\":                             '\\U00000421',\n\t\"Sfr;\":                             '\\U0001D516',\n\t\"ShortDownArrow;\":                  '\\U00002193',\n\t\"ShortLeftArrow;\":                  '\\U00002190',\n\t\"ShortRightArrow;\":                 '\\U00002192',\n\t\"ShortUpArrow;\":                    '\\U00002191',\n\t\"Sigma;\":                           '\\U000003A3',\n\t\"SmallCircle;\":                     '\\U00002218',\n\t\"Sopf;\":                            '\\U0001D54A',\n\t\"Sqrt;\":                            '\\U0000221A',\n\t\"Square;\":                          '\\U000025A1',\n\t\"SquareIntersection;\":              '\\U00002293',\n\t\"SquareSubset;\":                    '\\U0000228F',\n\t\"SquareSubsetEqual;\":               '\\U00002291',\n\t\"SquareSuperset;\":                  '\\U00002290',\n\t\"SquareSupersetEqual;\":             '\\U00002292',\n\t\"SquareUnion;\":                     '\\U00002294',\n\t\"Sscr;\":                            '\\U0001D4AE',\n\t\"Star;\":                            '\\U000022C6',\n\t\"Sub;\":                             '\\U000022D0',\n\t\"Subset;\":                          '\\U000022D0',\n\t\"SubsetEqual;\":                     '\\U00002286',\n\t\"Succeeds;\":                        '\\U0000227B',\n\t\"SucceedsEqual;\":                   '\\U00002AB0',\n\t\"SucceedsSlantEqual;\":              '\\U0000227D',\n\t\"SucceedsTilde;\":                   '\\U0000227F',\n\t\"SuchThat;\":                        '\\U0000220B',\n\t\"Sum;\":                             '\\U00002211',\n\t\"Sup;\":                             '\\U000022D1',\n\t\"Superset;\":                        '\\U00002283',\n\t\"SupersetEqual;\":                   '\\U00002287',\n\t\"Supset;\":                          '\\U000022D1',\n\t\"THORN;\":                           '\\U000000DE',\n\t\"TRADE;\":                           '\\U00002122',\n\t\"TSHcy;\":                           '\\U0000040B',\n\t\"TScy;\":                            '\\U00000426',\n\t\"Tab;\":                             '\\U00000009',\n\t\"Tau;\":                             '\\U000003A4',\n\t\"Tcaron;\":                          '\\U00000164',\n\t\"Tcedil;\":                          '\\U00000162',\n\t\"Tcy;\":                             '\\U00000422',\n\t\"Tfr;\":                             '\\U0001D517',\n\t\"Therefore;\":                       '\\U00002234',\n\t\"Theta;\":                           '\\U00000398',\n\t\"ThinSpace;\":                       '\\U00002009',\n\t\"Tilde;\":                           '\\U0000223C',\n\t\"TildeEqual;\":                      '\\U00002243',\n\t\"TildeFullEqual;\":                  '\\U00002245',\n\t\"TildeTilde;\":                      '\\U00002248',\n\t\"Topf;\":                            '\\U0001D54B',\n\t\"TripleDot;\":                       '\\U000020DB',\n\t\"Tscr;\":                            '\\U0001D4AF',\n\t\"Tstrok;\":                          '\\U00000166',\n\t\"Uacute;\":                          '\\U000000DA',\n\t\"Uarr;\":                            '\\U0000219F',\n\t\"Uarrocir;\":                        '\\U00002949',\n\t\"Ubrcy;\":                           '\\U0000040E',\n\t\"Ubreve;\":                          '\\U0000016C',\n\t\"Ucirc;\":                           '\\U000000DB',\n\t\"Ucy;\":                             '\\U00000423',\n\t\"Udblac;\":                          '\\U00000170',\n\t\"Ufr;\":                             '\\U0001D518',\n\t\"Ugrave;\":                          '\\U000000D9',\n\t\"Umacr;\":                           '\\U0000016A',\n\t\"UnderBar;\":                        '\\U0000005F',\n\t\"UnderBrace;\":                      '\\U000023DF',\n\t\"UnderBracket;\":                    '\\U000023B5',\n\t\"UnderParenthesis;\":                '\\U000023DD',\n\t\"Union;\":                           '\\U000022C3',\n\t\"UnionPlus;\":                       '\\U0000228E',\n\t\"Uogon;\":                           '\\U00000172',\n\t\"Uopf;\":                            '\\U0001D54C',\n\t\"UpArrow;\":                         '\\U00002191',\n\t\"UpArrowBar;\":                      '\\U00002912',\n\t\"UpArrowDownArrow;\":                '\\U000021C5',\n\t\"UpDownArrow;\":                     '\\U00002195',\n\t\"UpEquilibrium;\":                   '\\U0000296E',\n\t\"UpTee;\":                           '\\U000022A5',\n\t\"UpTeeArrow;\":                      '\\U000021A5',\n\t\"Uparrow;\":                         '\\U000021D1',\n\t\"Updownarrow;\":                     '\\U000021D5',\n\t\"UpperLeftArrow;\":                  '\\U00002196',\n\t\"UpperRightArrow;\":                 '\\U00002197',\n\t\"Upsi;\":                            '\\U000003D2',\n\t\"Upsilon;\":                         '\\U000003A5',\n\t\"Uring;\":                           '\\U0000016E',\n\t\"Uscr;\":                            '\\U0001D4B0',\n\t\"Utilde;\":                          '\\U00000168',\n\t\"Uuml;\":                            '\\U000000DC',\n\t\"VDash;\":                           '\\U000022AB',\n\t\"Vbar;\":                            '\\U00002AEB',\n\t\"Vcy;\":                             '\\U00000412',\n\t\"Vdash;\":                           '\\U000022A9',\n\t\"Vdashl;\":                          '\\U00002AE6',\n\t\"Vee;\":                             '\\U000022C1',\n\t\"Verbar;\":                          '\\U00002016',\n\t\"Vert;\":                            '\\U00002016',\n\t\"VerticalBar;\":                     '\\U00002223',\n\t\"VerticalLine;\":                    '\\U0000007C',\n\t\"VerticalSeparator;\":               '\\U00002758',\n\t\"VerticalTilde;\":                   '\\U00002240',\n\t\"VeryThinSpace;\":                   '\\U0000200A',\n\t\"Vfr;\":                             '\\U0001D519',\n\t\"Vopf;\":                            '\\U0001D54D',\n\t\"Vscr;\":                            '\\U0001D4B1',\n\t\"Vvdash;\":                          '\\U000022AA',\n\t\"Wcirc;\":                           '\\U00000174',\n\t\"Wedge;\":                           '\\U000022C0',\n\t\"Wfr;\":                             '\\U0001D51A',\n\t\"Wopf;\":                            '\\U0001D54E',\n\t\"Wscr;\":                            '\\U0001D4B2',\n\t\"Xfr;\":                             '\\U0001D51B',\n\t\"Xi;\":                              '\\U0000039E',\n\t\"Xopf;\":                            '\\U0001D54F',\n\t\"Xscr;\":                            '\\U0001D4B3',\n\t\"YAcy;\":                            '\\U0000042F',\n\t\"YIcy;\":                            '\\U00000407',\n\t\"YUcy;\":                            '\\U0000042E',\n\t\"Yacute;\":                          '\\U000000DD',\n\t\"Ycirc;\":                           '\\U00000176',\n\t\"Ycy;\":                             '\\U0000042B',\n\t\"Yfr;\":                             '\\U0001D51C',\n\t\"Yopf;\":                            '\\U0001D550',\n\t\"Yscr;\":                            '\\U0001D4B4',\n\t\"Yuml;\":                            '\\U00000178',\n\t\"ZHcy;\":                            '\\U00000416',\n\t\"Zacute;\":                          '\\U00000179',\n\t\"Zcaron;\":                          '\\U0000017D',\n\t\"Zcy;\":                             '\\U00000417',\n\t\"Zdot;\":                            '\\U0000017B',\n\t\"ZeroWidthSpace;\":                  '\\U0000200B',\n\t\"Zeta;\":                            '\\U00000396',\n\t\"Zfr;\":                             '\\U00002128',\n\t\"Zopf;\":                            '\\U00002124',\n\t\"Zscr;\":                            '\\U0001D4B5',\n\t\"aacute;\":                          '\\U000000E1',\n\t\"abreve;\":                          '\\U00000103',\n\t\"ac;\":                              '\\U0000223E',\n\t\"acd;\":                             '\\U0000223F',\n\t\"acirc;\":                           '\\U000000E2',\n\t\"acute;\":                           '\\U000000B4',\n\t\"acy;\":                             '\\U00000430',\n\t\"aelig;\":                           '\\U000000E6',\n\t\"af;\":                              '\\U00002061',\n\t\"afr;\":                             '\\U0001D51E',\n\t\"agrave;\":                          '\\U000000E0',\n\t\"alefsym;\":                         '\\U00002135',\n\t\"aleph;\":                           '\\U00002135',\n\t\"alpha;\":                           '\\U000003B1',\n\t\"amacr;\":                           '\\U00000101',\n\t\"amalg;\":                           '\\U00002A3F',\n\t\"amp;\":                             '\\U00000026',\n\t\"and;\":                             '\\U00002227',\n\t\"andand;\":                          '\\U00002A55',\n\t\"andd;\":                            '\\U00002A5C',\n\t\"andslope;\":                        '\\U00002A58',\n\t\"andv;\":                            '\\U00002A5A',\n\t\"ang;\":                             '\\U00002220',\n\t\"ange;\":                            '\\U000029A4',\n\t\"angle;\":                           '\\U00002220',\n\t\"angmsd;\":                          '\\U00002221',\n\t\"angmsdaa;\":                        '\\U000029A8',\n\t\"angmsdab;\":                        '\\U000029A9',\n\t\"angmsdac;\":                        '\\U000029AA',\n\t\"angmsdad;\":                        '\\U000029AB',\n\t\"angmsdae;\":                        '\\U000029AC',\n\t\"angmsdaf;\":                        '\\U000029AD',\n\t\"angmsdag;\":                        '\\U000029AE',\n\t\"angmsdah;\":                        '\\U000029AF',\n\t\"angrt;\":                           '\\U0000221F',\n\t\"angrtvb;\":                         '\\U000022BE',\n\t\"angrtvbd;\":                        '\\U0000299D',\n\t\"angsph;\":                          '\\U00002222',\n\t\"angst;\":                           '\\U000000C5',\n\t\"angzarr;\":                         '\\U0000237C',\n\t\"aogon;\":                           '\\U00000105',\n\t\"aopf;\":                            '\\U0001D552',\n\t\"ap;\":                              '\\U00002248',\n\t\"apE;\":                             '\\U00002A70',\n\t\"apacir;\":                          '\\U00002A6F',\n\t\"ape;\":                             '\\U0000224A',\n\t\"apid;\":                            '\\U0000224B',\n\t\"apos;\":                            '\\U00000027',\n\t\"approx;\":                          '\\U00002248',\n\t\"approxeq;\":                        '\\U0000224A',\n\t\"aring;\":                           '\\U000000E5',\n\t\"ascr;\":                            '\\U0001D4B6',\n\t\"ast;\":                             '\\U0000002A',\n\t\"asymp;\":                           '\\U00002248',\n\t\"asympeq;\":                         '\\U0000224D',\n\t\"atilde;\":                          '\\U000000E3',\n\t\"auml;\":                            '\\U000000E4',\n\t\"awconint;\":                        '\\U00002233',\n\t\"awint;\":                           '\\U00002A11',\n\t\"bNot;\":                            '\\U00002AED',\n\t\"backcong;\":                        '\\U0000224C',\n\t\"backepsilon;\":                     '\\U000003F6',\n\t\"backprime;\":                       '\\U00002035',\n\t\"backsim;\":                         '\\U0000223D',\n\t\"backsimeq;\":                       '\\U000022CD',\n\t\"barvee;\":                          '\\U000022BD',\n\t\"barwed;\":                          '\\U00002305',\n\t\"barwedge;\":                        '\\U00002305',\n\t\"bbrk;\":                            '\\U000023B5',\n\t\"bbrktbrk;\":                        '\\U000023B6',\n\t\"bcong;\":                           '\\U0000224C',\n\t\"bcy;\":                             '\\U00000431',\n\t\"bdquo;\":                           '\\U0000201E',\n\t\"becaus;\":                          '\\U00002235',\n\t\"because;\":                         '\\U00002235',\n\t\"bemptyv;\":                         '\\U000029B0',\n\t\"bepsi;\":                           '\\U000003F6',\n\t\"bernou;\":                          '\\U0000212C',\n\t\"beta;\":                            '\\U000003B2',\n\t\"beth;\":                            '\\U00002136',\n\t\"between;\":                         '\\U0000226C',\n\t\"bfr;\":                             '\\U0001D51F',\n\t\"bigcap;\":                          '\\U000022C2',\n\t\"bigcirc;\":                         '\\U000025EF',\n\t\"bigcup;\":                          '\\U000022C3',\n\t\"bigodot;\":                         '\\U00002A00',\n\t\"bigoplus;\":                        '\\U00002A01',\n\t\"bigotimes;\":                       '\\U00002A02',\n\t\"bigsqcup;\":                        '\\U00002A06',\n\t\"bigstar;\":                         '\\U00002605',\n\t\"bigtriangledown;\":                 '\\U000025BD',\n\t\"bigtriangleup;\":                   '\\U000025B3',\n\t\"biguplus;\":                        '\\U00002A04',\n\t\"bigvee;\":                          '\\U000022C1',\n\t\"bigwedge;\":                        '\\U000022C0',\n\t\"bkarow;\":                          '\\U0000290D',\n\t\"blacklozenge;\":                    '\\U000029EB',\n\t\"blacksquare;\":                     '\\U000025AA',\n\t\"blacktriangle;\":                   '\\U000025B4',\n\t\"blacktriangledown;\":               '\\U000025BE',\n\t\"blacktriangleleft;\":               '\\U000025C2',\n\t\"blacktriangleright;\":              '\\U000025B8',\n\t\"blank;\":                           '\\U00002423',\n\t\"blk12;\":                           '\\U00002592',\n\t\"blk14;\":                           '\\U00002591',\n\t\"blk34;\":                           '\\U00002593',\n\t\"block;\":                           '\\U00002588',\n\t\"bnot;\":                            '\\U00002310',\n\t\"bopf;\":                            '\\U0001D553',\n\t\"bot;\":                             '\\U000022A5',\n\t\"bottom;\":                          '\\U000022A5',\n\t\"bowtie;\":                          '\\U000022C8',\n\t\"boxDL;\":                           '\\U00002557',\n\t\"boxDR;\":                           '\\U00002554',\n\t\"boxDl;\":                           '\\U00002556',\n\t\"boxDr;\":                           '\\U00002553',\n\t\"boxH;\":                            '\\U00002550',\n\t\"boxHD;\":                           '\\U00002566',\n\t\"boxHU;\":                           '\\U00002569',\n\t\"boxHd;\":                           '\\U00002564',\n\t\"boxHu;\":                           '\\U00002567',\n\t\"boxUL;\":                           '\\U0000255D',\n\t\"boxUR;\":                           '\\U0000255A',\n\t\"boxUl;\":                           '\\U0000255C',\n\t\"boxUr;\":                           '\\U00002559',\n\t\"boxV;\":                            '\\U00002551',\n\t\"boxVH;\":                           '\\U0000256C',\n\t\"boxVL;\":                           '\\U00002563',\n\t\"boxVR;\":                           '\\U00002560',\n\t\"boxVh;\":                           '\\U0000256B',\n\t\"boxVl;\":                           '\\U00002562',\n\t\"boxVr;\":                           '\\U0000255F',\n\t\"boxbox;\":                          '\\U000029C9',\n\t\"boxdL;\":                           '\\U00002555',\n\t\"boxdR;\":                           '\\U00002552',\n\t\"boxdl;\":                           '\\U00002510',\n\t\"boxdr;\":                           '\\U0000250C',\n\t\"boxh;\":                            '\\U00002500',\n\t\"boxhD;\":                           '\\U00002565',\n\t\"boxhU;\":                           '\\U00002568',\n\t\"boxhd;\":                           '\\U0000252C',\n\t\"boxhu;\":                           '\\U00002534',\n\t\"boxminus;\":                        '\\U0000229F',\n\t\"boxplus;\":                         '\\U0000229E',\n\t\"boxtimes;\":                        '\\U000022A0',\n\t\"boxuL;\":                           '\\U0000255B',\n\t\"boxuR;\":                           '\\U00002558',\n\t\"boxul;\":                           '\\U00002518',\n\t\"boxur;\":                           '\\U00002514',\n\t\"boxv;\":                            '\\U00002502',\n\t\"boxvH;\":                           '\\U0000256A',\n\t\"boxvL;\":                           '\\U00002561',\n\t\"boxvR;\":                           '\\U0000255E',\n\t\"boxvh;\":                           '\\U0000253C',\n\t\"boxvl;\":                           '\\U00002524',\n\t\"boxvr;\":                           '\\U0000251C',\n\t\"bprime;\":                          '\\U00002035',\n\t\"breve;\":                           '\\U000002D8',\n\t\"brvbar;\":                          '\\U000000A6',\n\t\"bscr;\":                            '\\U0001D4B7',\n\t\"bsemi;\":                           '\\U0000204F',\n\t\"bsim;\":                            '\\U0000223D',\n\t\"bsime;\":                           '\\U000022CD',\n\t\"bsol;\":                            '\\U0000005C',\n\t\"bsolb;\":                           '\\U000029C5',\n\t\"bsolhsub;\":                        '\\U000027C8',\n\t\"bull;\":                            '\\U00002022',\n\t\"bullet;\":                          '\\U00002022',\n\t\"bump;\":                            '\\U0000224E',\n\t\"bumpE;\":                           '\\U00002AAE',\n\t\"bumpe;\":                           '\\U0000224F',\n\t\"bumpeq;\":                          '\\U0000224F',\n\t\"cacute;\":                          '\\U00000107',\n\t\"cap;\":                             '\\U00002229',\n\t\"capand;\":                          '\\U00002A44',\n\t\"capbrcup;\":                        '\\U00002A49',\n\t\"capcap;\":                          '\\U00002A4B',\n\t\"capcup;\":                          '\\U00002A47',\n\t\"capdot;\":                          '\\U00002A40',\n\t\"caret;\":                           '\\U00002041',\n\t\"caron;\":                           '\\U000002C7',\n\t\"ccaps;\":                           '\\U00002A4D',\n\t\"ccaron;\":                          '\\U0000010D',\n\t\"ccedil;\":                          '\\U000000E7',\n\t\"ccirc;\":                           '\\U00000109',\n\t\"ccups;\":                           '\\U00002A4C',\n\t\"ccupssm;\":                         '\\U00002A50',\n\t\"cdot;\":                            '\\U0000010B',\n\t\"cedil;\":                           '\\U000000B8',\n\t\"cemptyv;\":                         '\\U000029B2',\n\t\"cent;\":                            '\\U000000A2',\n\t\"centerdot;\":                       '\\U000000B7',\n\t\"cfr;\":                             '\\U0001D520',\n\t\"chcy;\":                            '\\U00000447',\n\t\"check;\":                           '\\U00002713',\n\t\"checkmark;\":                       '\\U00002713',\n\t\"chi;\":                             '\\U000003C7',\n\t\"cir;\":                             '\\U000025CB',\n\t\"cirE;\":                            '\\U000029C3',\n\t\"circ;\":                            '\\U000002C6',\n\t\"circeq;\":                          '\\U00002257',\n\t\"circlearrowleft;\":                 '\\U000021BA',\n\t\"circlearrowright;\":                '\\U000021BB',\n\t\"circledR;\":                        '\\U000000AE',\n\t\"circledS;\":                        '\\U000024C8',\n\t\"circledast;\":                      '\\U0000229B',\n\t\"circledcirc;\":                     '\\U0000229A',\n\t\"circleddash;\":                     '\\U0000229D',\n\t\"cire;\":                            '\\U00002257',\n\t\"cirfnint;\":                        '\\U00002A10',\n\t\"cirmid;\":                          '\\U00002AEF',\n\t\"cirscir;\":                         '\\U000029C2',\n\t\"clubs;\":                           '\\U00002663',\n\t\"clubsuit;\":                        '\\U00002663',\n\t\"colon;\":                           '\\U0000003A',\n\t\"colone;\":                          '\\U00002254',\n\t\"coloneq;\":                         '\\U00002254',\n\t\"comma;\":                           '\\U0000002C',\n\t\"commat;\":                          '\\U00000040',\n\t\"comp;\":                            '\\U00002201',\n\t\"compfn;\":                          '\\U00002218',\n\t\"complement;\":                      '\\U00002201',\n\t\"complexes;\":                       '\\U00002102',\n\t\"cong;\":                            '\\U00002245',\n\t\"congdot;\":                         '\\U00002A6D',\n\t\"conint;\":                          '\\U0000222E',\n\t\"copf;\":                            '\\U0001D554',\n\t\"coprod;\":                          '\\U00002210',\n\t\"copy;\":                            '\\U000000A9',\n\t\"copysr;\":                          '\\U00002117',\n\t\"crarr;\":                           '\\U000021B5',\n\t\"cross;\":                           '\\U00002717',\n\t\"cscr;\":                            '\\U0001D4B8',\n\t\"csub;\":                            '\\U00002ACF',\n\t\"csube;\":                           '\\U00002AD1',\n\t\"csup;\":                            '\\U00002AD0',\n\t\"csupe;\":                           '\\U00002AD2',\n\t\"ctdot;\":                           '\\U000022EF',\n\t\"cudarrl;\":                         '\\U00002938',\n\t\"cudarrr;\":                         '\\U00002935',\n\t\"cuepr;\":                           '\\U000022DE',\n\t\"cuesc;\":                           '\\U000022DF',\n\t\"cularr;\":                          '\\U000021B6',\n\t\"cularrp;\":                         '\\U0000293D',\n\t\"cup;\":                             '\\U0000222A',\n\t\"cupbrcap;\":                        '\\U00002A48',\n\t\"cupcap;\":                          '\\U00002A46',\n\t\"cupcup;\":                          '\\U00002A4A',\n\t\"cupdot;\":                          '\\U0000228D',\n\t\"cupor;\":                           '\\U00002A45',\n\t\"curarr;\":                          '\\U000021B7',\n\t\"curarrm;\":                         '\\U0000293C',\n\t\"curlyeqprec;\":                     '\\U000022DE',\n\t\"curlyeqsucc;\":                     '\\U000022DF',\n\t\"curlyvee;\":                        '\\U000022CE',\n\t\"curlywedge;\":                      '\\U000022CF',\n\t\"curren;\":                          '\\U000000A4',\n\t\"curvearrowleft;\":                  '\\U000021B6',\n\t\"curvearrowright;\":                 '\\U000021B7',\n\t\"cuvee;\":                           '\\U000022CE',\n\t\"cuwed;\":                           '\\U000022CF',\n\t\"cwconint;\":                        '\\U00002232',\n\t\"cwint;\":                           '\\U00002231',\n\t\"cylcty;\":                          '\\U0000232D',\n\t\"dArr;\":                            '\\U000021D3',\n\t\"dHar;\":                            '\\U00002965',\n\t\"dagger;\":                          '\\U00002020',\n\t\"daleth;\":                          '\\U00002138',\n\t\"darr;\":                            '\\U00002193',\n\t\"dash;\":                            '\\U00002010',\n\t\"dashv;\":                           '\\U000022A3',\n\t\"dbkarow;\":                         '\\U0000290F',\n\t\"dblac;\":                           '\\U000002DD',\n\t\"dcaron;\":                          '\\U0000010F',\n\t\"dcy;\":                             '\\U00000434',\n\t\"dd;\":                              '\\U00002146',\n\t\"ddagger;\":                         '\\U00002021',\n\t\"ddarr;\":                           '\\U000021CA',\n\t\"ddotseq;\":                         '\\U00002A77',\n\t\"deg;\":                             '\\U000000B0',\n\t\"delta;\":                           '\\U000003B4',\n\t\"demptyv;\":                         '\\U000029B1',\n\t\"dfisht;\":                          '\\U0000297F',\n\t\"dfr;\":                             '\\U0001D521',\n\t\"dharl;\":                           '\\U000021C3',\n\t\"dharr;\":                           '\\U000021C2',\n\t\"diam;\":                            '\\U000022C4',\n\t\"diamond;\":                         '\\U000022C4',\n\t\"diamondsuit;\":                     '\\U00002666',\n\t\"diams;\":                           '\\U00002666',\n\t\"die;\":                             '\\U000000A8',\n\t\"digamma;\":                         '\\U000003DD',\n\t\"disin;\":                           '\\U000022F2',\n\t\"div;\":                             '\\U000000F7',\n\t\"divide;\":                          '\\U000000F7',\n\t\"divideontimes;\":                   '\\U000022C7',\n\t\"divonx;\":                          '\\U000022C7',\n\t\"djcy;\":                            '\\U00000452',\n\t\"dlcorn;\":                          '\\U0000231E',\n\t\"dlcrop;\":                          '\\U0000230D',\n\t\"dollar;\":                          '\\U00000024',\n\t\"dopf;\":                            '\\U0001D555',\n\t\"dot;\":                             '\\U000002D9',\n\t\"doteq;\":                           '\\U00002250',\n\t\"doteqdot;\":                        '\\U00002251',\n\t\"dotminus;\":                        '\\U00002238',\n\t\"dotplus;\":                         '\\U00002214',\n\t\"dotsquare;\":                       '\\U000022A1',\n\t\"doublebarwedge;\":                  '\\U00002306',\n\t\"downarrow;\":                       '\\U00002193',\n\t\"downdownarrows;\":                  '\\U000021CA',\n\t\"downharpoonleft;\":                 '\\U000021C3',\n\t\"downharpoonright;\":                '\\U000021C2',\n\t\"drbkarow;\":                        '\\U00002910',\n\t\"drcorn;\":                          '\\U0000231F',\n\t\"drcrop;\":                          '\\U0000230C',\n\t\"dscr;\":                            '\\U0001D4B9',\n\t\"dscy;\":                            '\\U00000455',\n\t\"dsol;\":                            '\\U000029F6',\n\t\"dstrok;\":                          '\\U00000111',\n\t\"dtdot;\":                           '\\U000022F1',\n\t\"dtri;\":                            '\\U000025BF',\n\t\"dtrif;\":                           '\\U000025BE',\n\t\"duarr;\":                           '\\U000021F5',\n\t\"duhar;\":                           '\\U0000296F',\n\t\"dwangle;\":                         '\\U000029A6',\n\t\"dzcy;\":                            '\\U0000045F',\n\t\"dzigrarr;\":                        '\\U000027FF',\n\t\"eDDot;\":                           '\\U00002A77',\n\t\"eDot;\":                            '\\U00002251',\n\t\"eacute;\":                          '\\U000000E9',\n\t\"easter;\":                          '\\U00002A6E',\n\t\"ecaron;\":                          '\\U0000011B',\n\t\"ecir;\":                            '\\U00002256',\n\t\"ecirc;\":                           '\\U000000EA',\n\t\"ecolon;\":                          '\\U00002255',\n\t\"ecy;\":                             '\\U0000044D',\n\t\"edot;\":                            '\\U00000117',\n\t\"ee;\":                              '\\U00002147',\n\t\"efDot;\":                           '\\U00002252',\n\t\"efr;\":                             '\\U0001D522',\n\t\"eg;\":                              '\\U00002A9A',\n\t\"egrave;\":                          '\\U000000E8',\n\t\"egs;\":                             '\\U00002A96',\n\t\"egsdot;\":                          '\\U00002A98',\n\t\"el;\":                              '\\U00002A99',\n\t\"elinters;\":                        '\\U000023E7',\n\t\"ell;\":                             '\\U00002113',\n\t\"els;\":                             '\\U00002A95',\n\t\"elsdot;\":                          '\\U00002A97',\n\t\"emacr;\":                           '\\U00000113',\n\t\"empty;\":                           '\\U00002205',\n\t\"emptyset;\":                        '\\U00002205',\n\t\"emptyv;\":                          '\\U00002205',\n\t\"emsp;\":                            '\\U00002003',\n\t\"emsp13;\":                          '\\U00002004',\n\t\"emsp14;\":                          '\\U00002005',\n\t\"eng;\":                             '\\U0000014B',\n\t\"ensp;\":                            '\\U00002002',\n\t\"eogon;\":                           '\\U00000119',\n\t\"eopf;\":                            '\\U0001D556',\n\t\"epar;\":                            '\\U000022D5',\n\t\"eparsl;\":                          '\\U000029E3',\n\t\"eplus;\":                           '\\U00002A71',\n\t\"epsi;\":                            '\\U000003B5',\n\t\"epsilon;\":                         '\\U000003B5',\n\t\"epsiv;\":                           '\\U000003F5',\n\t\"eqcirc;\":                          '\\U00002256',\n\t\"eqcolon;\":                         '\\U00002255',\n\t\"eqsim;\":                           '\\U00002242',\n\t\"eqslantgtr;\":                      '\\U00002A96',\n\t\"eqslantless;\":                     '\\U00002A95',\n\t\"equals;\":                          '\\U0000003D',\n\t\"equest;\":                          '\\U0000225F',\n\t\"equiv;\":                           '\\U00002261',\n\t\"equivDD;\":                         '\\U00002A78',\n\t\"eqvparsl;\":                        '\\U000029E5',\n\t\"erDot;\":                           '\\U00002253',\n\t\"erarr;\":                           '\\U00002971',\n\t\"escr;\":                            '\\U0000212F',\n\t\"esdot;\":                           '\\U00002250',\n\t\"esim;\":                            '\\U00002242',\n\t\"eta;\":                             '\\U000003B7',\n\t\"eth;\":                             '\\U000000F0',\n\t\"euml;\":                            '\\U000000EB',\n\t\"euro;\":                            '\\U000020AC',\n\t\"excl;\":                            '\\U00000021',\n\t\"exist;\":                           '\\U00002203',\n\t\"expectation;\":                     '\\U00002130',\n\t\"exponentiale;\":                    '\\U00002147',\n\t\"fallingdotseq;\":                   '\\U00002252',\n\t\"fcy;\":                             '\\U00000444',\n\t\"female;\":                          '\\U00002640',\n\t\"ffilig;\":                          '\\U0000FB03',\n\t\"fflig;\":                           '\\U0000FB00',\n\t\"ffllig;\":                          '\\U0000FB04',\n\t\"ffr;\":                             '\\U0001D523',\n\t\"filig;\":                           '\\U0000FB01',\n\t\"flat;\":                            '\\U0000266D',\n\t\"fllig;\":                           '\\U0000FB02',\n\t\"fltns;\":                           '\\U000025B1',\n\t\"fnof;\":                            '\\U00000192',\n\t\"fopf;\":                            '\\U0001D557',\n\t\"forall;\":                          '\\U00002200',\n\t\"fork;\":                            '\\U000022D4',\n\t\"forkv;\":                           '\\U00002AD9',\n\t\"fpartint;\":                        '\\U00002A0D',\n\t\"frac12;\":                          '\\U000000BD',\n\t\"frac13;\":                          '\\U00002153',\n\t\"frac14;\":                          '\\U000000BC',\n\t\"frac15;\":                          '\\U00002155',\n\t\"frac16;\":                          '\\U00002159',\n\t\"frac18;\":                          '\\U0000215B',\n\t\"frac23;\":                          '\\U00002154',\n\t\"frac25;\":                          '\\U00002156',\n\t\"frac34;\":                          '\\U000000BE',\n\t\"frac35;\":                          '\\U00002157',\n\t\"frac38;\":                          '\\U0000215C',\n\t\"frac45;\":                          '\\U00002158',\n\t\"frac56;\":                          '\\U0000215A',\n\t\"frac58;\":                          '\\U0000215D',\n\t\"frac78;\":                          '\\U0000215E',\n\t\"frasl;\":                           '\\U00002044',\n\t\"frown;\":                           '\\U00002322',\n\t\"fscr;\":                            '\\U0001D4BB',\n\t\"gE;\":                              '\\U00002267',\n\t\"gEl;\":                             '\\U00002A8C',\n\t\"gacute;\":                          '\\U000001F5',\n\t\"gamma;\":                           '\\U000003B3',\n\t\"gammad;\":                          '\\U000003DD',\n\t\"gap;\":                             '\\U00002A86',\n\t\"gbreve;\":                          '\\U0000011F',\n\t\"gcirc;\":                           '\\U0000011D',\n\t\"gcy;\":                             '\\U00000433',\n\t\"gdot;\":                            '\\U00000121',\n\t\"ge;\":                              '\\U00002265',\n\t\"gel;\":                             '\\U000022DB',\n\t\"geq;\":                             '\\U00002265',\n\t\"geqq;\":                            '\\U00002267',\n\t\"geqslant;\":                        '\\U00002A7E',\n\t\"ges;\":                             '\\U00002A7E',\n\t\"gescc;\":                           '\\U00002AA9',\n\t\"gesdot;\":                          '\\U00002A80',\n\t\"gesdoto;\":                         '\\U00002A82',\n\t\"gesdotol;\":                        '\\U00002A84',\n\t\"gesles;\":                          '\\U00002A94',\n\t\"gfr;\":                             '\\U0001D524',\n\t\"gg;\":                              '\\U0000226B',\n\t\"ggg;\":                             '\\U000022D9',\n\t\"gimel;\":                           '\\U00002137',\n\t\"gjcy;\":                            '\\U00000453',\n\t\"gl;\":                              '\\U00002277',\n\t\"glE;\":                             '\\U00002A92',\n\t\"gla;\":                             '\\U00002AA5',\n\t\"glj;\":                             '\\U00002AA4',\n\t\"gnE;\":                             '\\U00002269',\n\t\"gnap;\":                            '\\U00002A8A',\n\t\"gnapprox;\":                        '\\U00002A8A',\n\t\"gne;\":                             '\\U00002A88',\n\t\"gneq;\":                            '\\U00002A88',\n\t\"gneqq;\":                           '\\U00002269',\n\t\"gnsim;\":                           '\\U000022E7',\n\t\"gopf;\":                            '\\U0001D558',\n\t\"grave;\":                           '\\U00000060',\n\t\"gscr;\":                            '\\U0000210A',\n\t\"gsim;\":                            '\\U00002273',\n\t\"gsime;\":                           '\\U00002A8E',\n\t\"gsiml;\":                           '\\U00002A90',\n\t\"gt;\":                              '\\U0000003E',\n\t\"gtcc;\":                            '\\U00002AA7',\n\t\"gtcir;\":                           '\\U00002A7A',\n\t\"gtdot;\":                           '\\U000022D7',\n\t\"gtlPar;\":                          '\\U00002995',\n\t\"gtquest;\":                         '\\U00002A7C',\n\t\"gtrapprox;\":                       '\\U00002A86',\n\t\"gtrarr;\":                          '\\U00002978',\n\t\"gtrdot;\":                          '\\U000022D7',\n\t\"gtreqless;\":                       '\\U000022DB',\n\t\"gtreqqless;\":                      '\\U00002A8C',\n\t\"gtrless;\":                         '\\U00002277',\n\t\"gtrsim;\":                          '\\U00002273',\n\t\"hArr;\":                            '\\U000021D4',\n\t\"hairsp;\":                          '\\U0000200A',\n\t\"half;\":                            '\\U000000BD',\n\t\"hamilt;\":                          '\\U0000210B',\n\t\"hardcy;\":                          '\\U0000044A',\n\t\"harr;\":                            '\\U00002194',\n\t\"harrcir;\":                         '\\U00002948',\n\t\"harrw;\":                           '\\U000021AD',\n\t\"hbar;\":                            '\\U0000210F',\n\t\"hcirc;\":                           '\\U00000125',\n\t\"hearts;\":                          '\\U00002665',\n\t\"heartsuit;\":                       '\\U00002665',\n\t\"hellip;\":                          '\\U00002026',\n\t\"hercon;\":                          '\\U000022B9',\n\t\"hfr;\":                             '\\U0001D525',\n\t\"hksearow;\":                        '\\U00002925',\n\t\"hkswarow;\":                        '\\U00002926',\n\t\"hoarr;\":                           '\\U000021FF',\n\t\"homtht;\":                          '\\U0000223B',\n\t\"hookleftarrow;\":                   '\\U000021A9',\n\t\"hookrightarrow;\":                  '\\U000021AA',\n\t\"hopf;\":                            '\\U0001D559',\n\t\"horbar;\":                          '\\U00002015',\n\t\"hscr;\":                            '\\U0001D4BD',\n\t\"hslash;\":                          '\\U0000210F',\n\t\"hstrok;\":                          '\\U00000127',\n\t\"hybull;\":                          '\\U00002043',\n\t\"hyphen;\":                          '\\U00002010',\n\t\"iacute;\":                          '\\U000000ED',\n\t\"ic;\":                              '\\U00002063',\n\t\"icirc;\":                           '\\U000000EE',\n\t\"icy;\":                             '\\U00000438',\n\t\"iecy;\":                            '\\U00000435',\n\t\"iexcl;\":                           '\\U000000A1',\n\t\"iff;\":                             '\\U000021D4',\n\t\"ifr;\":                             '\\U0001D526',\n\t\"igrave;\":                          '\\U000000EC',\n\t\"ii;\":                              '\\U00002148',\n\t\"iiiint;\":                          '\\U00002A0C',\n\t\"iiint;\":                           '\\U0000222D',\n\t\"iinfin;\":                          '\\U000029DC',\n\t\"iiota;\":                           '\\U00002129',\n\t\"ijlig;\":                           '\\U00000133',\n\t\"imacr;\":                           '\\U0000012B',\n\t\"image;\":                           '\\U00002111',\n\t\"imagline;\":                        '\\U00002110',\n\t\"imagpart;\":                        '\\U00002111',\n\t\"imath;\":                           '\\U00000131',\n\t\"imof;\":                            '\\U000022B7',\n\t\"imped;\":                           '\\U000001B5',\n\t\"in;\":                              '\\U00002208',\n\t\"incare;\":                          '\\U00002105',\n\t\"infin;\":                           '\\U0000221E',\n\t\"infintie;\":                        '\\U000029DD',\n\t\"inodot;\":                          '\\U00000131',\n\t\"int;\":                             '\\U0000222B',\n\t\"intcal;\":                          '\\U000022BA',\n\t\"integers;\":                        '\\U00002124',\n\t\"intercal;\":                        '\\U000022BA',\n\t\"intlarhk;\":                        '\\U00002A17',\n\t\"intprod;\":                         '\\U00002A3C',\n\t\"iocy;\":                            '\\U00000451',\n\t\"iogon;\":                           '\\U0000012F',\n\t\"iopf;\":                            '\\U0001D55A',\n\t\"iota;\":                            '\\U000003B9',\n\t\"iprod;\":                           '\\U00002A3C',\n\t\"iquest;\":                          '\\U000000BF',\n\t\"iscr;\":                            '\\U0001D4BE',\n\t\"isin;\":                            '\\U00002208',\n\t\"isinE;\":                           '\\U000022F9',\n\t\"isindot;\":                         '\\U000022F5',\n\t\"isins;\":                           '\\U000022F4',\n\t\"isinsv;\":                          '\\U000022F3',\n\t\"isinv;\":                           '\\U00002208',\n\t\"it;\":                              '\\U00002062',\n\t\"itilde;\":                          '\\U00000129',\n\t\"iukcy;\":                           '\\U00000456',\n\t\"iuml;\":                            '\\U000000EF',\n\t\"jcirc;\":                           '\\U00000135',\n\t\"jcy;\":                             '\\U00000439',\n\t\"jfr;\":                             '\\U0001D527',\n\t\"jmath;\":                           '\\U00000237',\n\t\"jopf;\":                            '\\U0001D55B',\n\t\"jscr;\":                            '\\U0001D4BF',\n\t\"jsercy;\":                          '\\U00000458',\n\t\"jukcy;\":                           '\\U00000454',\n\t\"kappa;\":                           '\\U000003BA',\n\t\"kappav;\":                          '\\U000003F0',\n\t\"kcedil;\":                          '\\U00000137',\n\t\"kcy;\":                             '\\U0000043A',\n\t\"kfr;\":                             '\\U0001D528',\n\t\"kgreen;\":                          '\\U00000138',\n\t\"khcy;\":                            '\\U00000445',\n\t\"kjcy;\":                            '\\U0000045C',\n\t\"kopf;\":                            '\\U0001D55C',\n\t\"kscr;\":                            '\\U0001D4C0',\n\t\"lAarr;\":                           '\\U000021DA',\n\t\"lArr;\":                            '\\U000021D0',\n\t\"lAtail;\":                          '\\U0000291B',\n\t\"lBarr;\":                           '\\U0000290E',\n\t\"lE;\":                              '\\U00002266',\n\t\"lEg;\":                             '\\U00002A8B',\n\t\"lHar;\":                            '\\U00002962',\n\t\"lacute;\":                          '\\U0000013A',\n\t\"laemptyv;\":                        '\\U000029B4',\n\t\"lagran;\":                          '\\U00002112',\n\t\"lambda;\":                          '\\U000003BB',\n\t\"lang;\":                            '\\U000027E8',\n\t\"langd;\":                           '\\U00002991',\n\t\"langle;\":                          '\\U000027E8',\n\t\"lap;\":                             '\\U00002A85',\n\t\"laquo;\":                           '\\U000000AB',\n\t\"larr;\":                            '\\U00002190',\n\t\"larrb;\":                           '\\U000021E4',\n\t\"larrbfs;\":                         '\\U0000291F',\n\t\"larrfs;\":                          '\\U0000291D',\n\t\"larrhk;\":                          '\\U000021A9',\n\t\"larrlp;\":                          '\\U000021AB',\n\t\"larrpl;\":                          '\\U00002939',\n\t\"larrsim;\":                         '\\U00002973',\n\t\"larrtl;\":                          '\\U000021A2',\n\t\"lat;\":                             '\\U00002AAB',\n\t\"latail;\":                          '\\U00002919',\n\t\"late;\":                            '\\U00002AAD',\n\t\"lbarr;\":                           '\\U0000290C',\n\t\"lbbrk;\":                           '\\U00002772',\n\t\"lbrace;\":                          '\\U0000007B',\n\t\"lbrack;\":                          '\\U0000005B',\n\t\"lbrke;\":                           '\\U0000298B',\n\t\"lbrksld;\":                         '\\U0000298F',\n\t\"lbrkslu;\":                         '\\U0000298D',\n\t\"lcaron;\":                          '\\U0000013E',\n\t\"lcedil;\":                          '\\U0000013C',\n\t\"lceil;\":                           '\\U00002308',\n\t\"lcub;\":                            '\\U0000007B',\n\t\"lcy;\":                             '\\U0000043B',\n\t\"ldca;\":                            '\\U00002936',\n\t\"ldquo;\":                           '\\U0000201C',\n\t\"ldquor;\":                          '\\U0000201E',\n\t\"ldrdhar;\":                         '\\U00002967',\n\t\"ldrushar;\":                        '\\U0000294B',\n\t\"ldsh;\":                            '\\U000021B2',\n\t\"le;\":                              '\\U00002264',\n\t\"leftarrow;\":                       '\\U00002190',\n\t\"leftarrowtail;\":                   '\\U000021A2',\n\t\"leftharpoondown;\":                 '\\U000021BD',\n\t\"leftharpoonup;\":                   '\\U000021BC',\n\t\"leftleftarrows;\":                  '\\U000021C7',\n\t\"leftrightarrow;\":                  '\\U00002194',\n\t\"leftrightarrows;\":                 '\\U000021C6',\n\t\"leftrightharpoons;\":               '\\U000021CB',\n\t\"leftrightsquigarrow;\":             '\\U000021AD',\n\t\"leftthreetimes;\":                  '\\U000022CB',\n\t\"leg;\":                             '\\U000022DA',\n\t\"leq;\":                             '\\U00002264',\n\t\"leqq;\":                            '\\U00002266',\n\t\"leqslant;\":                        '\\U00002A7D',\n\t\"les;\":                             '\\U00002A7D',\n\t\"lescc;\":                           '\\U00002AA8',\n\t\"lesdot;\":                          '\\U00002A7F',\n\t\"lesdoto;\":                         '\\U00002A81',\n\t\"lesdotor;\":                        '\\U00002A83',\n\t\"lesges;\":                          '\\U00002A93',\n\t\"lessapprox;\":                      '\\U00002A85',\n\t\"lessdot;\":                         '\\U000022D6',\n\t\"lesseqgtr;\":                       '\\U000022DA',\n\t\"lesseqqgtr;\":                      '\\U00002A8B',\n\t\"lessgtr;\":                         '\\U00002276',\n\t\"lesssim;\":                         '\\U00002272',\n\t\"lfisht;\":                          '\\U0000297C',\n\t\"lfloor;\":                          '\\U0000230A',\n\t\"lfr;\":                             '\\U0001D529',\n\t\"lg;\":                              '\\U00002276',\n\t\"lgE;\":                             '\\U00002A91',\n\t\"lhard;\":                           '\\U000021BD',\n\t\"lharu;\":                           '\\U000021BC',\n\t\"lharul;\":                          '\\U0000296A',\n\t\"lhblk;\":                           '\\U00002584',\n\t\"ljcy;\":                            '\\U00000459',\n\t\"ll;\":                              '\\U0000226A',\n\t\"llarr;\":                           '\\U000021C7',\n\t\"llcorner;\":                        '\\U0000231E',\n\t\"llhard;\":                          '\\U0000296B',\n\t\"lltri;\":                           '\\U000025FA',\n\t\"lmidot;\":                          '\\U00000140',\n\t\"lmoust;\":                          '\\U000023B0',\n\t\"lmoustache;\":                      '\\U000023B0',\n\t\"lnE;\":                             '\\U00002268',\n\t\"lnap;\":                            '\\U00002A89',\n\t\"lnapprox;\":                        '\\U00002A89',\n\t\"lne;\":                             '\\U00002A87',\n\t\"lneq;\":                            '\\U00002A87',\n\t\"lneqq;\":                           '\\U00002268',\n\t\"lnsim;\":                           '\\U000022E6',\n\t\"loang;\":                           '\\U000027EC',\n\t\"loarr;\":                           '\\U000021FD',\n\t\"lobrk;\":                           '\\U000027E6',\n\t\"longleftarrow;\":                   '\\U000027F5',\n\t\"longleftrightarrow;\":              '\\U000027F7',\n\t\"longmapsto;\":                      '\\U000027FC',\n\t\"longrightarrow;\":                  '\\U000027F6',\n\t\"looparrowleft;\":                   '\\U000021AB',\n\t\"looparrowright;\":                  '\\U000021AC',\n\t\"lopar;\":                           '\\U00002985',\n\t\"lopf;\":                            '\\U0001D55D',\n\t\"loplus;\":                          '\\U00002A2D',\n\t\"lotimes;\":                         '\\U00002A34',\n\t\"lowast;\":                          '\\U00002217',\n\t\"lowbar;\":                          '\\U0000005F',\n\t\"loz;\":                             '\\U000025CA',\n\t\"lozenge;\":                         '\\U000025CA',\n\t\"lozf;\":                            '\\U000029EB',\n\t\"lpar;\":                            '\\U00000028',\n\t\"lparlt;\":                          '\\U00002993',\n\t\"lrarr;\":                           '\\U000021C6',\n\t\"lrcorner;\":                        '\\U0000231F',\n\t\"lrhar;\":                           '\\U000021CB',\n\t\"lrhard;\":                          '\\U0000296D',\n\t\"lrm;\":                             '\\U0000200E',\n\t\"lrtri;\":                           '\\U000022BF',\n\t\"lsaquo;\":                          '\\U00002039',\n\t\"lscr;\":                            '\\U0001D4C1',\n\t\"lsh;\":                             '\\U000021B0',\n\t\"lsim;\":                            '\\U00002272',\n\t\"lsime;\":                           '\\U00002A8D',\n\t\"lsimg;\":                           '\\U00002A8F',\n\t\"lsqb;\":                            '\\U0000005B',\n\t\"lsquo;\":                           '\\U00002018',\n\t\"lsquor;\":                          '\\U0000201A',\n\t\"lstrok;\":                          '\\U00000142',\n\t\"lt;\":                              '\\U0000003C',\n\t\"ltcc;\":                            '\\U00002AA6',\n\t\"ltcir;\":                           '\\U00002A79',\n\t\"ltdot;\":                           '\\U000022D6',\n\t\"lthree;\":                          '\\U000022CB',\n\t\"ltimes;\":                          '\\U000022C9',\n\t\"ltlarr;\":                          '\\U00002976',\n\t\"ltquest;\":                         '\\U00002A7B',\n\t\"ltrPar;\":                          '\\U00002996',\n\t\"ltri;\":                            '\\U000025C3',\n\t\"ltrie;\":                           '\\U000022B4',\n\t\"ltrif;\":                           '\\U000025C2',\n\t\"lurdshar;\":                        '\\U0000294A',\n\t\"luruhar;\":                         '\\U00002966',\n\t\"mDDot;\":                           '\\U0000223A',\n\t\"macr;\":                            '\\U000000AF',\n\t\"male;\":                            '\\U00002642',\n\t\"malt;\":                            '\\U00002720',\n\t\"maltese;\":                         '\\U00002720',\n\t\"map;\":                             '\\U000021A6',\n\t\"mapsto;\":                          '\\U000021A6',\n\t\"mapstodown;\":                      '\\U000021A7',\n\t\"mapstoleft;\":                      '\\U000021A4',\n\t\"mapstoup;\":                        '\\U000021A5',\n\t\"marker;\":                          '\\U000025AE',\n\t\"mcomma;\":                          '\\U00002A29',\n\t\"mcy;\":                             '\\U0000043C',\n\t\"mdash;\":                           '\\U00002014',\n\t\"measuredangle;\":                   '\\U00002221',\n\t\"mfr;\":                             '\\U0001D52A',\n\t\"mho;\":                             '\\U00002127',\n\t\"micro;\":                           '\\U000000B5',\n\t\"mid;\":                             '\\U00002223',\n\t\"midast;\":                          '\\U0000002A',\n\t\"midcir;\":                          '\\U00002AF0',\n\t\"middot;\":                          '\\U000000B7',\n\t\"minus;\":                           '\\U00002212',\n\t\"minusb;\":                          '\\U0000229F',\n\t\"minusd;\":                          '\\U00002238',\n\t\"minusdu;\":                         '\\U00002A2A',\n\t\"mlcp;\":                            '\\U00002ADB',\n\t\"mldr;\":                            '\\U00002026',\n\t\"mnplus;\":                          '\\U00002213',\n\t\"models;\":                          '\\U000022A7',\n\t\"mopf;\":                            '\\U0001D55E',\n\t\"mp;\":                              '\\U00002213',\n\t\"mscr;\":                            '\\U0001D4C2',\n\t\"mstpos;\":                          '\\U0000223E',\n\t\"mu;\":                              '\\U000003BC',\n\t\"multimap;\":                        '\\U000022B8',\n\t\"mumap;\":                           '\\U000022B8',\n\t\"nLeftarrow;\":                      '\\U000021CD',\n\t\"nLeftrightarrow;\":                 '\\U000021CE',\n\t\"nRightarrow;\":                     '\\U000021CF',\n\t\"nVDash;\":                          '\\U000022AF',\n\t\"nVdash;\":                          '\\U000022AE',\n\t\"nabla;\":                           '\\U00002207',\n\t\"nacute;\":                          '\\U00000144',\n\t\"nap;\":                             '\\U00002249',\n\t\"napos;\":                           '\\U00000149',\n\t\"napprox;\":                         '\\U00002249',\n\t\"natur;\":                           '\\U0000266E',\n\t\"natural;\":                         '\\U0000266E',\n\t\"naturals;\":                        '\\U00002115',\n\t\"nbsp;\":                            '\\U000000A0',\n\t\"ncap;\":                            '\\U00002A43',\n\t\"ncaron;\":                          '\\U00000148',\n\t\"ncedil;\":                          '\\U00000146',\n\t\"ncong;\":                           '\\U00002247',\n\t\"ncup;\":                            '\\U00002A42',\n\t\"ncy;\":                             '\\U0000043D',\n\t\"ndash;\":                           '\\U00002013',\n\t\"ne;\":                              '\\U00002260',\n\t\"neArr;\":                           '\\U000021D7',\n\t\"nearhk;\":                          '\\U00002924',\n\t\"nearr;\":                           '\\U00002197',\n\t\"nearrow;\":                         '\\U00002197',\n\t\"nequiv;\":                          '\\U00002262',\n\t\"nesear;\":                          '\\U00002928',\n\t\"nexist;\":                          '\\U00002204',\n\t\"nexists;\":                         '\\U00002204',\n\t\"nfr;\":                             '\\U0001D52B',\n\t\"nge;\":                             '\\U00002271',\n\t\"ngeq;\":                            '\\U00002271',\n\t\"ngsim;\":                           '\\U00002275',\n\t\"ngt;\":                             '\\U0000226F',\n\t\"ngtr;\":                            '\\U0000226F',\n\t\"nhArr;\":                           '\\U000021CE',\n\t\"nharr;\":                           '\\U000021AE',\n\t\"nhpar;\":                           '\\U00002AF2',\n\t\"ni;\":                              '\\U0000220B',\n\t\"nis;\":                             '\\U000022FC',\n\t\"nisd;\":                            '\\U000022FA',\n\t\"niv;\":                             '\\U0000220B',\n\t\"njcy;\":                            '\\U0000045A',\n\t\"nlArr;\":                           '\\U000021CD',\n\t\"nlarr;\":                           '\\U0000219A',\n\t\"nldr;\":                            '\\U00002025',\n\t\"nle;\":                             '\\U00002270',\n\t\"nleftarrow;\":                      '\\U0000219A',\n\t\"nleftrightarrow;\":                 '\\U000021AE',\n\t\"nleq;\":                            '\\U00002270',\n\t\"nless;\":                           '\\U0000226E',\n\t\"nlsim;\":                           '\\U00002274',\n\t\"nlt;\":                             '\\U0000226E',\n\t\"nltri;\":                           '\\U000022EA',\n\t\"nltrie;\":                          '\\U000022EC',\n\t\"nmid;\":                            '\\U00002224',\n\t\"nopf;\":                            '\\U0001D55F',\n\t\"not;\":                             '\\U000000AC',\n\t\"notin;\":                           '\\U00002209',\n\t\"notinva;\":                         '\\U00002209',\n\t\"notinvb;\":                         '\\U000022F7',\n\t\"notinvc;\":                         '\\U000022F6',\n\t\"notni;\":                           '\\U0000220C',\n\t\"notniva;\":                         '\\U0000220C',\n\t\"notnivb;\":                         '\\U000022FE',\n\t\"notnivc;\":                         '\\U000022FD',\n\t\"npar;\":                            '\\U00002226',\n\t\"nparallel;\":                       '\\U00002226',\n\t\"npolint;\":                         '\\U00002A14',\n\t\"npr;\":                             '\\U00002280',\n\t\"nprcue;\":                          '\\U000022E0',\n\t\"nprec;\":                           '\\U00002280',\n\t\"nrArr;\":                           '\\U000021CF',\n\t\"nrarr;\":                           '\\U0000219B',\n\t\"nrightarrow;\":                     '\\U0000219B',\n\t\"nrtri;\":                           '\\U000022EB',\n\t\"nrtrie;\":                          '\\U000022ED',\n\t\"nsc;\":                             '\\U00002281',\n\t\"nsccue;\":                          '\\U000022E1',\n\t\"nscr;\":                            '\\U0001D4C3',\n\t\"nshortmid;\":                       '\\U00002224',\n\t\"nshortparallel;\":                  '\\U00002226',\n\t\"nsim;\":                            '\\U00002241',\n\t\"nsime;\":                           '\\U00002244',\n\t\"nsimeq;\":                          '\\U00002244',\n\t\"nsmid;\":                           '\\U00002224',\n\t\"nspar;\":                           '\\U00002226',\n\t\"nsqsube;\":                         '\\U000022E2',\n\t\"nsqsupe;\":                         '\\U000022E3',\n\t\"nsub;\":                            '\\U00002284',\n\t\"nsube;\":                           '\\U00002288',\n\t\"nsubseteq;\":                       '\\U00002288',\n\t\"nsucc;\":                           '\\U00002281',\n\t\"nsup;\":                            '\\U00002285',\n\t\"nsupe;\":                           '\\U00002289',\n\t\"nsupseteq;\":                       '\\U00002289',\n\t\"ntgl;\":                            '\\U00002279',\n\t\"ntilde;\":                          '\\U000000F1',\n\t\"ntlg;\":                            '\\U00002278',\n\t\"ntriangleleft;\":                   '\\U000022EA',\n\t\"ntrianglelefteq;\":                 '\\U000022EC',\n\t\"ntriangleright;\":                  '\\U000022EB',\n\t\"ntrianglerighteq;\":                '\\U000022ED',\n\t\"nu;\":                              '\\U000003BD',\n\t\"num;\":                             '\\U00000023',\n\t\"numero;\":                          '\\U00002116',\n\t\"numsp;\":                           '\\U00002007',\n\t\"nvDash;\":                          '\\U000022AD',\n\t\"nvHarr;\":                          '\\U00002904',\n\t\"nvdash;\":                          '\\U000022AC',\n\t\"nvinfin;\":                         '\\U000029DE',\n\t\"nvlArr;\":                          '\\U00002902',\n\t\"nvrArr;\":                          '\\U00002903',\n\t\"nwArr;\":                           '\\U000021D6',\n\t\"nwarhk;\":                          '\\U00002923',\n\t\"nwarr;\":                           '\\U00002196',\n\t\"nwarrow;\":                         '\\U00002196',\n\t\"nwnear;\":                          '\\U00002927',\n\t\"oS;\":                              '\\U000024C8',\n\t\"oacute;\":                          '\\U000000F3',\n\t\"oast;\":                            '\\U0000229B',\n\t\"ocir;\":                            '\\U0000229A',\n\t\"ocirc;\":                           '\\U000000F4',\n\t\"ocy;\":                             '\\U0000043E',\n\t\"odash;\":                           '\\U0000229D',\n\t\"odblac;\":                          '\\U00000151',\n\t\"odiv;\":                            '\\U00002A38',\n\t\"odot;\":                            '\\U00002299',\n\t\"odsold;\":                          '\\U000029BC',\n\t\"oelig;\":                           '\\U00000153',\n\t\"ofcir;\":                           '\\U000029BF',\n\t\"ofr;\":                             '\\U0001D52C',\n\t\"ogon;\":                            '\\U000002DB',\n\t\"ograve;\":                          '\\U000000F2',\n\t\"ogt;\":                             '\\U000029C1',\n\t\"ohbar;\":                           '\\U000029B5',\n\t\"ohm;\":                             '\\U000003A9',\n\t\"oint;\":                            '\\U0000222E',\n\t\"olarr;\":                           '\\U000021BA',\n\t\"olcir;\":                           '\\U000029BE',\n\t\"olcross;\":                         '\\U000029BB',\n\t\"oline;\":                           '\\U0000203E',\n\t\"olt;\":                             '\\U000029C0',\n\t\"omacr;\":                           '\\U0000014D',\n\t\"omega;\":                           '\\U000003C9',\n\t\"omicron;\":                         '\\U000003BF',\n\t\"omid;\":                            '\\U000029B6',\n\t\"ominus;\":                          '\\U00002296',\n\t\"oopf;\":                            '\\U0001D560',\n\t\"opar;\":                            '\\U000029B7',\n\t\"operp;\":                           '\\U000029B9',\n\t\"oplus;\":                           '\\U00002295',\n\t\"or;\":                              '\\U00002228',\n\t\"orarr;\":                           '\\U000021BB',\n\t\"ord;\":                             '\\U00002A5D',\n\t\"order;\":                           '\\U00002134',\n\t\"orderof;\":                         '\\U00002134',\n\t\"ordf;\":                            '\\U000000AA',\n\t\"ordm;\":                            '\\U000000BA',\n\t\"origof;\":                          '\\U000022B6',\n\t\"oror;\":                            '\\U00002A56',\n\t\"orslope;\":                         '\\U00002A57',\n\t\"orv;\":                             '\\U00002A5B',\n\t\"oscr;\":                            '\\U00002134',\n\t\"oslash;\":                          '\\U000000F8',\n\t\"osol;\":                            '\\U00002298',\n\t\"otilde;\":                          '\\U000000F5',\n\t\"otimes;\":                          '\\U00002297',\n\t\"otimesas;\":                        '\\U00002A36',\n\t\"ouml;\":                            '\\U000000F6',\n\t\"ovbar;\":                           '\\U0000233D',\n\t\"par;\":                             '\\U00002225',\n\t\"para;\":                            '\\U000000B6',\n\t\"parallel;\":                        '\\U00002225',\n\t\"parsim;\":                          '\\U00002AF3',\n\t\"parsl;\":                           '\\U00002AFD',\n\t\"part;\":                            '\\U00002202',\n\t\"pcy;\":                             '\\U0000043F',\n\t\"percnt;\":                          '\\U00000025',\n\t\"period;\":                          '\\U0000002E',\n\t\"permil;\":                          '\\U00002030',\n\t\"perp;\":                            '\\U000022A5',\n\t\"pertenk;\":                         '\\U00002031',\n\t\"pfr;\":                             '\\U0001D52D',\n\t\"phi;\":                             '\\U000003C6',\n\t\"phiv;\":                            '\\U000003D5',\n\t\"phmmat;\":                          '\\U00002133',\n\t\"phone;\":                           '\\U0000260E',\n\t\"pi;\":                              '\\U000003C0',\n\t\"pitchfork;\":                       '\\U000022D4',\n\t\"piv;\":                             '\\U000003D6',\n\t\"planck;\":                          '\\U0000210F',\n\t\"planckh;\":                         '\\U0000210E',\n\t\"plankv;\":                          '\\U0000210F',\n\t\"plus;\":                            '\\U0000002B',\n\t\"plusacir;\":                        '\\U00002A23',\n\t\"plusb;\":                           '\\U0000229E',\n\t\"pluscir;\":                         '\\U00002A22',\n\t\"plusdo;\":                          '\\U00002214',\n\t\"plusdu;\":                          '\\U00002A25',\n\t\"pluse;\":                           '\\U00002A72',\n\t\"plusmn;\":                          '\\U000000B1',\n\t\"plussim;\":                         '\\U00002A26',\n\t\"plustwo;\":                         '\\U00002A27',\n\t\"pm;\":                              '\\U000000B1',\n\t\"pointint;\":                        '\\U00002A15',\n\t\"popf;\":                            '\\U0001D561',\n\t\"pound;\":                           '\\U000000A3',\n\t\"pr;\":                              '\\U0000227A',\n\t\"prE;\":                             '\\U00002AB3',\n\t\"prap;\":                            '\\U00002AB7',\n\t\"prcue;\":                           '\\U0000227C',\n\t\"pre;\":                             '\\U00002AAF',\n\t\"prec;\":                            '\\U0000227A',\n\t\"precapprox;\":                      '\\U00002AB7',\n\t\"preccurlyeq;\":                     '\\U0000227C',\n\t\"preceq;\":                          '\\U00002AAF',\n\t\"precnapprox;\":                     '\\U00002AB9',\n\t\"precneqq;\":                        '\\U00002AB5',\n\t\"precnsim;\":                        '\\U000022E8',\n\t\"precsim;\":                         '\\U0000227E',\n\t\"prime;\":                           '\\U00002032',\n\t\"primes;\":                          '\\U00002119',\n\t\"prnE;\":                            '\\U00002AB5',\n\t\"prnap;\":                           '\\U00002AB9',\n\t\"prnsim;\":                          '\\U000022E8',\n\t\"prod;\":                            '\\U0000220F',\n\t\"profalar;\":                        '\\U0000232E',\n\t\"profline;\":                        '\\U00002312',\n\t\"profsurf;\":                        '\\U00002313',\n\t\"prop;\":                            '\\U0000221D',\n\t\"propto;\":                          '\\U0000221D',\n\t\"prsim;\":                           '\\U0000227E',\n\t\"prurel;\":                          '\\U000022B0',\n\t\"pscr;\":                            '\\U0001D4C5',\n\t\"psi;\":                             '\\U000003C8',\n\t\"puncsp;\":                          '\\U00002008',\n\t\"qfr;\":                             '\\U0001D52E',\n\t\"qint;\":                            '\\U00002A0C',\n\t\"qopf;\":                            '\\U0001D562',\n\t\"qprime;\":                          '\\U00002057',\n\t\"qscr;\":                            '\\U0001D4C6',\n\t\"quaternions;\":                     '\\U0000210D',\n\t\"quatint;\":                         '\\U00002A16',\n\t\"quest;\":                           '\\U0000003F',\n\t\"questeq;\":                         '\\U0000225F',\n\t\"quot;\":                            '\\U00000022',\n\t\"rAarr;\":                           '\\U000021DB',\n\t\"rArr;\":                            '\\U000021D2',\n\t\"rAtail;\":                          '\\U0000291C',\n\t\"rBarr;\":                           '\\U0000290F',\n\t\"rHar;\":                            '\\U00002964',\n\t\"racute;\":                          '\\U00000155',\n\t\"radic;\":                           '\\U0000221A',\n\t\"raemptyv;\":                        '\\U000029B3',\n\t\"rang;\":                            '\\U000027E9',\n\t\"rangd;\":                           '\\U00002992',\n\t\"range;\":                           '\\U000029A5',\n\t\"rangle;\":                          '\\U000027E9',\n\t\"raquo;\":                           '\\U000000BB',\n\t\"rarr;\":                            '\\U00002192',\n\t\"rarrap;\":                          '\\U00002975',\n\t\"rarrb;\":                           '\\U000021E5',\n\t\"rarrbfs;\":                         '\\U00002920',\n\t\"rarrc;\":                           '\\U00002933',\n\t\"rarrfs;\":                          '\\U0000291E',\n\t\"rarrhk;\":                          '\\U000021AA',\n\t\"rarrlp;\":                          '\\U000021AC',\n\t\"rarrpl;\":                          '\\U00002945',\n\t\"rarrsim;\":                         '\\U00002974',\n\t\"rarrtl;\":                          '\\U000021A3',\n\t\"rarrw;\":                           '\\U0000219D',\n\t\"ratail;\":                          '\\U0000291A',\n\t\"ratio;\":                           '\\U00002236',\n\t\"rationals;\":                       '\\U0000211A',\n\t\"rbarr;\":                           '\\U0000290D',\n\t\"rbbrk;\":                           '\\U00002773',\n\t\"rbrace;\":                          '\\U0000007D',\n\t\"rbrack;\":                          '\\U0000005D',\n\t\"rbrke;\":                           '\\U0000298C',\n\t\"rbrksld;\":                         '\\U0000298E',\n\t\"rbrkslu;\":                         '\\U00002990',\n\t\"rcaron;\":                          '\\U00000159',\n\t\"rcedil;\":                          '\\U00000157',\n\t\"rceil;\":                           '\\U00002309',\n\t\"rcub;\":                            '\\U0000007D',\n\t\"rcy;\":                             '\\U00000440',\n\t\"rdca;\":                            '\\U00002937',\n\t\"rdldhar;\":                         '\\U00002969',\n\t\"rdquo;\":                           '\\U0000201D',\n\t\"rdquor;\":                          '\\U0000201D',\n\t\"rdsh;\":                            '\\U000021B3',\n\t\"real;\":                            '\\U0000211C',\n\t\"realine;\":                         '\\U0000211B',\n\t\"realpart;\":                        '\\U0000211C',\n\t\"reals;\":                           '\\U0000211D',\n\t\"rect;\":                            '\\U000025AD',\n\t\"reg;\":                             '\\U000000AE',\n\t\"rfisht;\":                          '\\U0000297D',\n\t\"rfloor;\":                          '\\U0000230B',\n\t\"rfr;\":                             '\\U0001D52F',\n\t\"rhard;\":                           '\\U000021C1',\n\t\"rharu;\":                           '\\U000021C0',\n\t\"rharul;\":                          '\\U0000296C',\n\t\"rho;\":                             '\\U000003C1',\n\t\"rhov;\":                            '\\U000003F1',\n\t\"rightarrow;\":                      '\\U00002192',\n\t\"rightarrowtail;\":                  '\\U000021A3',\n\t\"rightharpoondown;\":                '\\U000021C1',\n\t\"rightharpoonup;\":                  '\\U000021C0',\n\t\"rightleftarrows;\":                 '\\U000021C4',\n\t\"rightleftharpoons;\":               '\\U000021CC',\n\t\"rightrightarrows;\":                '\\U000021C9',\n\t\"rightsquigarrow;\":                 '\\U0000219D',\n\t\"rightthreetimes;\":                 '\\U000022CC',\n\t\"ring;\":                            '\\U000002DA',\n\t\"risingdotseq;\":                    '\\U00002253',\n\t\"rlarr;\":                           '\\U000021C4',\n\t\"rlhar;\":                           '\\U000021CC',\n\t\"rlm;\":                             '\\U0000200F',\n\t\"rmoust;\":                          '\\U000023B1',\n\t\"rmoustache;\":                      '\\U000023B1',\n\t\"rnmid;\":                           '\\U00002AEE',\n\t\"roang;\":                           '\\U000027ED',\n\t\"roarr;\":                           '\\U000021FE',\n\t\"robrk;\":                           '\\U000027E7',\n\t\"ropar;\":                           '\\U00002986',\n\t\"ropf;\":                            '\\U0001D563',\n\t\"roplus;\":                          '\\U00002A2E',\n\t\"rotimes;\":                         '\\U00002A35',\n\t\"rpar;\":                            '\\U00000029',\n\t\"rpargt;\":                          '\\U00002994',\n\t\"rppolint;\":                        '\\U00002A12',\n\t\"rrarr;\":                           '\\U000021C9',\n\t\"rsaquo;\":                          '\\U0000203A',\n\t\"rscr;\":                            '\\U0001D4C7',\n\t\"rsh;\":                             '\\U000021B1',\n\t\"rsqb;\":                            '\\U0000005D',\n\t\"rsquo;\":                           '\\U00002019',\n\t\"rsquor;\":                          '\\U00002019',\n\t\"rthree;\":                          '\\U000022CC',\n\t\"rtimes;\":                          '\\U000022CA',\n\t\"rtri;\":                            '\\U000025B9',\n\t\"rtrie;\":                           '\\U000022B5',\n\t\"rtrif;\":                           '\\U000025B8',\n\t\"rtriltri;\":                        '\\U000029CE',\n\t\"ruluhar;\":                         '\\U00002968',\n\t\"rx;\":                              '\\U0000211E',\n\t\"sacute;\":                          '\\U0000015B',\n\t\"sbquo;\":                           '\\U0000201A',\n\t\"sc;\":                              '\\U0000227B',\n\t\"scE;\":                             '\\U00002AB4',\n\t\"scap;\":                            '\\U00002AB8',\n\t\"scaron;\":                          '\\U00000161',\n\t\"sccue;\":                           '\\U0000227D',\n\t\"sce;\":                             '\\U00002AB0',\n\t\"scedil;\":                          '\\U0000015F',\n\t\"scirc;\":                           '\\U0000015D',\n\t\"scnE;\":                            '\\U00002AB6',\n\t\"scnap;\":                           '\\U00002ABA',\n\t\"scnsim;\":                          '\\U000022E9',\n\t\"scpolint;\":                        '\\U00002A13',\n\t\"scsim;\":                           '\\U0000227F',\n\t\"scy;\":                             '\\U00000441',\n\t\"sdot;\":                            '\\U000022C5',\n\t\"sdotb;\":                           '\\U000022A1',\n\t\"sdote;\":                           '\\U00002A66',\n\t\"seArr;\":                           '\\U000021D8',\n\t\"searhk;\":                          '\\U00002925',\n\t\"searr;\":                           '\\U00002198',\n\t\"searrow;\":                         '\\U00002198',\n\t\"sect;\":                            '\\U000000A7',\n\t\"semi;\":                            '\\U0000003B',\n\t\"seswar;\":                          '\\U00002929',\n\t\"setminus;\":                        '\\U00002216',\n\t\"setmn;\":                           '\\U00002216',\n\t\"sext;\":                            '\\U00002736',\n\t\"sfr;\":                             '\\U0001D530',\n\t\"sfrown;\":                          '\\U00002322',\n\t\"sharp;\":                           '\\U0000266F',\n\t\"shchcy;\":                          '\\U00000449',\n\t\"shcy;\":                            '\\U00000448',\n\t\"shortmid;\":                        '\\U00002223',\n\t\"shortparallel;\":                   '\\U00002225',\n\t\"shy;\":                             '\\U000000AD',\n\t\"sigma;\":                           '\\U000003C3',\n\t\"sigmaf;\":                          '\\U000003C2',\n\t\"sigmav;\":                          '\\U000003C2',\n\t\"sim;\":                             '\\U0000223C',\n\t\"simdot;\":                          '\\U00002A6A',\n\t\"sime;\":                            '\\U00002243',\n\t\"simeq;\":                           '\\U00002243',\n\t\"simg;\":                            '\\U00002A9E',\n\t\"simgE;\":                           '\\U00002AA0',\n\t\"siml;\":                            '\\U00002A9D',\n\t\"simlE;\":                           '\\U00002A9F',\n\t\"simne;\":                           '\\U00002246',\n\t\"simplus;\":                         '\\U00002A24',\n\t\"simrarr;\":                         '\\U00002972',\n\t\"slarr;\":                           '\\U00002190',\n\t\"smallsetminus;\":                   '\\U00002216',\n\t\"smashp;\":                          '\\U00002A33',\n\t\"smeparsl;\":                        '\\U000029E4',\n\t\"smid;\":                            '\\U00002223',\n\t\"smile;\":                           '\\U00002323',\n\t\"smt;\":                             '\\U00002AAA',\n\t\"smte;\":                            '\\U00002AAC',\n\t\"softcy;\":                          '\\U0000044C',\n\t\"sol;\":                             '\\U0000002F',\n\t\"solb;\":                            '\\U000029C4',\n\t\"solbar;\":                          '\\U0000233F',\n\t\"sopf;\":                            '\\U0001D564',\n\t\"spades;\":                          '\\U00002660',\n\t\"spadesuit;\":                       '\\U00002660',\n\t\"spar;\":                            '\\U00002225',\n\t\"sqcap;\":                           '\\U00002293',\n\t\"sqcup;\":                           '\\U00002294',\n\t\"sqsub;\":                           '\\U0000228F',\n\t\"sqsube;\":                          '\\U00002291',\n\t\"sqsubset;\":                        '\\U0000228F',\n\t\"sqsubseteq;\":                      '\\U00002291',\n\t\"sqsup;\":                           '\\U00002290',\n\t\"sqsupe;\":                          '\\U00002292',\n\t\"sqsupset;\":                        '\\U00002290',\n\t\"sqsupseteq;\":                      '\\U00002292',\n\t\"squ;\":                             '\\U000025A1',\n\t\"square;\":                          '\\U000025A1',\n\t\"squarf;\":                          '\\U000025AA',\n\t\"squf;\":                            '\\U000025AA',\n\t\"srarr;\":                           '\\U00002192',\n\t\"sscr;\":                            '\\U0001D4C8',\n\t\"ssetmn;\":                          '\\U00002216',\n\t\"ssmile;\":                          '\\U00002323',\n\t\"sstarf;\":                          '\\U000022C6',\n\t\"star;\":                            '\\U00002606',\n\t\"starf;\":                           '\\U00002605',\n\t\"straightepsilon;\":                 '\\U000003F5',\n\t\"straightphi;\":                     '\\U000003D5',\n\t\"strns;\":                           '\\U000000AF',\n\t\"sub;\":                             '\\U00002282',\n\t\"subE;\":                            '\\U00002AC5',\n\t\"subdot;\":                          '\\U00002ABD',\n\t\"sube;\":                            '\\U00002286',\n\t\"subedot;\":                         '\\U00002AC3',\n\t\"submult;\":                         '\\U00002AC1',\n\t\"subnE;\":                           '\\U00002ACB',\n\t\"subne;\":                           '\\U0000228A',\n\t\"subplus;\":                         '\\U00002ABF',\n\t\"subrarr;\":                         '\\U00002979',\n\t\"subset;\":                          '\\U00002282',\n\t\"subseteq;\":                        '\\U00002286',\n\t\"subseteqq;\":                       '\\U00002AC5',\n\t\"subsetneq;\":                       '\\U0000228A',\n\t\"subsetneqq;\":                      '\\U00002ACB',\n\t\"subsim;\":                          '\\U00002AC7',\n\t\"subsub;\":                          '\\U00002AD5',\n\t\"subsup;\":                          '\\U00002AD3',\n\t\"succ;\":                            '\\U0000227B',\n\t\"succapprox;\":                      '\\U00002AB8',\n\t\"succcurlyeq;\":                     '\\U0000227D',\n\t\"succeq;\":                          '\\U00002AB0',\n\t\"succnapprox;\":                     '\\U00002ABA',\n\t\"succneqq;\":                        '\\U00002AB6',\n\t\"succnsim;\":                        '\\U000022E9',\n\t\"succsim;\":                         '\\U0000227F',\n\t\"sum;\":                             '\\U00002211',\n\t\"sung;\":                            '\\U0000266A',\n\t\"sup;\":                             '\\U00002283',\n\t\"sup1;\":                            '\\U000000B9',\n\t\"sup2;\":                            '\\U000000B2',\n\t\"sup3;\":                            '\\U000000B3',\n\t\"supE;\":                            '\\U00002AC6',\n\t\"supdot;\":                          '\\U00002ABE',\n\t\"supdsub;\":                         '\\U00002AD8',\n\t\"supe;\":                            '\\U00002287',\n\t\"supedot;\":                         '\\U00002AC4',\n\t\"suphsol;\":                         '\\U000027C9',\n\t\"suphsub;\":                         '\\U00002AD7',\n\t\"suplarr;\":                         '\\U0000297B',\n\t\"supmult;\":                         '\\U00002AC2',\n\t\"supnE;\":                           '\\U00002ACC',\n\t\"supne;\":                           '\\U0000228B',\n\t\"supplus;\":                         '\\U00002AC0',\n\t\"supset;\":                          '\\U00002283',\n\t\"supseteq;\":                        '\\U00002287',\n\t\"supseteqq;\":                       '\\U00002AC6',\n\t\"supsetneq;\":                       '\\U0000228B',\n\t\"supsetneqq;\":                      '\\U00002ACC',\n\t\"supsim;\":                          '\\U00002AC8',\n\t\"supsub;\":                          '\\U00002AD4',\n\t\"supsup;\":                          '\\U00002AD6',\n\t\"swArr;\":                           '\\U000021D9',\n\t\"swarhk;\":                          '\\U00002926',\n\t\"swarr;\":                           '\\U00002199',\n\t\"swarrow;\":                         '\\U00002199',\n\t\"swnwar;\":                          '\\U0000292A',\n\t\"szlig;\":                           '\\U000000DF',\n\t\"target;\":                          '\\U00002316',\n\t\"tau;\":                             '\\U000003C4',\n\t\"tbrk;\":                            '\\U000023B4',\n\t\"tcaron;\":                          '\\U00000165',\n\t\"tcedil;\":                          '\\U00000163',\n\t\"tcy;\":                             '\\U00000442',\n\t\"tdot;\":                            '\\U000020DB',\n\t\"telrec;\":                          '\\U00002315',\n\t\"tfr;\":                             '\\U0001D531',\n\t\"there4;\":                          '\\U00002234',\n\t\"therefore;\":                       '\\U00002234',\n\t\"theta;\":                           '\\U000003B8',\n\t\"thetasym;\":                        '\\U000003D1',\n\t\"thetav;\":                          '\\U000003D1',\n\t\"thickapprox;\":                     '\\U00002248',\n\t\"thicksim;\":                        '\\U0000223C',\n\t\"thinsp;\":                          '\\U00002009',\n\t\"thkap;\":                           '\\U00002248',\n\t\"thksim;\":                          '\\U0000223C',\n\t\"thorn;\":                           '\\U000000FE',\n\t\"tilde;\":                           '\\U000002DC',\n\t\"times;\":                           '\\U000000D7',\n\t\"timesb;\":                          '\\U000022A0',\n\t\"timesbar;\":                        '\\U00002A31',\n\t\"timesd;\":                          '\\U00002A30',\n\t\"tint;\":                            '\\U0000222D',\n\t\"toea;\":                            '\\U00002928',\n\t\"top;\":                             '\\U000022A4',\n\t\"topbot;\":                          '\\U00002336',\n\t\"topcir;\":                          '\\U00002AF1',\n\t\"topf;\":                            '\\U0001D565',\n\t\"topfork;\":                         '\\U00002ADA',\n\t\"tosa;\":                            '\\U00002929',\n\t\"tprime;\":                          '\\U00002034',\n\t\"trade;\":                           '\\U00002122',\n\t\"triangle;\":                        '\\U000025B5',\n\t\"triangledown;\":                    '\\U000025BF',\n\t\"triangleleft;\":                    '\\U000025C3',\n\t\"trianglelefteq;\":                  '\\U000022B4',\n\t\"triangleq;\":                       '\\U0000225C',\n\t\"triangleright;\":                   '\\U000025B9',\n\t\"trianglerighteq;\":                 '\\U000022B5',\n\t\"tridot;\":                          '\\U000025EC',\n\t\"trie;\":                            '\\U0000225C',\n\t\"triminus;\":                        '\\U00002A3A',\n\t\"triplus;\":                         '\\U00002A39',\n\t\"trisb;\":                           '\\U000029CD',\n\t\"tritime;\":                         '\\U00002A3B',\n\t\"trpezium;\":                        '\\U000023E2',\n\t\"tscr;\":                            '\\U0001D4C9',\n\t\"tscy;\":                            '\\U00000446',\n\t\"tshcy;\":                           '\\U0000045B',\n\t\"tstrok;\":                          '\\U00000167',\n\t\"twixt;\":                           '\\U0000226C',\n\t\"twoheadleftarrow;\":                '\\U0000219E',\n\t\"twoheadrightarrow;\":               '\\U000021A0',\n\t\"uArr;\":                            '\\U000021D1',\n\t\"uHar;\":                            '\\U00002963',\n\t\"uacute;\":                          '\\U000000FA',\n\t\"uarr;\":                            '\\U00002191',\n\t\"ubrcy;\":                           '\\U0000045E',\n\t\"ubreve;\":                          '\\U0000016D',\n\t\"ucirc;\":                           '\\U000000FB',\n\t\"ucy;\":                             '\\U00000443',\n\t\"udarr;\":                           '\\U000021C5',\n\t\"udblac;\":                          '\\U00000171',\n\t\"udhar;\":                           '\\U0000296E',\n\t\"ufisht;\":                          '\\U0000297E',\n\t\"ufr;\":                             '\\U0001D532',\n\t\"ugrave;\":                          '\\U000000F9',\n\t\"uharl;\":                           '\\U000021BF',\n\t\"uharr;\":                           '\\U000021BE',\n\t\"uhblk;\":                           '\\U00002580',\n\t\"ulcorn;\":                          '\\U0000231C',\n\t\"ulcorner;\":                        '\\U0000231C',\n\t\"ulcrop;\":                          '\\U0000230F',\n\t\"ultri;\":                           '\\U000025F8',\n\t\"umacr;\":                           '\\U0000016B',\n\t\"uml;\":                             '\\U000000A8',\n\t\"uogon;\":                           '\\U00000173',\n\t\"uopf;\":                            '\\U0001D566',\n\t\"uparrow;\":                         '\\U00002191',\n\t\"updownarrow;\":                     '\\U00002195',\n\t\"upharpoonleft;\":                   '\\U000021BF',\n\t\"upharpoonright;\":                  '\\U000021BE',\n\t\"uplus;\":                           '\\U0000228E',\n\t\"upsi;\":                            '\\U000003C5',\n\t\"upsih;\":                           '\\U000003D2',\n\t\"upsilon;\":                         '\\U000003C5',\n\t\"upuparrows;\":                      '\\U000021C8',\n\t\"urcorn;\":                          '\\U0000231D',\n\t\"urcorner;\":                        '\\U0000231D',\n\t\"urcrop;\":                          '\\U0000230E',\n\t\"uring;\":                           '\\U0000016F',\n\t\"urtri;\":                           '\\U000025F9',\n\t\"uscr;\":                            '\\U0001D4CA',\n\t\"utdot;\":                           '\\U000022F0',\n\t\"utilde;\":                          '\\U00000169',\n\t\"utri;\":                            '\\U000025B5',\n\t\"utrif;\":                           '\\U000025B4',\n\t\"uuarr;\":                           '\\U000021C8',\n\t\"uuml;\":                            '\\U000000FC',\n\t\"uwangle;\":                         '\\U000029A7',\n\t\"vArr;\":                            '\\U000021D5',\n\t\"vBar;\":                            '\\U00002AE8',\n\t\"vBarv;\":                           '\\U00002AE9',\n\t\"vDash;\":                           '\\U000022A8',\n\t\"vangrt;\":                          '\\U0000299C',\n\t\"varepsilon;\":                      '\\U000003F5',\n\t\"varkappa;\":                        '\\U000003F0',\n\t\"varnothing;\":                      '\\U00002205',\n\t\"varphi;\":                          '\\U000003D5',\n\t\"varpi;\":                           '\\U000003D6',\n\t\"varpropto;\":                       '\\U0000221D',\n\t\"varr;\":                            '\\U00002195',\n\t\"varrho;\":                          '\\U000003F1',\n\t\"varsigma;\":                        '\\U000003C2',\n\t\"vartheta;\":                        '\\U000003D1',\n\t\"vartriangleleft;\":                 '\\U000022B2',\n\t\"vartriangleright;\":                '\\U000022B3',\n\t\"vcy;\":                             '\\U00000432',\n\t\"vdash;\":                           '\\U000022A2',\n\t\"vee;\":                             '\\U00002228',\n\t\"veebar;\":                          '\\U000022BB',\n\t\"veeeq;\":                           '\\U0000225A',\n\t\"vellip;\":                          '\\U000022EE',\n\t\"verbar;\":                          '\\U0000007C',\n\t\"vert;\":                            '\\U0000007C',\n\t\"vfr;\":                             '\\U0001D533',\n\t\"vltri;\":                           '\\U000022B2',\n\t\"vopf;\":                            '\\U0001D567',\n\t\"vprop;\":                           '\\U0000221D',\n\t\"vrtri;\":                           '\\U000022B3',\n\t\"vscr;\":                            '\\U0001D4CB',\n\t\"vzigzag;\":                         '\\U0000299A',\n\t\"wcirc;\":                           '\\U00000175',\n\t\"wedbar;\":                          '\\U00002A5F',\n\t\"wedge;\":                           '\\U00002227',\n\t\"wedgeq;\":                          '\\U00002259',\n\t\"weierp;\":                          '\\U00002118',\n\t\"wfr;\":                             '\\U0001D534',\n\t\"wopf;\":                            '\\U0001D568',\n\t\"wp;\":                              '\\U00002118',\n\t\"wr;\":                              '\\U00002240',\n\t\"wreath;\":                          '\\U00002240',\n\t\"wscr;\":                            '\\U0001D4CC',\n\t\"xcap;\":                            '\\U000022C2',\n\t\"xcirc;\":                           '\\U000025EF',\n\t\"xcup;\":                            '\\U000022C3',\n\t\"xdtri;\":                           '\\U000025BD',\n\t\"xfr;\":                             '\\U0001D535',\n\t\"xhArr;\":                           '\\U000027FA',\n\t\"xharr;\":                           '\\U000027F7',\n\t\"xi;\":                              '\\U000003BE',\n\t\"xlArr;\":                           '\\U000027F8',\n\t\"xlarr;\":                           '\\U000027F5',\n\t\"xmap;\":                            '\\U000027FC',\n\t\"xnis;\":                            '\\U000022FB',\n\t\"xodot;\":                           '\\U00002A00',\n\t\"xopf;\":                            '\\U0001D569',\n\t\"xoplus;\":                          '\\U00002A01',\n\t\"xotime;\":                          '\\U00002A02',\n\t\"xrArr;\":                           '\\U000027F9',\n\t\"xrarr;\":                           '\\U000027F6',\n\t\"xscr;\":                            '\\U0001D4CD',\n\t\"xsqcup;\":                          '\\U00002A06',\n\t\"xuplus;\":                          '\\U00002A04',\n\t\"xutri;\":                           '\\U000025B3',\n\t\"xvee;\":                            '\\U000022C1',\n\t\"xwedge;\":                          '\\U000022C0',\n\t\"yacute;\":                          '\\U000000FD',\n\t\"yacy;\":                            '\\U0000044F',\n\t\"ycirc;\":                           '\\U00000177',\n\t\"ycy;\":                             '\\U0000044B',\n\t\"yen;\":                             '\\U000000A5',\n\t\"yfr;\":                             '\\U0001D536',\n\t\"yicy;\":                            '\\U00000457',\n\t\"yopf;\":                            '\\U0001D56A',\n\t\"yscr;\":                            '\\U0001D4CE',\n\t\"yucy;\":                            '\\U0000044E',\n\t\"yuml;\":                            '\\U000000FF',\n\t\"zacute;\":                          '\\U0000017A',\n\t\"zcaron;\":                          '\\U0000017E',\n\t\"zcy;\":                             '\\U00000437',\n\t\"zdot;\":                            '\\U0000017C',\n\t\"zeetrf;\":                          '\\U00002128',\n\t\"zeta;\":                            '\\U000003B6',\n\t\"zfr;\":                             '\\U0001D537',\n\t\"zhcy;\":                            '\\U00000436',\n\t\"zigrarr;\":                         '\\U000021DD',\n\t\"zopf;\":                            '\\U0001D56B',\n\t\"zscr;\":                            '\\U0001D4CF',\n\t\"zwj;\":                             '\\U0000200D',\n\t\"zwnj;\":                            '\\U0000200C',\n\t\"AElig\":                            '\\U000000C6',\n\t\"AMP\":                              '\\U00000026',\n\t\"Aacute\":                           '\\U000000C1',\n\t\"Acirc\":                            '\\U000000C2',\n\t\"Agrave\":                           '\\U000000C0',\n\t\"Aring\":                            '\\U000000C5',\n\t\"Atilde\":                           '\\U000000C3',\n\t\"Auml\":                             '\\U000000C4',\n\t\"COPY\":                             '\\U000000A9',\n\t\"Ccedil\":                           '\\U000000C7',\n\t\"ETH\":                              '\\U000000D0',\n\t\"Eacute\":                           '\\U000000C9',\n\t\"Ecirc\":                            '\\U000000CA',\n\t\"Egrave\":                           '\\U000000C8',\n\t\"Euml\":                             '\\U000000CB',\n\t\"GT\":                               '\\U0000003E',\n\t\"Iacute\":                           '\\U000000CD',\n\t\"Icirc\":                            '\\U000000CE',\n\t\"Igrave\":                           '\\U000000CC',\n\t\"Iuml\":                             '\\U000000CF',\n\t\"LT\":                               '\\U0000003C',\n\t\"Ntilde\":                           '\\U000000D1',\n\t\"Oacute\":                           '\\U000000D3',\n\t\"Ocirc\":                            '\\U000000D4',\n\t\"Ograve\":                           '\\U000000D2',\n\t\"Oslash\":                           '\\U000000D8',\n\t\"Otilde\":                           '\\U000000D5',\n\t\"Ouml\":                             '\\U000000D6',\n\t\"QUOT\":                             '\\U00000022',\n\t\"REG\":                              '\\U000000AE',\n\t\"THORN\":                            '\\U000000DE',\n\t\"Uacute\":                           '\\U000000DA',\n\t\"Ucirc\":                            '\\U000000DB',\n\t\"Ugrave\":                           '\\U000000D9',\n\t\"Uuml\":                             '\\U000000DC',\n\t\"Yacute\":                           '\\U000000DD',\n\t\"aacute\":                           '\\U000000E1',\n\t\"acirc\":                            '\\U000000E2',\n\t\"acute\":                            '\\U000000B4',\n\t\"aelig\":                            '\\U000000E6',\n\t\"agrave\":                           '\\U000000E0',\n\t\"amp\":                              '\\U00000026',\n\t\"aring\":                            '\\U000000E5',\n\t\"atilde\":                           '\\U000000E3',\n\t\"auml\":                             '\\U000000E4',\n\t\"brvbar\":                           '\\U000000A6',\n\t\"ccedil\":                           '\\U000000E7',\n\t\"cedil\":                            '\\U000000B8',\n\t\"cent\":                             '\\U000000A2',\n\t\"copy\":                             '\\U000000A9',\n\t\"curren\":                           '\\U000000A4',\n\t\"deg\":                              '\\U000000B0',\n\t\"divide\":                           '\\U000000F7',\n\t\"eacute\":                           '\\U000000E9',\n\t\"ecirc\":                            '\\U000000EA',\n\t\"egrave\":                           '\\U000000E8',\n\t\"eth\":                              '\\U000000F0',\n\t\"euml\":                             '\\U000000EB',\n\t\"frac12\":                           '\\U000000BD',\n\t\"frac14\":                           '\\U000000BC',\n\t\"frac34\":                           '\\U000000BE',\n\t\"gt\":                               '\\U0000003E',\n\t\"iacute\":                           '\\U000000ED',\n\t\"icirc\":                            '\\U000000EE',\n\t\"iexcl\":                            '\\U000000A1',\n\t\"igrave\":                           '\\U000000EC',\n\t\"iquest\":                           '\\U000000BF',\n\t\"iuml\":                             '\\U000000EF',\n\t\"laquo\":                            '\\U000000AB',\n\t\"lt\":                               '\\U0000003C',\n\t\"macr\":                             '\\U000000AF',\n\t\"micro\":                            '\\U000000B5',\n\t\"middot\":                           '\\U000000B7',\n\t\"nbsp\":                             '\\U000000A0',\n\t\"not\":                              '\\U000000AC',\n\t\"ntilde\":                           '\\U000000F1',\n\t\"oacute\":                           '\\U000000F3',\n\t\"ocirc\":                            '\\U000000F4',\n\t\"ograve\":                           '\\U000000F2',\n\t\"ordf\":                             '\\U000000AA',\n\t\"ordm\":                             '\\U000000BA',\n\t\"oslash\":                           '\\U000000F8',\n\t\"otilde\":                           '\\U000000F5',\n\t\"ouml\":                             '\\U000000F6',\n\t\"para\":                             '\\U000000B6',\n\t\"plusmn\":                           '\\U000000B1',\n\t\"pound\":                            '\\U000000A3',\n\t\"quot\":                             '\\U00000022',\n\t\"raquo\":                            '\\U000000BB',\n\t\"reg\":                              '\\U000000AE',\n\t\"sect\":                             '\\U000000A7',\n\t\"shy\":                              '\\U000000AD',\n\t\"sup1\":                             '\\U000000B9',\n\t\"sup2\":                             '\\U000000B2',\n\t\"sup3\":                             '\\U000000B3',\n\t\"szlig\":                            '\\U000000DF',\n\t\"thorn\":                            '\\U000000FE',\n\t\"times\":                            '\\U000000D7',\n\t\"uacute\":                           '\\U000000FA',\n\t\"ucirc\":                            '\\U000000FB',\n\t\"ugrave\":                           '\\U000000F9',\n\t\"uml\":                              '\\U000000A8',\n\t\"uuml\":                             '\\U000000FC',\n\t\"yacute\":                           '\\U000000FD',\n\t\"yen\":                              '\\U000000A5',\n\t\"yuml\":                             '\\U000000FF',\n}\n\n// HTML entities that are two unicode codepoints.\nvar entity2 = map[string][2]rune{\n\t// TODO(nigeltao): Handle replacements that are wider than their names.\n\t// \"nLt;\":                     {'\\u226A', '\\u20D2'},\n\t// \"nGt;\":                     {'\\u226B', '\\u20D2'},\n\t\"NotEqualTilde;\":           {'\\u2242', '\\u0338'},\n\t\"NotGreaterFullEqual;\":     {'\\u2267', '\\u0338'},\n\t\"NotGreaterGreater;\":       {'\\u226B', '\\u0338'},\n\t\"NotGreaterSlantEqual;\":    {'\\u2A7E', '\\u0338'},\n\t\"NotHumpDownHump;\":         {'\\u224E', '\\u0338'},\n\t\"NotHumpEqual;\":            {'\\u224F', '\\u0338'},\n\t\"NotLeftTriangleBar;\":      {'\\u29CF', '\\u0338'},\n\t\"NotLessLess;\":             {'\\u226A', '\\u0338'},\n\t\"NotLessSlantEqual;\":       {'\\u2A7D', '\\u0338'},\n\t\"NotNestedGreaterGreater;\": {'\\u2AA2', '\\u0338'},\n\t\"NotNestedLessLess;\":       {'\\u2AA1', '\\u0338'},\n\t\"NotPrecedesEqual;\":        {'\\u2AAF', '\\u0338'},\n\t\"NotRightTriangleBar;\":     {'\\u29D0', '\\u0338'},\n\t\"NotSquareSubset;\":         {'\\u228F', '\\u0338'},\n\t\"NotSquareSuperset;\":       {'\\u2290', '\\u0338'},\n\t\"NotSubset;\":               {'\\u2282', '\\u20D2'},\n\t\"NotSucceedsEqual;\":        {'\\u2AB0', '\\u0338'},\n\t\"NotSucceedsTilde;\":        {'\\u227F', '\\u0338'},\n\t\"NotSuperset;\":             {'\\u2283', '\\u20D2'},\n\t\"ThickSpace;\":              {'\\u205F', '\\u200A'},\n\t\"acE;\":                     {'\\u223E', '\\u0333'},\n\t\"bne;\":                     {'\\u003D', '\\u20E5'},\n\t\"bnequiv;\":                 {'\\u2261', '\\u20E5'},\n\t\"caps;\":                    {'\\u2229', '\\uFE00'},\n\t\"cups;\":                    {'\\u222A', '\\uFE00'},\n\t\"fjlig;\":                   {'\\u0066', '\\u006A'},\n\t\"gesl;\":                    {'\\u22DB', '\\uFE00'},\n\t\"gvertneqq;\":               {'\\u2269', '\\uFE00'},\n\t\"gvnE;\":                    {'\\u2269', '\\uFE00'},\n\t\"lates;\":                   {'\\u2AAD', '\\uFE00'},\n\t\"lesg;\":                    {'\\u22DA', '\\uFE00'},\n\t\"lvertneqq;\":               {'\\u2268', '\\uFE00'},\n\t\"lvnE;\":                    {'\\u2268', '\\uFE00'},\n\t\"nGg;\":                     {'\\u22D9', '\\u0338'},\n\t\"nGtv;\":                    {'\\u226B', '\\u0338'},\n\t\"nLl;\":                     {'\\u22D8', '\\u0338'},\n\t\"nLtv;\":                    {'\\u226A', '\\u0338'},\n\t\"nang;\":                    {'\\u2220', '\\u20D2'},\n\t\"napE;\":                    {'\\u2A70', '\\u0338'},\n\t\"napid;\":                   {'\\u224B', '\\u0338'},\n\t\"nbump;\":                   {'\\u224E', '\\u0338'},\n\t\"nbumpe;\":                  {'\\u224F', '\\u0338'},\n\t\"ncongdot;\":                {'\\u2A6D', '\\u0338'},\n\t\"nedot;\":                   {'\\u2250', '\\u0338'},\n\t\"nesim;\":                   {'\\u2242', '\\u0338'},\n\t\"ngE;\":                     {'\\u2267', '\\u0338'},\n\t\"ngeqq;\":                   {'\\u2267', '\\u0338'},\n\t\"ngeqslant;\":               {'\\u2A7E', '\\u0338'},\n\t\"nges;\":                    {'\\u2A7E', '\\u0338'},\n\t\"nlE;\":                     {'\\u2266', '\\u0338'},\n\t\"nleqq;\":                   {'\\u2266', '\\u0338'},\n\t\"nleqslant;\":               {'\\u2A7D', '\\u0338'},\n\t\"nles;\":                    {'\\u2A7D', '\\u0338'},\n\t\"notinE;\":                  {'\\u22F9', '\\u0338'},\n\t\"notindot;\":                {'\\u22F5', '\\u0338'},\n\t\"nparsl;\":                  {'\\u2AFD', '\\u20E5'},\n\t\"npart;\":                   {'\\u2202', '\\u0338'},\n\t\"npre;\":                    {'\\u2AAF', '\\u0338'},\n\t\"npreceq;\":                 {'\\u2AAF', '\\u0338'},\n\t\"nrarrc;\":                  {'\\u2933', '\\u0338'},\n\t\"nrarrw;\":                  {'\\u219D', '\\u0338'},\n\t\"nsce;\":                    {'\\u2AB0', '\\u0338'},\n\t\"nsubE;\":                   {'\\u2AC5', '\\u0338'},\n\t\"nsubset;\":                 {'\\u2282', '\\u20D2'},\n\t\"nsubseteqq;\":              {'\\u2AC5', '\\u0338'},\n\t\"nsucceq;\":                 {'\\u2AB0', '\\u0338'},\n\t\"nsupE;\":                   {'\\u2AC6', '\\u0338'},\n\t\"nsupset;\":                 {'\\u2283', '\\u20D2'},\n\t\"nsupseteqq;\":              {'\\u2AC6', '\\u0338'},\n\t\"nvap;\":                    {'\\u224D', '\\u20D2'},\n\t\"nvge;\":                    {'\\u2265', '\\u20D2'},\n\t\"nvgt;\":                    {'\\u003E', '\\u20D2'},\n\t\"nvle;\":                    {'\\u2264', '\\u20D2'},\n\t\"nvlt;\":                    {'\\u003C', '\\u20D2'},\n\t\"nvltrie;\":                 {'\\u22B4', '\\u20D2'},\n\t\"nvrtrie;\":                 {'\\u22B5', '\\u20D2'},\n\t\"nvsim;\":                   {'\\u223C', '\\u20D2'},\n\t\"race;\":                    {'\\u223D', '\\u0331'},\n\t\"smtes;\":                   {'\\u2AAC', '\\uFE00'},\n\t\"sqcaps;\":                  {'\\u2293', '\\uFE00'},\n\t\"sqcups;\":                  {'\\u2294', '\\uFE00'},\n\t\"varsubsetneq;\":            {'\\u228A', '\\uFE00'},\n\t\"varsubsetneqq;\":           {'\\u2ACB', '\\uFE00'},\n\t\"varsupsetneq;\":            {'\\u228B', '\\uFE00'},\n\t\"varsupsetneqq;\":           {'\\u2ACC', '\\uFE00'},\n\t\"vnsub;\":                   {'\\u2282', '\\u20D2'},\n\t\"vnsup;\":                   {'\\u2283', '\\u20D2'},\n\t\"vsubnE;\":                  {'\\u2ACB', '\\uFE00'},\n\t\"vsubne;\":                  {'\\u228A', '\\uFE00'},\n\t\"vsupnE;\":                  {'\\u2ACC', '\\uFE00'},\n\t\"vsupne;\":                  {'\\u228B', '\\uFE00'},\n}\n"
  },
  {
    "path": "internal/escape.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\nimport (\n\t\"bytes\"\n\t\"io\"\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\ntype writer interface {\n\tio.Writer\n\tio.ByteWriter\n\tWriteString(string) (int, error)\n}\n\n// These replacements permit compatibility with old numeric entities that\n// assumed Windows-1252 encoding.\n// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference\nvar replacementTable = [...]rune{\n\t'\\u20AC', // First entry is what 0x80 should be replaced with.\n\t'\\u0081',\n\t'\\u201A',\n\t'\\u0192',\n\t'\\u201E',\n\t'\\u2026',\n\t'\\u2020',\n\t'\\u2021',\n\t'\\u02C6',\n\t'\\u2030',\n\t'\\u0160',\n\t'\\u2039',\n\t'\\u0152',\n\t'\\u008D',\n\t'\\u017D',\n\t'\\u008F',\n\t'\\u0090',\n\t'\\u2018',\n\t'\\u2019',\n\t'\\u201C',\n\t'\\u201D',\n\t'\\u2022',\n\t'\\u2013',\n\t'\\u2014',\n\t'\\u02DC',\n\t'\\u2122',\n\t'\\u0161',\n\t'\\u203A',\n\t'\\u0153',\n\t'\\u009D',\n\t'\\u017E',\n\t'\\u0178', // Last entry is 0x9F.\n\t// 0x00->'\\uFFFD' is handled programmatically.\n\t// 0x0D->'\\u000D' is a no-op.\n}\n\n// unescapeEntity reads an entity like \"&lt;\" from b[src:] and writes the\n// corresponding \"<\" to b[dst:], returning the incremented dst and src cursors.\n// Precondition: b[src] == '&' && dst <= src.\n// attribute should be true if parsing an attribute value.\nfunc unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {\n\t// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference\n\n\t// i starts at 1 because we already know that s[0] == '&'.\n\ti, s := 1, b[src:]\n\n\tif len(s) <= 1 {\n\t\tb[dst] = b[src]\n\t\treturn dst + 1, src + 1\n\t}\n\n\tif s[i] == '#' {\n\t\tif len(s) <= 3 { // We need to have at least \"&#.\".\n\t\t\tb[dst] = b[src]\n\t\t\treturn dst + 1, src + 1\n\t\t}\n\t\ti++\n\t\tc := s[i]\n\t\thex := false\n\t\tif c == 'x' || c == 'X' {\n\t\t\thex = true\n\t\t\ti++\n\t\t}\n\n\t\tx := '\\x00'\n\t\tfor i < len(s) {\n\t\t\tc = s[i]\n\t\t\ti++\n\t\t\tif hex {\n\t\t\t\tif '0' <= c && c <= '9' {\n\t\t\t\t\tx = 16*x + rune(c) - '0'\n\t\t\t\t\tcontinue\n\t\t\t\t} else if 'a' <= c && c <= 'f' {\n\t\t\t\t\tx = 16*x + rune(c) - 'a' + 10\n\t\t\t\t\tcontinue\n\t\t\t\t} else if 'A' <= c && c <= 'F' {\n\t\t\t\t\tx = 16*x + rune(c) - 'A' + 10\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t} else if '0' <= c && c <= '9' {\n\t\t\t\tx = 10*x + rune(c) - '0'\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c != ';' {\n\t\t\t\ti--\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\tif i <= 3 { // No characters matched.\n\t\t\tb[dst] = b[src]\n\t\t\treturn dst + 1, src + 1\n\t\t}\n\n\t\tif 0x80 <= x && x <= 0x9F {\n\t\t\t// Replace characters from Windows-1252 with UTF-8 equivalents.\n\t\t\tx = replacementTable[x-0x80]\n\t\t} else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF {\n\t\t\t// Replace invalid characters with the replacement character.\n\t\t\tx = '\\uFFFD'\n\t\t}\n\n\t\treturn dst + utf8.EncodeRune(b[dst:], x), src + i\n\t}\n\n\t// Consume the maximum number of characters possible, with the\n\t// consumed characters matching one of the named references.\n\n\tfor i < len(s) {\n\t\tc := s[i]\n\t\ti++\n\t\t// Lower-cased characters are more common in entities, so we check for them first.\n\t\tif 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {\n\t\t\tcontinue\n\t\t}\n\t\tif c != ';' {\n\t\t\ti--\n\t\t}\n\t\tbreak\n\t}\n\n\tentityName := string(s[1:i])\n\tif entityName == \"\" {\n\t\t// No-op.\n\t} else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {\n\t\t// No-op.\n\t} else if x := entity[entityName]; x != 0 {\n\t\treturn dst + utf8.EncodeRune(b[dst:], x), src + i\n\t} else if x := entity2[entityName]; x[0] != 0 {\n\t\tdst1 := dst + utf8.EncodeRune(b[dst:], x[0])\n\t\treturn dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i\n\t} else if !attribute {\n\t\tmaxLen := len(entityName) - 1\n\t\tif maxLen > longestEntityWithoutSemicolon {\n\t\t\tmaxLen = longestEntityWithoutSemicolon\n\t\t}\n\t\tfor j := maxLen; j > 1; j-- {\n\t\t\tif x := entity[entityName[:j]]; x != 0 {\n\t\t\t\treturn dst + utf8.EncodeRune(b[dst:], x), src + j + 1\n\t\t\t}\n\t\t}\n\t}\n\n\tdst1, src1 = dst+i, src+i\n\tcopy(b[dst:dst1], b[src:src1])\n\treturn dst1, src1\n}\n\n// unescape unescapes b's entities in-place, so that \"a&lt;b\" becomes \"a<b\".\n// attribute should be true if parsing an attribute value.\nfunc unescape(b []byte, attribute bool) []byte {\n\tfor i, c := range b {\n\t\tif c == '&' {\n\t\t\tdst, src := unescapeEntity(b, i, i, attribute)\n\t\t\tfor src < len(b) {\n\t\t\t\tc := b[src]\n\t\t\t\tif c == '&' {\n\t\t\t\t\tdst, src = unescapeEntity(b, dst, src, attribute)\n\t\t\t\t} else {\n\t\t\t\t\tb[dst] = c\n\t\t\t\t\tdst, src = dst+1, src+1\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn b[0:dst]\n\t\t}\n\t}\n\treturn b\n}\n\nconst escapedChars = \"&'<>\\\"\\r\"\n\nfunc escape(w writer, s string) error {\n\ti := strings.IndexAny(s, escapedChars)\n\tfor i != -1 {\n\t\tif _, err := w.WriteString(s[:i]); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tvar esc string\n\t\tswitch s[i] {\n\t\tcase '&':\n\t\t\tesc = \"&amp;\"\n\t\tcase '\\'':\n\t\t\t// \"&#39;\" is shorter than \"&apos;\" and apos was not in HTML until HTML5.\n\t\t\tesc = \"&#39;\"\n\t\tcase '<':\n\t\t\tesc = \"&lt;\"\n\t\tcase '>':\n\t\t\tesc = \"&gt;\"\n\t\tcase '\"':\n\t\t\t// \"&#34;\" is shorter than \"&quot;\".\n\t\t\tesc = \"&#34;\"\n\t\tcase '\\r':\n\t\t\tesc = \"&#13;\"\n\t\tdefault:\n\t\t\tpanic(\"unrecognized escape character\")\n\t\t}\n\t\ts = s[i+1:]\n\t\tif _, err := w.WriteString(esc); err != nil {\n\t\t\treturn err\n\t\t}\n\t\ti = strings.IndexAny(s, escapedChars)\n\t}\n\t_, err := w.WriteString(s)\n\treturn err\n}\n\n// EscapeString escapes special characters like \"<\" to become \"&lt;\". It\n// escapes only five such characters: <, >, &, ' and \".\n// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't\n// always true.\nfunc EscapeString(s string) string {\n\tif !strings.ContainsAny(s, escapedChars) {\n\t\treturn s\n\t}\n\tvar buf bytes.Buffer\n\tescape(&buf, s)\n\treturn buf.String()\n}\n\n// UnescapeString unescapes entities like \"&lt;\" to become \"<\". It unescapes a\n// larger range of entities than EscapeString escapes. For example, \"&aacute;\"\n// unescapes to \"á\", as does \"&#225;\" and \"&xE1;\".\n// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't\n// always true.\nfunc UnescapeString(s string) string {\n\tfor _, c := range s {\n\t\tif c == '&' {\n\t\t\treturn string(unescape([]byte(s), false))\n\t\t}\n\t}\n\treturn s\n}\n"
  },
  {
    "path": "internal/foreign.go",
    "content": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\nimport (\n\t\"strings\"\n)\n\nfunc adjustAttributeNames(aa []Attribute, nameMap map[string]string) {\n\tfor i := range aa {\n\t\tif newName, ok := nameMap[aa[i].Key]; ok {\n\t\t\taa[i].Key = newName\n\t\t}\n\t}\n}\n\nfunc adjustForeignAttributes(aa []Attribute) {\n\tfor i, a := range aa {\n\t\tif a.Key == \"\" || a.Key[0] != 'x' {\n\t\t\tcontinue\n\t\t}\n\t\tswitch a.Key {\n\t\tcase \"xlink:actuate\", \"xlink:arcrole\", \"xlink:href\", \"xlink:role\", \"xlink:show\",\n\t\t\t\"xlink:title\", \"xlink:type\", \"xml:base\", \"xml:lang\", \"xml:space\", \"xmlns:xlink\":\n\t\t\tj := strings.Index(a.Key, \":\")\n\t\t\taa[i].Namespace = a.Key[:j]\n\t\t\taa[i].Key = a.Key[j+1:]\n\t\t}\n\t}\n}\n\nfunc htmlIntegrationPoint(n *Node) bool {\n\tif n.Type != ElementNode {\n\t\treturn false\n\t}\n\tswitch n.Namespace {\n\tcase \"math\":\n\t\tif n.Data == \"annotation-xml\" {\n\t\t\tfor _, a := range n.Attr {\n\t\t\t\tif a.Key == \"encoding\" {\n\t\t\t\t\tval := strings.ToLower(a.Val)\n\t\t\t\t\tif val == \"text/html\" || val == \"application/xhtml+xml\" {\n\t\t\t\t\t\treturn true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tcase \"svg\":\n\t\tswitch n.Data {\n\t\tcase \"desc\", \"foreignObject\", \"title\":\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc mathMLTextIntegrationPoint(n *Node) bool {\n\tif n.Namespace != \"math\" {\n\t\treturn false\n\t}\n\tswitch n.Data {\n\tcase \"mi\", \"mo\", \"mn\", \"ms\", \"mtext\":\n\t\treturn true\n\t}\n\treturn false\n}\n\n// Section 12.2.6.5.\nvar breakout = map[string]bool{\n\t\"b\":          true,\n\t\"big\":        true,\n\t\"blockquote\": true,\n\t\"body\":       true,\n\t\"br\":         true,\n\t\"center\":     true,\n\t\"code\":       true,\n\t\"dd\":         true,\n\t\"div\":        true,\n\t\"dl\":         true,\n\t\"dt\":         true,\n\t\"em\":         true,\n\t\"embed\":      true,\n\t\"h1\":         true,\n\t\"h2\":         true,\n\t\"h3\":         true,\n\t\"h4\":         true,\n\t\"h5\":         true,\n\t\"h6\":         true,\n\t\"head\":       true,\n\t\"hr\":         true,\n\t\"i\":          true,\n\t\"img\":        true,\n\t\"li\":         true,\n\t\"listing\":    true,\n\t\"menu\":       true,\n\t\"meta\":       true,\n\t\"nobr\":       true,\n\t\"ol\":         true,\n\t\"p\":          true,\n\t\"pre\":        true,\n\t\"ruby\":       true,\n\t\"s\":          true,\n\t\"small\":      true,\n\t\"span\":       true,\n\t\"strong\":     true,\n\t\"strike\":     true,\n\t\"sub\":        true,\n\t\"sup\":        true,\n\t\"table\":      true,\n\t\"tt\":         true,\n\t\"u\":          true,\n\t\"ul\":         true,\n\t\"var\":        true,\n}\n\n// Section 12.2.6.5.\nvar svgTagNameAdjustments = map[string]string{\n\t\"altglyph\":            \"altGlyph\",\n\t\"altglyphdef\":         \"altGlyphDef\",\n\t\"altglyphitem\":        \"altGlyphItem\",\n\t\"animatecolor\":        \"animateColor\",\n\t\"animatemotion\":       \"animateMotion\",\n\t\"animatetransform\":    \"animateTransform\",\n\t\"clippath\":            \"clipPath\",\n\t\"feblend\":             \"feBlend\",\n\t\"fecolormatrix\":       \"feColorMatrix\",\n\t\"fecomponenttransfer\": \"feComponentTransfer\",\n\t\"fecomposite\":         \"feComposite\",\n\t\"feconvolvematrix\":    \"feConvolveMatrix\",\n\t\"fediffuselighting\":   \"feDiffuseLighting\",\n\t\"fedisplacementmap\":   \"feDisplacementMap\",\n\t\"fedistantlight\":      \"feDistantLight\",\n\t\"feflood\":             \"feFlood\",\n\t\"fefunca\":             \"feFuncA\",\n\t\"fefuncb\":             \"feFuncB\",\n\t\"fefuncg\":             \"feFuncG\",\n\t\"fefuncr\":             \"feFuncR\",\n\t\"fegaussianblur\":      \"feGaussianBlur\",\n\t\"feimage\":             \"feImage\",\n\t\"femerge\":             \"feMerge\",\n\t\"femergenode\":         \"feMergeNode\",\n\t\"femorphology\":        \"feMorphology\",\n\t\"feoffset\":            \"feOffset\",\n\t\"fepointlight\":        \"fePointLight\",\n\t\"fespecularlighting\":  \"feSpecularLighting\",\n\t\"fespotlight\":         \"feSpotLight\",\n\t\"fetile\":              \"feTile\",\n\t\"feturbulence\":        \"feTurbulence\",\n\t\"foreignobject\":       \"foreignObject\",\n\t\"glyphref\":            \"glyphRef\",\n\t\"lineargradient\":      \"linearGradient\",\n\t\"radialgradient\":      \"radialGradient\",\n\t\"textpath\":            \"textPath\",\n}\n\n// Section 12.2.6.1\nvar mathMLAttributeAdjustments = map[string]string{\n\t\"definitionurl\": \"definitionURL\",\n}\n\nvar svgAttributeAdjustments = map[string]string{\n\t\"attributename\":       \"attributeName\",\n\t\"attributetype\":       \"attributeType\",\n\t\"basefrequency\":       \"baseFrequency\",\n\t\"baseprofile\":         \"baseProfile\",\n\t\"calcmode\":            \"calcMode\",\n\t\"clippathunits\":       \"clipPathUnits\",\n\t\"diffuseconstant\":     \"diffuseConstant\",\n\t\"edgemode\":            \"edgeMode\",\n\t\"filterunits\":         \"filterUnits\",\n\t\"glyphref\":            \"glyphRef\",\n\t\"gradienttransform\":   \"gradientTransform\",\n\t\"gradientunits\":       \"gradientUnits\",\n\t\"kernelmatrix\":        \"kernelMatrix\",\n\t\"kernelunitlength\":    \"kernelUnitLength\",\n\t\"keypoints\":           \"keyPoints\",\n\t\"keysplines\":          \"keySplines\",\n\t\"keytimes\":            \"keyTimes\",\n\t\"lengthadjust\":        \"lengthAdjust\",\n\t\"limitingconeangle\":   \"limitingConeAngle\",\n\t\"markerheight\":        \"markerHeight\",\n\t\"markerunits\":         \"markerUnits\",\n\t\"markerwidth\":         \"markerWidth\",\n\t\"maskcontentunits\":    \"maskContentUnits\",\n\t\"maskunits\":           \"maskUnits\",\n\t\"numoctaves\":          \"numOctaves\",\n\t\"pathlength\":          \"pathLength\",\n\t\"patterncontentunits\": \"patternContentUnits\",\n\t\"patterntransform\":    \"patternTransform\",\n\t\"patternunits\":        \"patternUnits\",\n\t\"pointsatx\":           \"pointsAtX\",\n\t\"pointsaty\":           \"pointsAtY\",\n\t\"pointsatz\":           \"pointsAtZ\",\n\t\"preservealpha\":       \"preserveAlpha\",\n\t\"preserveaspectratio\": \"preserveAspectRatio\",\n\t\"primitiveunits\":      \"primitiveUnits\",\n\t\"refx\":                \"refX\",\n\t\"refy\":                \"refY\",\n\t\"repeatcount\":         \"repeatCount\",\n\t\"repeatdur\":           \"repeatDur\",\n\t\"requiredextensions\":  \"requiredExtensions\",\n\t\"requiredfeatures\":    \"requiredFeatures\",\n\t\"specularconstant\":    \"specularConstant\",\n\t\"specularexponent\":    \"specularExponent\",\n\t\"spreadmethod\":        \"spreadMethod\",\n\t\"startoffset\":         \"startOffset\",\n\t\"stddeviation\":        \"stdDeviation\",\n\t\"stitchtiles\":         \"stitchTiles\",\n\t\"surfacescale\":        \"surfaceScale\",\n\t\"systemlanguage\":      \"systemLanguage\",\n\t\"tablevalues\":         \"tableValues\",\n\t\"targetx\":             \"targetX\",\n\t\"targety\":             \"targetY\",\n\t\"textlength\":          \"textLength\",\n\t\"viewbox\":             \"viewBox\",\n\t\"viewtarget\":          \"viewTarget\",\n\t\"xchannelselector\":    \"xChannelSelector\",\n\t\"ychannelselector\":    \"yChannelSelector\",\n\t\"zoomandpan\":          \"zoomAndPan\",\n}\n"
  },
  {
    "path": "internal/handler/handler.go",
    "content": "package handler\n\nimport (\n\t\"errors\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"github.com/withastro/compiler/internal/sourcemap\"\n)\n\ntype Handler struct {\n\tsourcetext string\n\tfilename   string\n\tbuilder    sourcemap.ChunkBuilder\n\terrors     []error\n\twarnings   []error\n\tinfos      []error\n\thints      []error\n}\n\nfunc NewHandler(sourcetext string, filename string) *Handler {\n\treturn &Handler{\n\t\tsourcetext: sourcetext,\n\t\tfilename:   filename,\n\t\tbuilder:    sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(sourcetext, len(strings.Split(sourcetext, \"\\n\")))),\n\t\terrors:     make([]error, 0),\n\t\twarnings:   make([]error, 0),\n\t\tinfos:      make([]error, 0),\n\t\thints:      make([]error, 0),\n\t}\n}\n\nfunc (h *Handler) HasErrors() bool {\n\treturn len(h.errors) > 0\n}\n\nfunc (h *Handler) AppendError(err error) {\n\th.errors = append(h.errors, err)\n}\n\nfunc (h *Handler) AppendWarning(err error) {\n\th.warnings = append(h.warnings, err)\n}\n\nfunc (h *Handler) AppendInfo(err error) {\n\th.infos = append(h.infos, err)\n}\n\nfunc (h *Handler) AppendHint(err error) {\n\th.hints = append(h.hints, err)\n}\n\nfunc (h *Handler) Errors() []loc.DiagnosticMessage {\n\tmsgs := make([]loc.DiagnosticMessage, 0)\n\tfor _, err := range h.errors {\n\t\tif err != nil {\n\t\t\tmsgs = append(msgs, ErrorToMessage(h, loc.ErrorType, err))\n\t\t}\n\t}\n\treturn msgs\n}\n\nfunc (h *Handler) Warnings() []loc.DiagnosticMessage {\n\tmsgs := make([]loc.DiagnosticMessage, 0)\n\tfor _, err := range h.warnings {\n\t\tif err != nil {\n\t\t\tmsgs = append(msgs, ErrorToMessage(h, loc.WarningType, err))\n\t\t}\n\t}\n\treturn msgs\n}\n\nfunc (h *Handler) Diagnostics() []loc.DiagnosticMessage {\n\tmsgs := make([]loc.DiagnosticMessage, 0)\n\tfor _, err := range h.errors {\n\t\tif err != nil {\n\t\t\tmsgs = append(msgs, ErrorToMessage(h, loc.ErrorType, err))\n\t\t}\n\t}\n\tfor _, err := range h.warnings {\n\t\tif err != nil {\n\t\t\tmsgs = append(msgs, ErrorToMessage(h, loc.WarningType, err))\n\t\t}\n\t}\n\tfor _, err := range h.infos {\n\t\tif err != nil {\n\t\t\tmsgs = append(msgs, ErrorToMessage(h, loc.InformationType, err))\n\t\t}\n\t}\n\tfor _, err := range h.hints {\n\t\tif err != nil {\n\t\t\tmsgs = append(msgs, ErrorToMessage(h, loc.HintType, err))\n\t\t}\n\t}\n\treturn msgs\n}\n\nfunc ErrorToMessage(h *Handler, severity loc.DiagnosticSeverity, err error) loc.DiagnosticMessage {\n\tvar rangedError *loc.ErrorWithRange\n\tswitch {\n\tcase errors.As(err, &rangedError):\n\t\tpos := h.builder.GetLineAndColumnForLocation(rangedError.Range.Loc)\n\t\tlocation := &loc.DiagnosticLocation{\n\t\t\tFile:   h.filename,\n\t\t\tLine:   pos[0],\n\t\t\tColumn: pos[1],\n\t\t\tLength: rangedError.Range.Len,\n\t\t}\n\t\tmessage := rangedError.ToMessage(location)\n\t\tmessage.Severity = int(severity)\n\t\treturn message\n\tdefault:\n\t\treturn loc.DiagnosticMessage{Text: err.Error()}\n\t}\n}\n"
  },
  {
    "path": "internal/hash.go",
    "content": "package astro\n\nimport (\n\t\"encoding/base32\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/internal/xxhash\"\n)\n\nfunc HashString(str string) string {\n\th := xxhash.New()\n\t//nolint\n\th.Write([]byte(str))\n\thashBytes := h.Sum(nil)\n\treturn strings.ToLower(base32.StdEncoding.EncodeToString(hashBytes)[:8])\n}\n"
  },
  {
    "path": "internal/helpers/joiner.go",
    "content": "package helpers\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n)\n\n// This provides an efficient way to join lots of big string and byte slices\n// together. It avoids the cost of repeatedly reallocating as the buffer grows\n// by measuring exactly how big the buffer should be and then allocating once.\n// This is a measurable speedup.\ntype Joiner struct {\n\tlastByte byte\n\tstrings  []joinerString\n\tbytes    []joinerBytes\n\tlength   uint32\n}\n\ntype joinerString struct {\n\tdata   string\n\toffset uint32\n}\n\ntype joinerBytes struct {\n\tdata   []byte\n\toffset uint32\n}\n\nfunc (j *Joiner) AddString(data string) {\n\tif len(data) > 0 {\n\t\tj.lastByte = data[len(data)-1]\n\t}\n\tj.strings = append(j.strings, joinerString{data, j.length})\n\tj.length += uint32(len(data))\n}\n\nfunc (j *Joiner) AddBytes(data []byte) {\n\tif len(data) > 0 {\n\t\tj.lastByte = data[len(data)-1]\n\t}\n\tj.bytes = append(j.bytes, joinerBytes{data, j.length})\n\tj.length += uint32(len(data))\n}\n\nfunc (j *Joiner) LastByte() byte {\n\treturn j.lastByte\n}\n\nfunc (j *Joiner) Length() uint32 {\n\treturn j.length\n}\n\nfunc (j *Joiner) EnsureNewlineAtEnd() {\n\tif j.length > 0 && j.lastByte != '\\n' {\n\t\tj.AddString(\"\\n\")\n\t}\n}\n\nfunc (j *Joiner) Done() []byte {\n\tif len(j.strings) == 0 && len(j.bytes) == 1 && j.bytes[0].offset == 0 {\n\t\t// No need to allocate if there was only a single byte array written\n\t\treturn j.bytes[0].data\n\t}\n\tbuffer := make([]byte, j.length)\n\tfor _, item := range j.strings {\n\t\tcopy(buffer[item.offset:], item.data)\n\t}\n\tfor _, item := range j.bytes {\n\t\tcopy(buffer[item.offset:], item.data)\n\t}\n\treturn buffer\n}\n\nfunc (j *Joiner) Contains(s string, b []byte) bool {\n\tfor _, item := range j.strings {\n\t\tif strings.Contains(item.data, s) {\n\t\t\treturn true\n\t\t}\n\t}\n\tfor _, item := range j.bytes {\n\t\tif bytes.Contains(item.data, b) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "internal/helpers/js_comment_utils.go",
    "content": "package helpers\n\nimport (\n\t\"strings\"\n)\n\nfunc peekIs(input string, cur int, assert byte) bool {\n\treturn cur+1 < len(input) && input[cur+1] == assert\n}\n\n// RemoveComments removes both block and inline comments from a string\nfunc RemoveComments(input string) string {\n\tvar (\n\t\tsb        = strings.Builder{}\n\t\tinComment = false\n\t)\n\tfor cur := 0; cur < len(input); cur++ {\n\t\tif input[cur] == '/' && !inComment {\n\t\t\tif peekIs(input, cur, '*') {\n\t\t\t\tinComment = true\n\t\t\t\tcur++\n\t\t\t} else if peekIs(input, cur, '/') {\n\t\t\t\t// Skip until the end of line for inline comments\n\t\t\t\tfor cur < len(input) && input[cur] != '\\n' {\n\t\t\t\t\tcur++\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t} else if input[cur] == '*' && inComment && peekIs(input, cur, '/') {\n\t\t\tinComment = false\n\t\t\tcur++\n\t\t\tcontinue\n\t\t}\n\n\t\tif !inComment {\n\t\t\tsb.WriteByte(input[cur])\n\t\t}\n\t}\n\n\tif inComment {\n\t\treturn \"\"\n\t}\n\n\treturn strings.TrimSpace(sb.String())\n}\n"
  },
  {
    "path": "internal/js_scanner/js_scanner.go",
    "content": "package js_scanner\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/iancoleman/strcase\"\n\t\"github.com/tdewolff/parse/v2\"\n\t\"github.com/tdewolff/parse/v2/js\"\n\t\"github.com/withastro/compiler/internal/loc\"\n)\n\n// FindTopLevelReturns scans JavaScript/TypeScript source code and returns the\n// byte positions of all `return` statements that are at the top level (i.e., not\n// inside any function, arrow function, method, or class method).\n//\n// This is used to transform top-level returns into throws in TSX output, because\n// top-level returns are valid in Astro frontmatter but cause TypeScript parsing errors.\nfunc FindTopLevelReturns(source []byte) []int {\n\tl := js.NewLexer(parse.NewInputBytes(source))\n\ti := 0\n\treturns := make([]int, 0)\n\n\t// We need to track \"function scope depth\" - returns are only top-level\n\t// if they're not inside any function body.\n\t//\n\t// The challenge is distinguishing between:\n\t// - `if (cond) { return; }` - top-level return (inside if block)\n\t// - `function f() { return; }` - not top-level (inside function)\n\t// - `() => { return; }` - not top-level (inside arrow function)\n\t// - `class C { method() { return; } }` - not top-level (inside class method)\n\t// - `{ method() { return; } }` - not top-level (inside object method)\n\t// - `{ ['computed']() { return; } }` - not top-level (computed method)\n\t//\n\t// Strategy: Track when we're expecting a function body to start.\n\t// A function body starts with `{` after:\n\t// - `function` keyword followed by optional name and `()`\n\t// - `=>` (arrow function)\n\t// - `identifier()` where `{` follows (method shorthand in objects/classes)\n\t// - `[expr]()` where `{` follows (computed method in objects/classes)\n\tfunctionScopeStack := make([]int, 0) // stack of brace depths when entering function scopes\n\tbraceDepth := 0\n\tbracketDepth := 0\n\n\t// Track parentheses depth to detect when we close params\n\tparenDepth := 0\n\tparenDepthAtFunctionStart := -1 // the paren depth when we saw `function` keyword\n\n\t// Track if we're expecting a function body\n\texpectingFunctionBody := false\n\n\t// Track method shorthand: identifier + () + { = method shorthand\n\t// We need to track the paren depth when we see an identifier, so we know\n\t// if the identifier is BEFORE the parens (method shorthand) or INSIDE them (not method)\n\t// E.g., `method() { }` vs `if (condition) { }`\n\tidentParenDepth := -1 // paren depth when we last saw an identifier at current level\n\n\t// Track that we actually went through parens after seeing identifier\n\t// This distinguishes `method() {` from `class Foo {`\n\twentThroughParensForMethod := false\n\n\t// Track computed property: [expr] + () + { = computed method\n\t// After we see `]` that closes a bracket at the same level, we may have a computed method\n\tsawCloseBracketForMethod := false\n\n\tfor {\n\t\ttoken, value := l.Next()\n\n\t\t// Handle regex vs division ambiguity\n\t\tif token == js.DivToken || token == js.DivEqToken {\n\t\t\tif i+1 < len(source) {\n\t\t\t\tlns := bytes.Split(source[i+1:], []byte{'\\n'})\n\t\t\t\tif bytes.Contains(lns[0], []byte{'/'}) {\n\t\t\t\t\ttoken, value = l.RegExp()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif token == js.ErrorToken {\n\t\t\tif l.Err() != io.EOF {\n\t\t\t\treturn returns\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\t// Skip whitespace and comments\n\t\tif token == js.WhitespaceToken || token == js.LineTerminatorToken ||\n\t\t\ttoken == js.CommentToken || token == js.CommentLineTerminatorToken {\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Track identifiers (for method shorthand pattern: identifier + () + {)\n\t\t// Only track if we're not already inside parens from something else\n\t\tif js.IsIdentifier(token) {\n\t\t\tidentParenDepth = parenDepth\n\t\t\twentThroughParensForMethod = false\n\t\t\tsawCloseBracketForMethod = false\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Track parentheses\n\t\tif js.IsPunctuator(token) {\n\t\t\tif value[0] == '(' {\n\t\t\t\tparenDepth++\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t} else if value[0] == ')' {\n\t\t\t\tparenDepth--\n\t\t\t\t// If we close parens back to function start level, we expect function body next\n\t\t\t\tif parenDepthAtFunctionStart >= 0 && parenDepth == parenDepthAtFunctionStart {\n\t\t\t\t\texpectingFunctionBody = true\n\t\t\t\t\tparenDepthAtFunctionStart = -1\n\t\t\t\t}\n\t\t\t\t// Check if we just closed parens back to where we saw an identifier\n\t\t\t\t// This means we went through `identifier()` pattern\n\t\t\t\tif identParenDepth >= 0 && parenDepth == identParenDepth {\n\t\t\t\t\twentThroughParensForMethod = true\n\t\t\t\t}\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Track square brackets for computed properties [expr]\n\t\tif js.IsPunctuator(token) {\n\t\t\tif value[0] == '[' {\n\t\t\t\tbracketDepth++\n\t\t\t\tsawCloseBracketForMethod = false\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t} else if value[0] == ']' {\n\t\t\t\tbracketDepth--\n\t\t\t\t// Mark that we just closed a bracket - this could be a computed property name\n\t\t\t\t// The next thing should be `()` for it to be a method\n\t\t\t\tsawCloseBracketForMethod = true\n\t\t\t\tidentParenDepth = -1\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Detect arrow function: `=>` means we expect a function body\n\t\tif token == js.ArrowToken {\n\t\t\texpectingFunctionBody = true\n\t\t\tidentParenDepth = -1\n\t\t\tsawCloseBracketForMethod = false\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Track function keywords - after `function`, we wait for `(` then `)`\n\t\tif token == js.FunctionToken {\n\t\t\tparenDepthAtFunctionStart = parenDepth\n\t\t\tidentParenDepth = -1\n\t\t\tsawCloseBracketForMethod = false\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Track braces\n\t\tif js.IsPunctuator(token) {\n\t\t\tif value[0] == '{' {\n\t\t\t\t// Check if this brace opens a function body\n\t\t\t\t// This happens after:\n\t\t\t\t// 1. `function name()` or `function()`\n\t\t\t\t// 2. `=>`\n\t\t\t\t// 3. `identifier()` (method shorthand) - identifier followed by () then {\n\t\t\t\t// 4. `[expr]()` (computed method) - sawCloseBracketForMethod was set and we went through ()\n\t\t\t\tisMethodShorthand := wentThroughParensForMethod\n\t\t\t\tisComputedMethod := sawCloseBracketForMethod\n\t\t\t\tif expectingFunctionBody || isMethodShorthand || isComputedMethod {\n\t\t\t\t\t// Entering a function scope\n\t\t\t\t\tfunctionScopeStack = append(functionScopeStack, braceDepth)\n\t\t\t\t\texpectingFunctionBody = false\n\t\t\t\t}\n\t\t\t\tidentParenDepth = -1\n\t\t\t\twentThroughParensForMethod = false\n\t\t\t\tsawCloseBracketForMethod = false\n\t\t\t\tbraceDepth++\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t} else if value[0] == '}' {\n\t\t\t\tbraceDepth--\n\t\t\t\t// Check if we're exiting a function scope\n\t\t\t\tif len(functionScopeStack) > 0 && braceDepth == functionScopeStack[len(functionScopeStack)-1] {\n\t\t\t\t\tfunctionScopeStack = functionScopeStack[:len(functionScopeStack)-1]\n\t\t\t\t}\n\t\t\t\tidentParenDepth = -1\n\t\t\t\twentThroughParensForMethod = false\n\t\t\t\tsawCloseBracketForMethod = false\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\t// Reset identifier tracking on other tokens (but preserve sawCloseBracketForMethod\n\t\t// through parens so `[expr]()` works)\n\t\tidentParenDepth = -1\n\n\t\t// A return is top-level if we're not inside any function scope\n\t\tif token == js.ReturnToken && len(functionScopeStack) == 0 {\n\t\t\treturns = append(returns, i)\n\t\t}\n\n\t\ti += len(value)\n\t}\n\n\treturn returns\n}\n\ntype HoistedScripts struct {\n\tHoisted     [][]byte\n\tHoistedLocs []loc.Loc\n\tBody        [][]byte\n\tBodyLocs    []loc.Loc\n}\n\nfunc HoistExports(source []byte) HoistedScripts {\n\tshouldHoist := bytes.Contains(source, []byte(\"export\"))\n\tif !shouldHoist {\n\t\tbody := make([][]byte, 0)\n\t\tbody = append(body, source)\n\t\tbodyLocs := make([]loc.Loc, 0)\n\t\tbodyLocs = append(bodyLocs, loc.Loc{Start: 0})\n\t\treturn HoistedScripts{\n\t\t\tBody:     body,\n\t\t\tBodyLocs: bodyLocs,\n\t\t}\n\t}\n\n\tl := js.NewLexer(parse.NewInputBytes(source))\n\ti := 0\n\tend := 0\n\n\thoisted := make([][]byte, 0)\n\thoistedLocs := make([]loc.Loc, 0)\n\tbody := make([][]byte, 0)\n\tbodyLocs := make([]loc.Loc, 0)\n\tpairs := make(map[byte]int)\n\n\t// Let's lex the script until we find what we need!\nouter:\n\tfor {\n\t\ttoken, value := l.Next()\n\n\t\tif token == js.DivToken || token == js.DivEqToken {\n\t\t\tlns := bytes.Split(source[i+1:], []byte{'\\n'})\n\t\t\tif bytes.Contains(lns[0], []byte{'/'}) {\n\t\t\t\ttoken, value = l.RegExp()\n\t\t\t}\n\t\t}\n\n\t\tif token == js.ErrorToken {\n\t\t\tif l.Err() != io.EOF {\n\t\t\t\tbody := make([][]byte, 0)\n\t\t\t\tbody = append(body, source)\n\t\t\t\tbodyLocs := make([]loc.Loc, 0)\n\t\t\t\tbodyLocs = append(bodyLocs, loc.Loc{Start: 0})\n\t\t\t\treturn HoistedScripts{\n\t\t\t\t\tHoisted:     hoisted,\n\t\t\t\t\tHoistedLocs: hoistedLocs,\n\t\t\t\t\tBody:        body,\n\t\t\t\t\tBodyLocs:    bodyLocs,\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\t// Common delimiters. Track their length, then skip.\n\t\tif token == js.WhitespaceToken || token == js.LineTerminatorToken || token == js.SemicolonToken {\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Exports should be consumed until all opening braces are closed,\n\t\t// a specifier is found, and a line terminator has been found\n\t\tif token == js.ExportToken {\n\t\t\tflags := make(map[string]bool)\n\t\t\ttokensFound := make(map[string]bool)\n\t\t\tfoundIdent := false\n\t\t\tfoundSemicolonOrLineTerminator := false\n\t\t\tfoundBody := false\n\t\t\tstart := i\n\t\t\ti += len(value)\n\t\t\tfor {\n\t\t\t\tnext, nextValue := l.Next()\n\t\t\t\tif next == js.DivToken || next == js.DivEqToken {\n\t\t\t\t\tlns := bytes.Split(source[i+1:], []byte{'\\n'})\n\t\t\t\t\tif bytes.Contains(lns[0], []byte{'/'}) {\n\t\t\t\t\t\tnext, nextValue = l.RegExp()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti += len(nextValue)\n\t\t\t\tflags[string(nextValue)] = true\n\t\t\t\ttokensFound[string(nextValue)] = true\n\n\t\t\t\tif next == js.ErrorToken && l.Err() == io.EOF {\n\t\t\t\t\tfoundSemicolonOrLineTerminator = true\n\t\t\t\t}\n\n\t\t\t\tif js.IsIdentifier(next) {\n\t\t\t\t\tif isKeyword(nextValue) && next != js.FromToken {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif string(nextValue) == \"type\" {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif !foundIdent {\n\t\t\t\t\t\tfoundIdent = true\n\t\t\t\t\t}\n\t\t\t\t} else if next == js.LineTerminatorToken || next == js.SemicolonToken {\n\t\t\t\t\tif next == js.LineTerminatorToken && i < len(source) && (source[i] == '&' || source[i] == '|') {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif (flags[\"function\"] || flags[\"=>\"] || flags[\"interface\"]) && !foundBody {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif flags[\"&\"] || flags[\"=\"] {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif pairs['('] > 0 {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\n\t\t\t\t\tfoundSemicolonOrLineTerminator = true\n\t\t\t\t} else if js.IsPunctuator(next) {\n\t\t\t\t\tif nextValue[0] == '{' {\n\t\t\t\t\t\tif flags[\"function\"] {\n\t\t\t\t\t\t\t// Curly braces can occur in a function parameter destructuring, which we don't want to consider\n\t\t\t\t\t\t\tfoundBody = foundBody || pairs['('] == 0\n\t\t\t\t\t\t} else if flags[\"=>\"] {\n\t\t\t\t\t\t\t// Arrow can also occur in type definition before arrow function body (which we don't want to consider), but `=` cannot\n\t\t\t\t\t\t\tfoundBody = foundBody || tokensFound[\"=\"]\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfoundBody = true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif nextValue[0] == '{' || nextValue[0] == '(' || nextValue[0] == '[' {\n\t\t\t\t\t\tflags[string(nextValue[0])] = true\n\t\t\t\t\t\tpairs[nextValue[0]]++\n\t\t\t\t\t} else if nextValue[0] == '}' {\n\t\t\t\t\t\tpairs['{']--\n\t\t\t\t\t} else if nextValue[0] == ')' {\n\t\t\t\t\t\tpairs['(']--\n\t\t\t\t\t} else if nextValue[0] == ']' {\n\t\t\t\t\t\tpairs['[']--\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Sometimes, exports are written in multiple lines, like\n\t\t\t\t\t//\n\t\t\t\t\t// export const foo =\n\t\t\t\t\t//   [...]\n\t\t\t\t\t// export type Props = ThisProps &\n\t\t\t\t\t// \t SomeWeirdType<{ thatsSuperLong: SoItEndsUpFormattedLikeThis }>\n\t\t\t\t\t//\n\t\t\t\t\t// So, we omit the semicolon check if the line ends up with one of these\n\t\t\t\t\tif flags[\"&\"] && nextValue[0] != '&' {\n\t\t\t\t\t\tflags[\"&\"] = false\n\t\t\t\t\t}\n\t\t\t\t\tif flags[\"=\"] && nextValue[0] != '=' {\n\t\t\t\t\t\tflags[\"=\"] = false\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif foundIdent && foundSemicolonOrLineTerminator && pairs['{'] == 0 && pairs['('] == 0 && pairs['['] == 0 {\n\t\t\t\t\thoisted = append(hoisted, source[start:i])\n\t\t\t\t\thoistedLocs = append(hoistedLocs, loc.Loc{Start: start})\n\t\t\t\t\tif end < start {\n\t\t\t\t\t\tbody = append(body, source[end:start])\n\t\t\t\t\t\tbodyLocs = append(bodyLocs, loc.Loc{Start: end})\n\t\t\t\t\t}\n\t\t\t\t\tend = i\n\t\t\t\t\tcontinue outer\n\t\t\t\t}\n\n\t\t\t\tif next == js.ErrorToken {\n\t\t\t\t\tif l.Err() != io.EOF {\n\t\t\t\t\t\tbody := make([][]byte, 0)\n\t\t\t\t\t\tbody = append(body, source)\n\t\t\t\t\t\tbodyLocs := make([]loc.Loc, 0)\n\t\t\t\t\t\tbodyLocs = append(bodyLocs, loc.Loc{Start: 0})\n\t\t\t\t\t\treturn HoistedScripts{\n\t\t\t\t\t\t\tHoisted:     hoisted,\n\t\t\t\t\t\t\tHoistedLocs: hoistedLocs,\n\t\t\t\t\t\t\tBody:        body,\n\t\t\t\t\t\t\tBodyLocs:    bodyLocs,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak outer\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Track opening and closing braces\n\t\tif js.IsPunctuator(token) {\n\t\t\tif value[0] == '{' || value[0] == '(' || value[0] == '[' {\n\t\t\t\tpairs[value[0]]++\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t} else if value[0] == '}' {\n\t\t\t\tpairs['{']--\n\t\t\t} else if value[0] == ')' {\n\t\t\t\tpairs['(']--\n\t\t\t} else if value[0] == ']' {\n\t\t\t\tpairs['[']--\n\t\t\t}\n\t\t}\n\n\t\t// Track our current position\n\t\ti += len(value)\n\t}\n\n\tbody = append(body, source[end:])\n\tbodyLocs = append(bodyLocs, loc.Loc{Start: end})\n\n\treturn HoistedScripts{\n\t\tHoisted:     hoisted,\n\t\tHoistedLocs: hoistedLocs,\n\t\tBody:        body,\n\t\tBodyLocs:    bodyLocs,\n\t}\n}\n\nfunc isKeyword(value []byte) bool {\n\treturn js.Keywords[string(value)] != 0\n}\n\n// isPropsAliasing checks if we're in a Props aliasing context (import { Props as X })\n// rather than destructuring with 'as' property ({ as: Component })\nfunc isPropsAliasing(idents []string) bool {\n\treturn len(idents) > 0 && idents[len(idents)-1] == \"Props\"\n}\n\nfunc HoistImports(source []byte) HoistedScripts {\n\timports := make([][]byte, 0)\n\timportLocs := make([]loc.Loc, 0)\n\tbody := make([][]byte, 0)\n\tbodyLocs := make([]loc.Loc, 0)\n\tprev := 0\n\tfor i, statement := NextImportStatement(source, 0); i > -1 && i < len(source)+1; i, statement = NextImportStatement(source, i) {\n\t\tbodyLocs = append(bodyLocs, loc.Loc{Start: prev})\n\t\tbody = append(body, source[prev:statement.Span.Start])\n\t\timports = append(imports, statement.Value)\n\t\timportLocs = append(importLocs, loc.Loc{Start: statement.Span.Start})\n\t\tprev = i\n\t}\n\tif prev == 0 {\n\t\tbodyLocs = append(bodyLocs, loc.Loc{Start: 0})\n\t\tbody = append(body, source)\n\t\treturn HoistedScripts{Body: body, BodyLocs: bodyLocs}\n\t}\n\tbodyLocs = append(bodyLocs, loc.Loc{Start: prev})\n\tbody = append(body, source[prev:])\n\treturn HoistedScripts{Hoisted: imports, HoistedLocs: importLocs, Body: body, BodyLocs: bodyLocs}\n}\n\nfunc HasGetStaticPaths(source []byte) bool {\n\tident := []byte(\"getStaticPaths\")\n\tif !bytes.Contains(source, ident) {\n\t\treturn false\n\t}\n\n\texports := HoistExports(source)\n\tfor _, statement := range exports.Hoisted {\n\t\tif bytes.Contains(statement, ident) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\ntype Props struct {\n\tIdent     string\n\tStatement string\n\tGenerics  string\n}\n\nfunc GetPropsType(source []byte) Props {\n\tdefaultPropType := \"Record<string, any>\"\n\tident := defaultPropType\n\tgenericsIdents := make([]string, 0)\n\tgenerics := \"\"\n\tstatement := \"\"\n\n\tif !bytes.Contains(source, []byte(\"Props\")) {\n\t\treturn Props{\n\t\t\tIdent:     ident,\n\t\t\tStatement: statement,\n\t\t\tGenerics:  generics,\n\t\t}\n\t}\n\tl := js.NewLexer(parse.NewInputBytes(source))\n\ti := 0\n\tpairs := make(map[byte]int)\n\tidents := make([]string, 0)\n\n\tstart := 0\n\tend := 0\n\nouter:\n\tfor {\n\t\ttoken, value := l.Next()\n\n\t\tif token == js.DivToken || token == js.DivEqToken {\n\t\t\tif len(source) > i {\n\t\t\t\tlns := bytes.Split(source[i+1:], []byte{'\\n'})\n\t\t\t\tif bytes.Contains(lns[0], []byte{'/'}) {\n\t\t\t\t\ttoken, value = l.RegExp()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif token == js.ErrorToken {\n\t\t\tif l.Err() != io.EOF {\n\t\t\t\treturn Props{\n\t\t\t\t\tIdent: ident,\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\n\t\t// Common delimiters. Track their length, then skip.\n\t\tif token == js.WhitespaceToken || token == js.LineTerminatorToken || token == js.SemicolonToken {\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\tif token == js.ExtendsToken {\n\t\t\tif bytes.Equal(value, []byte(\"extends\")) {\n\t\t\t\tidents = append(idents, \"extends\")\n\t\t\t}\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\tif pairs['{'] == 0 && pairs['('] == 0 && pairs['['] == 0 && pairs['<'] == 1 && token == js.CommaToken {\n\t\t\tidents = make([]string, 0)\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\tif js.IsIdentifier(token) {\n\t\t\tif isKeyword(value) {\n\t\t\t\t// fix(#814): fix Props detection when using `{ Props as SomethingElse }`\n\t\t\t\t// fix(#927): only reset Props when 'as' follows 'Props' in the same context\n\t\t\t\tif ident == \"Props\" && string(value) == \"as\" && isPropsAliasing(idents) {\n\t\t\t\t\tstart = 0\n\t\t\t\t\tident = defaultPropType\n\t\t\t\t\tidents = make([]string, 0)\n\t\t\t\t}\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif pairs['<'] == 1 && pairs['{'] == 0 {\n\t\t\t\tfoundExtends := false\n\t\t\t\tfor _, id := range idents {\n\t\t\t\t\tif id == \"extends\" {\n\t\t\t\t\t\tfoundExtends = true\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !foundExtends {\n\t\t\t\t\tgenericsIdents = append(genericsIdents, string(value))\n\t\t\t\t}\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Note: do not check that `pairs['{'] == 0` to support named imports\n\t\t\tif pairs['('] == 0 && pairs['['] == 0 && string(value) == \"Props\" {\n\t\t\t\tident = \"Props\"\n\t\t\t}\n\t\t\tidents = append(idents, string(value))\n\t\t\ti += len(value)\n\t\t\tcontinue\n\t\t}\n\n\t\tif bytes.ContainsAny(value, \"<>\") {\n\t\t\tif len(idents) > 0 && idents[len(idents)-1] == \"Props\" {\n\t\t\t\tstart = i\n\t\t\t\tident = \"Props\"\n\t\t\t\tidents = make([]string, 0)\n\t\t\t}\n\t\t\tfor _, c := range value {\n\t\t\t\tif c == '<' {\n\t\t\t\t\tpairs['<']++\n\t\t\t\t\ti += len(value)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif c == '>' {\n\t\t\t\t\tpairs['<']--\n\t\t\t\t\tif pairs['<'] == 0 {\n\t\t\t\t\t\tend = i\n\t\t\t\t\t\t// Important: only break out if we've already found `Props`!\n\t\t\t\t\t\tif ident != defaultPropType {\n\t\t\t\t\t\t\tbreak outer\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif token == js.QuestionToken || (pairs['{'] == 0 && token == js.ColonToken) {\n\t\t\tidents = make([]string, 0)\n\t\t\tidents = append(idents, \"extends\")\n\t\t}\n\n\t\t// Track opening and closing braces\n\t\tif js.IsPunctuator(token) {\n\t\t\tif value[0] == '{' || value[0] == '(' || value[0] == '[' {\n\t\t\t\tidents = make([]string, 0)\n\t\t\t\tpairs[value[0]]++\n\t\t\t\ti += len(value)\n\t\t\t\tcontinue\n\t\t\t} else if value[0] == '}' {\n\t\t\t\tpairs['{']--\n\t\t\t\tif pairs['<'] == 0 && pairs['{'] == 0 && ident != defaultPropType {\n\t\t\t\t\tend = i\n\t\t\t\t\tbreak outer\n\t\t\t\t}\n\t\t\t} else if value[0] == ')' {\n\t\t\t\tpairs['(']--\n\t\t\t} else if value[0] == ']' {\n\t\t\t\tpairs['[']--\n\t\t\t}\n\t\t}\n\n\t\t// Track our current position\n\t\ti += len(value)\n\t}\n\tif start > 0 && len(genericsIdents) > 0 && ident != defaultPropType {\n\t\tgenerics = fmt.Sprintf(\"<%s>\", strings.Join(genericsIdents, \", \"))\n\t\tstatement = strings.TrimSpace(string(source[start:end]))\n\t}\n\n\treturn Props{\n\t\tIdent:     ident,\n\t\tStatement: statement,\n\t\tGenerics:  generics,\n\t}\n}\n\nfunc IsIdentifier(value []byte) bool {\n\tvalid := true\n\tfor i, b := range value {\n\t\tif i == 0 {\n\t\t\tvalid = js.IsIdentifierStart([]byte{b})\n\t\t} else if i < len(value)-1 {\n\t\t\tvalid = js.IsIdentifierContinue([]byte{b})\n\t\t} else {\n\t\t\tvalid = js.IsIdentifierEnd([]byte{b})\n\t\t}\n\t\tif !valid {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn valid\n}\n\nfunc GetObjectKeys(source []byte) [][]byte {\n\tkeys := make([][]byte, 0)\n\tpairs := make(map[byte]int)\n\n\tif source[0] == '{' && source[len(source)-1] == '}' {\n\t\tl := js.NewLexer(parse.NewInputBytes(source[1 : len(source)-1]))\n\t\ti := 0\n\t\tvar prev js.TokenType\n\n\t\tfor {\n\t\t\ttoken, value := l.Next()\n\t\t\topenPairs := pairs['{'] > 0 || pairs['('] > 0 || pairs['['] > 0\n\n\t\t\tif token == js.DivToken || token == js.DivEqToken {\n\t\t\t\tlns := bytes.Split(source[i+1:], []byte{'\\n'})\n\t\t\t\tif bytes.Contains(lns[0], []byte{'/'}) {\n\t\t\t\t\ttoken, value = l.RegExp()\n\t\t\t\t}\n\t\t\t}\n\t\t\ti += len(value)\n\n\t\t\tif token == js.ErrorToken {\n\t\t\t\treturn keys\n\t\t\t}\n\n\t\t\tif js.IsPunctuator(token) {\n\t\t\t\tif value[0] == '{' || value[0] == '(' || value[0] == '[' {\n\t\t\t\t\tpairs[value[0]]++\n\t\t\t\t\tcontinue\n\t\t\t\t} else if value[0] == '}' {\n\t\t\t\t\tpairs['{']--\n\t\t\t\t} else if value[0] == ')' {\n\t\t\t\t\tpairs['(']--\n\t\t\t\t} else if value[0] == ']' {\n\t\t\t\t\tpairs['[']--\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif prev != js.ColonToken {\n\t\t\t\tpush := func() {\n\t\t\t\t\tif token != js.StringToken {\n\t\t\t\t\t\tkeys = append(keys, value)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tkey := value[1 : len(value)-1]\n\t\t\t\t\t\tident := string(key)\n\t\t\t\t\t\tif !IsIdentifier(key) {\n\t\t\t\t\t\t\tident = strcase.ToLowerCamel(string(key))\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif string(key) == ident {\n\t\t\t\t\t\t\tkeys = append(keys, []byte(key))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tkeys = append(keys, []byte(fmt.Sprintf(\"%s: %s\", value, ident)))\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !openPairs && (token == js.IdentifierToken || token == js.StringToken) {\n\t\t\t\t\tpush()\n\t\t\t\t} else if pairs['['] == 1 && token == js.StringToken {\n\t\t\t\t\tpush()\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif !openPairs && token != js.WhitespaceToken {\n\t\t\t\tprev = token\n\t\t\t}\n\t\t}\n\t}\n\n\treturn keys\n}\n\ntype Import struct {\n\tIsType     bool\n\tExportName string\n\tLocalName  string\n\tAssertions string\n}\n\ntype ImportStatement struct {\n\tSpan       loc.Span\n\tValue      []byte\n\tIsType     bool\n\tImports    []Import\n\tSpecifier  string\n\tAssertions string\n}\n\ntype ImportState uint32\n\nconst (\n\tImportDefault ImportState = iota\n\tImportNamed\n)\n\nfunc NextImportStatement(source []byte, pos int) (int, ImportStatement) {\n\tl := js.NewLexer(parse.NewInputBytes(source[pos:]))\n\ti := pos\n\tfor {\n\t\ttoken, value := l.Next()\n\n\t\tif len(source) > i && token == js.DivToken || token == js.DivEqToken {\n\t\t\tlns := bytes.Split(source[i+1:], []byte{'\\n'})\n\t\t\tif bytes.Contains(lns[0], []byte{'/'}) {\n\t\t\t\ttoken, value = l.RegExp()\n\t\t\t}\n\t\t}\n\n\t\tif token == js.ErrorToken {\n\t\t\t// EOF or other error\n\t\t\treturn -1, ImportStatement{}\n\t\t}\n\t\t// Imports should be consumed up until we find a specifier,\n\t\t// then we can exit after the following line terminator or semicolon\n\t\tif token == js.ImportToken {\n\t\t\ti += len(value)\n\t\t\ttext := []byte(value)\n\t\t\tisType := false\n\t\t\tspecifier := \"\"\n\t\t\tassertion := \"\"\n\t\t\tfoundSpecifier := false\n\t\t\tfoundAssertion := false\n\t\t\timports := make([]Import, 0)\n\t\t\timportState := ImportDefault\n\t\t\tcurrImport := Import{}\n\t\t\tpairs := make(map[byte]int)\n\t\t\tfor {\n\t\t\t\tnext, nextValue := l.Next()\n\t\t\t\tif len(source) > i && (next == js.DivToken || next == js.DivEqToken) {\n\t\t\t\t\tlns := bytes.Split(source[i+1:], []byte{'\\n'})\n\t\t\t\t\tif bytes.Contains(lns[0], []byte{'/'}) {\n\t\t\t\t\t\tnext, nextValue = l.RegExp()\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ti += len(nextValue)\n\t\t\t\ttext = append(text, nextValue...)\n\n\t\t\t\tif next == js.ErrorToken {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tif next == js.DotToken {\n\t\t\t\t\tisMeta := false\n\t\t\t\t\tfor {\n\t\t\t\t\t\tnext, _ := l.Next()\n\t\t\t\t\t\tif next == js.MetaToken {\n\t\t\t\t\t\t\tisMeta = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif next != js.WhitespaceToken && next != js.MetaToken {\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif isMeta {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif !foundSpecifier && next == js.StringToken {\n\t\t\t\t\tif len(nextValue) > 1 {\n\t\t\t\t\t\tspecifier = string(nextValue[1 : len(nextValue)-1])\n\t\t\t\t\t\tfoundSpecifier = true\n\t\t\t\t\t}\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif !foundSpecifier && next == js.IdentifierToken && string(nextValue) == \"type\" {\n\t\t\t\t\tisType = true\n\t\t\t\t}\n\n\t\t\t\tif foundSpecifier && (next == js.LineTerminatorToken || next == js.SemicolonToken) && pairs['{'] == 0 && pairs['('] == 0 && pairs['['] == 0 {\n\t\t\t\t\tif currImport.ExportName != \"\" {\n\t\t\t\t\t\tif currImport.LocalName == \"\" {\n\t\t\t\t\t\t\tcurrImport.LocalName = currImport.ExportName\n\t\t\t\t\t\t}\n\t\t\t\t\t\timports = append(imports, currImport)\n\t\t\t\t\t}\n\t\t\t\t\treturn i, ImportStatement{\n\t\t\t\t\t\tSpan:       loc.Span{Start: i - len(text), End: i},\n\t\t\t\t\t\tValue:      text,\n\t\t\t\t\t\tIsType:     isType,\n\t\t\t\t\t\tImports:    imports,\n\t\t\t\t\t\tSpecifier:  specifier,\n\t\t\t\t\t\tAssertions: assertion,\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif next == js.WhitespaceToken {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif foundAssertion {\n\t\t\t\t\tassertion += string(nextValue)\n\t\t\t\t}\n\n\t\t\t\tif !foundAssertion && next == js.StringToken {\n\t\t\t\t\tspecifier = string(nextValue[1 : len(nextValue)-1])\n\t\t\t\t\tfoundSpecifier = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif !foundAssertion && foundSpecifier && next == js.IdentifierToken && string(nextValue) == \"assert\" {\n\t\t\t\t\tfoundAssertion = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tif !foundAssertion && next == js.OpenBraceToken {\n\t\t\t\t\timportState = ImportNamed\n\t\t\t\t}\n\n\t\t\t\tif !foundAssertion && next == js.CommaToken {\n\t\t\t\t\tif currImport.LocalName == \"\" {\n\t\t\t\t\t\tcurrImport.LocalName = currImport.ExportName\n\t\t\t\t\t}\n\t\t\t\t\timports = append(imports, currImport)\n\t\t\t\t\tcurrImport = Import{}\n\t\t\t\t}\n\n\t\t\t\tif !foundAssertion && next == js.IdentifierToken {\n\t\t\t\t\tif currImport.ExportName != \"\" {\n\t\t\t\t\t\tcurrImport.LocalName = string(nextValue)\n\t\t\t\t\t} else if importState == ImportNamed {\n\t\t\t\t\t\tcurrImport.ExportName = string(nextValue)\n\t\t\t\t\t} else if importState == ImportDefault {\n\t\t\t\t\t\tcurrImport.ExportName = \"default\"\n\t\t\t\t\t\tcurrImport.LocalName = string(nextValue)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif !foundAssertion && next == js.MulToken {\n\t\t\t\t\tcurrImport.ExportName = string(nextValue)\n\t\t\t\t}\n\n\t\t\t\tif js.IsPunctuator(next) {\n\t\t\t\t\tif nextValue[0] == '{' || nextValue[0] == '(' || nextValue[0] == '[' {\n\t\t\t\t\t\tpairs[nextValue[0]]++\n\t\t\t\t\t} else if nextValue[0] == '}' {\n\t\t\t\t\t\tpairs['{']--\n\t\t\t\t\t} else if nextValue[0] == ')' {\n\t\t\t\t\t\tpairs['(']--\n\t\t\t\t\t} else if nextValue[0] == ']' {\n\t\t\t\t\t\tpairs['[']--\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// do not hoist dynamic imports\n\t\t\t\tif next == js.OpenParenToken && len(specifier) == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// do not hoist `{ import: \"value\" }`\n\t\t\t\tif next == js.ColonToken && len(specifier) == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// if this is import.meta.*, ignore (watch for first dot)\n\t\t\t\tif next == js.DotToken && len(specifier) == 0 {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ti += len(value)\n\t}\n}\n\n/*\nDetermines the export name of a component, i.e. the object path to which\nwe can access the module, if it were imported using a dynamic import (`import()`)\n\nReturns the export name and a boolean indicating whether\nthe component is imported AND used in the template.\n*/\nfunc ExtractComponentExportName(data string, imported Import) (string, bool) {\n\tnamespacePrefix := fmt.Sprintf(\"%s.\", imported.LocalName)\n\tisNamespacedComponent := strings.Contains(data, \".\") && strings.HasPrefix(data, namespacePrefix)\n\tlocalNameEqualsData := imported.LocalName == data\n\tif isNamespacedComponent || localNameEqualsData {\n\t\tvar exportName string\n\t\tswitch true {\n\t\tcase localNameEqualsData:\n\t\t\texportName = imported.ExportName\n\t\tcase imported.ExportName == \"*\":\n\t\t\t// matched a namespaced import\n\t\t\texportName = strings.Replace(data, namespacePrefix, \"\", 1)\n\t\tcase imported.ExportName == \"default\":\n\t\t\t// matched a default import\n\t\t\texportName = strings.Replace(data, imported.LocalName, \"default\", 1)\n\t\tdefault:\n\t\t\t// matched a named import\n\t\t\texportName = data\n\t\t}\n\t\treturn exportName, true\n\t}\n\treturn \"\", false\n}\n"
  },
  {
    "path": "internal/js_scanner/js_scanner_test.go",
    "content": "package js_scanner\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\t\"unicode/utf8\"\n\n\t\"github.com/withastro/compiler/internal/test_utils\"\n)\n\ntype testcase struct {\n\tname   string\n\tsource string\n\twant   string\n\tonly   bool\n}\n\n// Test cases for FindTopLevelReturns\nfunc TestFindTopLevelReturns(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   []int\n\t\tonly   bool\n\t}{\n\t\t{\n\t\t\tname:   \"basic top-level return\",\n\t\t\tsource: `return \"value\";`,\n\t\t\twant:   []int{0},\n\t\t},\n\t\t{\n\t\t\tname: \"return inside function declaration\",\n\t\t\tsource: `function foo() {\nreturn \"value\";\n}`,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"return inside arrow function\",\n\t\t\tsource: `const foo = () => {\nreturn \"value\";\n}`,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"return inside class method\",\n\t\t\tsource: `class Component {\n\trender() {\n\t\treturn \"wow\"!\n\t}\n}`,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"return inside exported async function\",\n\t\t\tsource: `export async function getStaticPaths({ paginate }: { paginate: PaginateFunction }) {\n\tconst { data: products }: { data: IProduct[] } = await getEntry(\"products\", \"products\");\n\n\treturn paginate(products, {\n\t\tpageSize: 10,\n\t});\n}`,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"mixed: function with return, then top-level return\",\n\t\t\tsource: `const foo = () => {\nreturn \"value\";\n}\n\nif (true) {\nreturn \"value\";\n\t\t}\n`,\n\t\t\twant: []int{51},\n\t\t},\n\t\t{\n\t\t\tname: \"multiple top-level returns\",\n\t\t\tsource: `const foo = () => {\nreturn \"value\";\n}\n\nif (true) {\nreturn \"value\";\n\t\t}\nif (true) {\nreturn \"value\";\n\t\t}\n`,\n\t\t\twant: []int{51, 83},\n\t\t},\n\t\t{\n\t\t\tname: \"return inside object method shorthand\",\n\t\t\tsource: `const something = {\n\tsomeFunction: () => {\n\t\treturn \"Hello World\";\n\t},\n\tsomeOtherFunction() {\n\t\treturn \"Hello World\";\n\t},\n};`,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"return inside arrow function with satisfies\",\n\t\t\tsource: `export const getStaticPaths = (({ paginate }) => {\n\tconst data = [0, 1, 2];\n\treturn paginate(data, {\n\t\tpageSize: 10,\n\t});\n}) satisfies GetStaticPaths;`,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"top-level return with Astro.redirect\",\n\t\t\tsource: `if (something) {\n\treturn Astro.redirect();\n}`,\n\t\t\twant: []int{18},\n\t\t},\n\t\t{\n\t\t\tname: \"no returns at all\",\n\t\t\tsource: `const foo = \"bar\";\nconsole.log(foo);`,\n\t\t\twant: nil,\n\t\t},\n\t\t{\n\t\t\tname: \"computed method in class with generic arrow\",\n\t\t\tsource: `class Foo {\n\t['get']() {\n\t\treturn 'ok';\n\t}\n}\nconst generic = <T,>(value: T) => { return value; };\nif (true) { return Astro.redirect('/test'); }`,\n\t\t\twant: []int{110},\n\t\t},\n\t\t{\n\t\t\tname: \"computed method in object\",\n\t\t\tsource: `const obj = { ['get']() { return 'obj'; } };\nif (true) { return Astro.redirect(); }`,\n\t\t\twant: []int{57},\n\t\t},\n\t\t{\n\t\t\tname: \"generic arrow function\",\n\t\t\tsource: `const generic = <T,>(value: T) => { return value; };\nif (true) { return Astro.redirect(); }`,\n\t\t\twant: []int{65},\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tif tt.only {\n\t\t\ttests = []struct {\n\t\t\t\tname   string\n\t\t\t\tsource string\n\t\t\t\twant   []int\n\t\t\t\tonly   bool\n\t\t\t}{tt}\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot := FindTopLevelReturns([]byte(tt.source))\n\t\t\tif diff := test_utils.ANSIDiff(fmt.Sprint(tt.want), fmt.Sprint(got)); diff != \"\" {\n\t\t\t\tt.Errorf(\"mismatch (-want +got):\\n%s\", diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc fixturesHoistImport() []testcase {\n\treturn []testcase{\n\t\t{\n\t\t\tname:   \"basic\",\n\t\t\tsource: `const value = \"test\"`,\n\t\t\twant:   ``,\n\t\t},\n\t\t{\n\t\t\tname: \"import\",\n\t\t\tsource: `import { fn } from \"package\";\nconst b = await fetch();`,\n\t\t\twant: `import { fn } from \"package\";\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"dynamic\",\n\t\t\tsource: `const markdownDocs = await Astro.glob('../markdown/*.md')\nconst article2 = await import('../markdown/article2.md')\n`,\n\t\t\twant: \"\",\n\t\t},\n\t\t{\n\t\t\tname: \"big import\",\n\t\t\tsource: `import {\na,\nb,\nc,\nd,\n} from \"package\"\n\nconst b = await fetch();`,\n\t\t\twant: `import {\na,\nb,\nc,\nd,\n} from \"package\"\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"import with comment\",\n\t\t\tsource: `// comment\nimport { fn } from \"package\";\nconst b = await fetch();`,\n\t\t\twant: `import { fn } from \"package\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"import assertion\",\n\t\t\tsource: `// comment\nimport { fn } from \"package\" assert { it: 'works' };\nconst b = await fetch();`,\n\t\t\twant: `import { fn } from \"package\" assert { it: 'works' };`,\n\t\t},\n\t\t{\n\t\t\tname: \"import assertion 2\",\n\t\t\tsource: `// comment\nimport {\nfn\n} from\n\"package\" assert {\nit: 'works'\n};\nconst b = await fetch();`,\n\t\t\twant: `import {\nfn\n} from\n\"package\" assert {\nit: 'works'\n};\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"import.meta.env\",\n\t\t\tsource: `console.log(import.meta.env.FOO);\nimport Test from \"../components/Test.astro\";`,\n\t\t\twant: `import Test from \"../components/Test.astro\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"import.meta.env II\",\n\t\t\tsource: `console.log(\nimport\n\t.meta\n\t.env\n\t.FOO\n);\nimport Test from \"../components/Test.astro\";`,\n\t\t\twant: `import Test from \"../components/Test.astro\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"import/export\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async fn() {}\nconst b = await fetch()`,\n\t\t\twant: `import { fn } from \"package\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths() {\nconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `import { fn } from \"package\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with comments\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths() {\nconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `import { fn } from \"package\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with semicolon\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths() {\nconst content = Astro.fetchContent('**/*.md');\n}; const b = await fetch()`,\n\t\t\twant: `import { fn } from \"package\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with RegExp escape\",\n\t\t\tsource: `export async function getStaticPaths() {\nconst pattern = /\\.md$/g.test('value');\n}\nimport a from \"a\";`,\n\t\t\twant: `import a from \"a\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with divider\",\n\t\t\tsource: `export async function getStaticPaths() {\nconst pattern = a / b;\n}`,\n\t\t\twant: ``,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with divider and following content\",\n\t\t\tsource: `export async function getStaticPaths() {\nconst value = 1 / 2;\n}\n// comment\nimport { b } from \"b\";\nconst { a } = Astro.props;`,\n\t\t\twant: `import { b } from \"b\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with regex and following content\",\n\t\t\tsource: `export async function getStaticPaths() {\nconst value = /2/g;\n}\n// comment\nimport { b } from \"b\";\nconst { a } = Astro.props;`,\n\t\t\twant: `import { b } from \"b\";`,\n\t\t},\n\t\t{\n\t\t\tname: \"multiple imports\",\n\t\t\tsource: `import { a } from \"a\";\nimport { b } from \"b\";\n// comment\nimport { c } from \"c\";\nconst d = await fetch()\n\n// comment\nimport { d } from \"d\";`,\n\t\t\twant: `import { a } from \"a\";\nimport { b } from \"b\";\nimport { c } from \"c\";\nimport { d } from \"d\";\n`,\n\t\t},\n\t\t{\n\t\t\tname:   \"assignment\",\n\t\t\tsource: `let show = true;`,\n\t\t\twant:   ``,\n\t\t},\n\t\t{\n\t\t\tname: \"RegExp is not a comment\",\n\t\t\tsource: `import { a } from \"a\";\n/import \\{ b \\} from \"b\";/;\nimport { c } from \"c\";`,\n\t\t\twant: `import { a } from \"a\";\nimport { c } from \"c\";\n`,\n\t\t},\n\t}\n}\n\nfunc TestHoistImport(t *testing.T) {\n\ttests := fixturesHoistImport()\n\tfor _, tt := range tests {\n\t\tif tt.only {\n\t\t\ttests = make([]testcase, 0)\n\t\t\ttests = append(tests, tt)\n\t\t\tbreak\n\t\t}\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tresult := HoistImports([]byte(tt.source))\n\t\t\tgot := []byte{}\n\t\t\tfor _, imp := range result.Hoisted {\n\t\t\t\tgot = append(got, bytes.TrimSpace(imp)...)\n\t\t\t\tgot = append(got, '\\n')\n\t\t\t}\n\t\t\t// compare to expected string, show diff if mismatch\n\t\t\tif diff := test_utils.ANSIDiff(strings.TrimSpace(tt.want), strings.TrimSpace(string(got))); diff != \"\" {\n\t\t\t\tt.Errorf(\"mismatch (-want +got):\\n%s\", diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc FuzzHoistImport(f *testing.F) {\n\ttests := fixturesHoistImport()\n\tfor _, tt := range tests {\n\t\tf.Add(tt.source) // Use f.Add to provide a seed corpus\n\t}\n\tf.Fuzz(func(t *testing.T, source string) {\n\t\tresult := HoistImports([]byte(source))\n\t\tgot := []byte{}\n\t\tfor _, imp := range result.Hoisted {\n\t\t\tgot = append(got, bytes.TrimSpace(imp)...)\n\t\t\tgot = append(got, '\\n')\n\t\t}\n\t\tif utf8.ValidString(source) && !utf8.ValidString(string(got)) {\n\t\t\tt.Errorf(\"Import hoisting produced an invalid string: %q\", got)\n\t\t}\n\t})\n}\n\nfunc TestHoistExport(t *testing.T) {\n\ttests := []testcase{\n\t\t{\n\t\t\tname: \"getStaticPaths\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths() {\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export async function getStaticPaths() {\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and destructured props\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths({ paginate })\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export async function getStaticPaths({ paginate })\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and param definition type in curly braces\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths(input: { paginate: any })\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export async function getStaticPaths(input: { paginate: any })\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and param definition type in square braces\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths([{ stuff }])\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export async function getStaticPaths([{ stuff }])\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and type specified with square braces 1\",\n\t\t\tsource: `import { fn } from \"package\";\nexport const getStaticPaths: () => { params: any }[]\n= () =>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export const getStaticPaths: () => { params: any }[]\n= () =>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and type specified with square braces 2\",\n\t\t\tsource: `import { fn } from \"package\";\nexport const getStaticPaths: () => { params: any }[] =\n() =>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export const getStaticPaths: () => { params: any }[] =\n() =>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and type specified with square braces 3\",\n\t\t\tsource: `import { fn } from \"package\";\nexport const getStaticPaths: () => { params: any }[] = ()\n=>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export const getStaticPaths: () => { params: any }[] = ()\n=>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and type specified with square braces 4\",\n\t\t\tsource: `import { fn } from \"package\";\nexport const getStaticPaths: () => { params: any }[] = () =>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export const getStaticPaths: () => { params: any }[] = () =>\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with curly brace on next line and definition specified by anonymous function with destructured parameter\",\n\t\t\tsource: `import { fn } from \"package\";\nexport const getStaticPaths = function({ paginate })\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export const getStaticPaths = function({ paginate })\n{\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with comments\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths() {\n  // This works!\n  const content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export async function getStaticPaths() {\n  // This works!\n  const content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with semicolon\",\n\t\t\tsource: `import { fn } from \"package\";\nexport async function getStaticPaths() {\n  const content = Astro.fetchContent('**/*.md');\n}; const b = await fetch()`,\n\t\t\twant: `export async function getStaticPaths() {\n  const content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with RegExp escape\",\n\t\t\tsource: `// cool\nexport async function getStaticPaths() {\n  const pattern = /\\.md$/g.test('value');\n}\nimport a from \"a\";`,\n\t\t\twant: `export async function getStaticPaths() {\n  const pattern = /\\.md$/g.test('value');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with divider\",\n\t\t\tsource: `export async function getStaticPaths() {\n  const pattern = a / b;\n}`,\n\t\t\twant: `export async function getStaticPaths() {\n  const pattern = a / b;\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with divider and following content\",\n\t\t\tsource: `export async function getStaticPaths() {\n  const value = 1 / 2;\n}\n// comment\nimport { b } from \"b\";\nconst { a } = Astro.props;`,\n\t\t\twant: `export async function getStaticPaths() {\n  const value = 1 / 2;\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with regex and following content\",\n\t\t\tsource: `// comment\nexport async function getStaticPaths() {\n  const value = /2/g;\n}\nimport { b } from \"b\";\nconst { a } = Astro.props;`,\n\t\t\twant: `export async function getStaticPaths() {\n  const value = /2/g;\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths with TypeScript type\",\n\t\t\tsource: `import { fn } from \"package\";\n\nexport async function getStaticPaths({\n\tpaginate\n}: {\n\tpaginate: any\n}) {\n\tconst content = Astro.fetchContent('**/*.md');\n}\nconst b = await fetch()`,\n\t\t\twant: `export async function getStaticPaths({\n\tpaginate\n}: {\n\tpaginate: any\n}) {\n\tconst content = Astro.fetchContent('**/*.md');\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"export interface\",\n\t\t\tsource: `import { a } from \"a\";\nexport interface Props {\n\topen?: boolean;\n}`,\n\t\t\twant: `export interface Props {\n\topen?: boolean;\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"export multiple\",\n\t\t\tsource: `import { a } from \"a\";\nexport interface Props {\n\topen?: boolean;\n}\nexport const foo = \"bar\"`,\n\t\t\twant: `export interface Props {\n\topen?: boolean;\n}\nexport const foo = \"bar\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"export multiple with content after\",\n\t\t\tsource: `import { a } from \"a\";\nexport interface Props {\n\topen?: boolean;\n}\nexport const baz = \"bing\"\n// beep boop`,\n\t\t\twant: `export interface Props {\n\topen?: boolean;\n}\nexport const baz = \"bing\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"export three\",\n\t\t\tsource: `import { a } from \"a\";\nexport interface Props {}\nexport const a = \"b\"\nexport const c = \"d\"`,\n\t\t\twant: `export interface Props {}\nexport const a = \"b\"\nexport const c = \"d\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"export with comments\",\n\t\t\tsource: `import { a } from \"a\";\n// comment\nexport interface Props {}\nexport const a = \"b\"\nexport const c = \"d\"`,\n\t\t\twant: `export interface Props {}\nexport const a = \"b\"\nexport const c = \"d\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"export local reference (runtime error)\",\n\t\t\tsource: `import { a } from \"a\";\nexport interface Props {}\nconst value = await fetch(\"something\")\nexport const data = { value }\n`,\n\t\t\twant: `export interface Props {}\nexport const data = { value }`,\n\t\t},\n\t\t{\n\t\t\tname: \"export passthrough\",\n\t\t\tsource: `export * from \"./local-data.json\";\nexport { default as A } from \"./_types\"\nexport B from \"./_types\"\nexport type C from \"./_types\"`,\n\t\t\twant: `export * from \"./local-data.json\";\nexport { default as A } from \"./_types\"\nexport B from \"./_types\"\nexport type C from \"./_types\"`,\n\t\t},\n\t\t{\n\t\t\tname: \"multi-line export\",\n\t\t\tsource: `export interface Props\n{\n\tfoo: 'bar';\n}`,\n\t\t\twant: `export interface Props\n{\n\tfoo: 'bar';\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"multi-line type export\",\n\t\t\tsource: `export type Props =\n{\n\tfoo: 'bar';\n}`,\n\t\t\twant: `export type Props =\n{\n\tfoo: 'bar';\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"multi-line type export with multiple exports\",\n\t\t\tsource: `export type Theme = 'light' | 'dark';\n\nexport type Props =\n{\n\ttheme: Theme;\n};\n\nexport interface Foo {\n\tbar: string;\n}\n\nexport type FooAndBar1 = 'Foo' &\n'Bar';\nexport type FooAndBar2 = 'Foo'\n& 'Bar';\nexport type FooOrBar = 'Foo'\n| 'Bar';`,\n\t\t\twant: `export type Theme = 'light' | 'dark';\nexport type Props =\n{\n\ttheme: Theme;\n}\nexport interface Foo {\n\tbar: string;\n}\nexport type FooAndBar1 = 'Foo' &\n'Bar';\nexport type FooAndBar2 = 'Foo'\n& 'Bar';\nexport type FooOrBar = 'Foo'\n| 'Bar';`,\n\t\t},\n\t\t{\n\t\t\tname: \"Picture\",\n\t\t\tsource: `// @ts-ignore\nimport loader from 'virtual:image-loader';\nimport { getPicture } from '../src/get-picture.js';\nimport type { ImageAttributes, ImageMetadata, OutputFormat, PictureAttributes, TransformOptions } from '../src/types.js';\nexport interface LocalImageProps extends Omit<PictureAttributes, 'src' | 'width' | 'height'>, Omit<TransformOptions, 'src'>, Omit<ImageAttributes, 'src' | 'width' | 'height'> {\n\tsrc: ImageMetadata | Promise<{ default: ImageMetadata }>;\n\tsizes: HTMLImageElement['sizes'];\n\twidths: number[];\n\tformats?: OutputFormat[];\n}\nexport interface RemoteImageProps extends Omit<PictureAttributes, 'src' | 'width' | 'height'>, TransformOptions, Omit<ImageAttributes, 'src' | 'width' | 'height'> {\n\tsrc: string;\n\tsizes: HTMLImageElement['sizes'];\n\twidths: number[];\n\taspectRatio: TransformOptions['aspectRatio'];\n\tformats?: OutputFormat[];\n}\nexport type Props = LocalImageProps | RemoteImageProps;\nconst { src, sizes, widths, aspectRatio, formats = ['avif', 'webp'], loading = 'lazy', decoding = 'async', ...attrs } = Astro.props as Props;\nconst { image, sources } = await getPicture({ loader, src, widths, formats, aspectRatio });\n`,\n\t\t\twant: `export interface LocalImageProps extends Omit<PictureAttributes, 'src' | 'width' | 'height'>, Omit<TransformOptions, 'src'>, Omit<ImageAttributes, 'src' | 'width' | 'height'> {\n\tsrc: ImageMetadata | Promise<{ default: ImageMetadata }>;\n\tsizes: HTMLImageElement['sizes'];\n\twidths: number[];\n\tformats?: OutputFormat[];\n}\nexport interface RemoteImageProps extends Omit<PictureAttributes, 'src' | 'width' | 'height'>, TransformOptions, Omit<ImageAttributes, 'src' | 'width' | 'height'> {\n\tsrc: string;\n\tsizes: HTMLImageElement['sizes'];\n\twidths: number[];\n\taspectRatio: TransformOptions['aspectRatio'];\n\tformats?: OutputFormat[];\n}\nexport type Props = LocalImageProps | RemoteImageProps;`,\n\t\t},\n\t\t{\n\t\t\tname: \"Image\",\n\t\t\tsource: `// @ts-ignore\nimport loader from 'virtual:image-loader';\nimport { getImage } from '../src/index.js';\nimport type { ImageAttributes, ImageMetadata, TransformOptions, OutputFormat } from '../src/types.js';\nconst { loading = \"lazy\", decoding = \"async\", ...props } = Astro.props as Props;\nconst attrs = await getImage(loader, props);\n\n// Moved after Astro.props for test\nexport interface LocalImageProps extends Omit<TransformOptions, 'src'>, Omit<ImageAttributes, 'src' | 'width' | 'height'> {\n\tsrc: ImageMetadata | Promise<{ default: ImageMetadata }>;\n}\nexport interface RemoteImageProps extends TransformOptions, ImageAttributes {\n\tsrc: string;\n\tformat: OutputFormat;\n\twidth: number;\n\theight: number;\n}\nexport type Props = LocalImageProps | RemoteImageProps;\n`,\n\t\t\twant: `export interface LocalImageProps extends Omit<TransformOptions, 'src'>, Omit<ImageAttributes, 'src' | 'width' | 'height'> {\n\tsrc: ImageMetadata | Promise<{ default: ImageMetadata }>;\n}\nexport interface RemoteImageProps extends TransformOptions, ImageAttributes {\n\tsrc: string;\n\tformat: OutputFormat;\n\twidth: number;\n\theight: number;\n}\nexport type Props = LocalImageProps | RemoteImageProps;`,\n\t\t},\n\t\t{\n\t\t\tname: \"comments\",\n\t\t\tsource: `//\nexport const foo = 0\n/*\n*/`,\n\t\t\twant: `export const foo = 0`,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tif tt.only {\n\t\t\ttests = make([]testcase, 0)\n\t\t\ttests = append(tests, tt)\n\t\t\tbreak\n\t\t}\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tresult := HoistExports([]byte(tt.source))\n\t\t\tgot := []byte{}\n\t\t\tfor _, imp := range result.Hoisted {\n\t\t\t\tgot = append(got, bytes.TrimSpace(imp)...)\n\t\t\t\tgot = append(got, '\\n')\n\t\t\t}\n\t\t\t// compare to expected string, show diff if mismatch\n\t\t\tif diff := test_utils.ANSIDiff(strings.TrimSpace(tt.want), strings.TrimSpace(string(got))); diff != \"\" {\n\t\t\t\tt.Errorf(\"mismatch (-want +got):\\n%s\", diff)\n\t\t\t}\n\t\t})\n\t}\n}\n\ntype keytestcase struct {\n\tname   string\n\tsource string\n\twant   []string\n\tonly   bool\n}\n\nfunc TestGetObjectKeys(t *testing.T) {\n\ttests := []keytestcase{\n\t\t{\n\t\t\tname:   \"basic\",\n\t\t\tsource: `{ value }`,\n\t\t\twant:   []string{\"value\"},\n\t\t},\n\t\t{\n\t\t\tname:   \"shorhand\",\n\t\t\tsource: `{ value, foo, bar, baz, bing }`,\n\t\t\twant:   []string{\"value\", \"foo\", \"bar\", \"baz\", \"bing\"},\n\t\t},\n\t\t{\n\t\t\tname:   \"literal\",\n\t\t\tsource: `{ value: 0 }`,\n\t\t\twant:   []string{\"value\"},\n\t\t},\n\t\t{\n\t\t\tname:   \"multiple\",\n\t\t\tsource: `{ a: 0, b: 1, c: 2  }`,\n\t\t\twant:   []string{\"a\", \"b\", \"c\"},\n\t\t},\n\t\t{\n\t\t\tname:   \"objects\",\n\t\t\tsource: `{ a: { a1: 0 }, b: { b1: { b2: 0 }}, c: { c1: { c2: { c3: 0 }}}  }`,\n\t\t\twant:   []string{\"a\", \"b\", \"c\"},\n\t\t},\n\t\t{\n\t\t\tname:   \"regexp\",\n\t\t\tsource: `{ a: /hello/g, b: 0 }`,\n\t\t\twant:   []string{\"a\", \"b\"},\n\t\t},\n\t\t{\n\t\t\tname:   \"array\",\n\t\t\tsource: `{ a: [0, 1, 2], b: [\"one\", \"two\", \"three\"], c: 0 }`,\n\t\t\twant:   []string{\"a\", \"b\", \"c\"},\n\t\t},\n\t\t{\n\t\t\tname:   \"valid strings\",\n\t\t\tsource: `{ \"lowercase\": true, \"camelCase\": true, \"PascalCase\": true, \"snake_case\": true, \"__private\": true, [\"computed\"]: true, }`,\n\t\t\t// Note that quotes are dropped\n\t\t\twant: []string{`lowercase`, `camelCase`, `PascalCase`, `snake_case`, `__private`, `computed`},\n\t\t},\n\t\t{\n\t\t\tname:   \"invalid strings\",\n\t\t\tsource: `{ \"dash-case\": true, \"with.dot\": true, \"with space\": true }`,\n\t\t\twant:   []string{`\"dash-case\": dashCase`, `\"with.dot\": withDot`, `\"with space\": withSpace`},\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tif tt.only {\n\t\t\ttests = make([]keytestcase, 0)\n\t\t\ttests = append(tests, tt)\n\t\t\tbreak\n\t\t}\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tkeys := GetObjectKeys([]byte(tt.source))\n\t\t\toutput := make([]string, 0)\n\t\t\tfor _, key := range keys {\n\t\t\t\toutput = append(output, string(key))\n\t\t\t}\n\t\t\tgot, _ := json.Marshal(output)\n\t\t\twant, _ := json.Marshal(tt.want)\n\t\t\t// compare to expected string, show diff if mismatch\n\t\t\tif diff := test_utils.ANSIDiff(string(want), string(got)); diff != \"\" {\n\t\t\t\tt.Errorf(\"mismatch (-want +got):\\n%s\", diff)\n\t\t\t}\n\n\t\t})\n\t}\n}\n\n// propsTestCase represents a test case for GetPropsType\ntype propsTestCase struct {\n\tname   string\n\tsource string\n\twant   Props\n}\n\n// makeProps is a helper to create Props structs concisely\nfunc makeProps(ident string, statement string, generics string) Props {\n\treturn Props{\n\t\tIdent:     ident,\n\t\tStatement: statement,\n\t\tGenerics:  generics,\n\t}\n}\n\n// getPropsTypeTestCases returns all test cases for GetPropsType\nfunc getPropsTypeTestCases() []propsTestCase {\n\tconst defaultType = \"Record<string, any>\"\n\n\treturn []propsTestCase{\n\t\t// Basic cases\n\t\t{\n\t\t\tname:   \"no props\",\n\t\t\tsource: `const foo = \"bar\"`,\n\t\t\twant:   makeProps(defaultType, \"\", \"\"),\n\t\t},\n\t\t{\n\t\t\tname: \"interface Props\",\n\t\t\tsource: `interface Props {\n\t\t\t\tfoo: string;\n\t\t\t}`,\n\t\t\twant: makeProps(\"Props\", \"\", \"\"),\n\t\t},\n\t\t{\n\t\t\tname: \"type Props\",\n\t\t\tsource: `type Props = {\n\t\t\t\tfoo: string;\n\t\t\t}`,\n\t\t\twant: makeProps(\"Props\", \"\", \"\"),\n\t\t},\n\n\t\t// Generics\n\t\t{\n\t\t\tname: \"Props with generics\",\n\t\t\tsource: `interface Props<T> {\n\t\t\t\tfoo: T;\n\t\t\t}`,\n\t\t\twant: makeProps(\"Props\", \"<T>\", \"<T>\"),\n\t\t},\n\n\t\t// Issue #927: 'as' prop name handling\n\t\t{\n\t\t\tname: \"destructuring with 'as' prop name without type assertion - issue #927\",\n\t\t\tsource: `interface Props {\n\t\t\t\tas?: string;\n\t\t\t\thref?: string;\n\t\t\t}\n\t\t\tconst { as: Component, href } = Astro.props;`,\n\t\t\twant: makeProps(\"Props\", \"\", \"\"),\n\t\t},\n\t\t{\n\t\t\tname: \"destructuring with 'as' prop name with type assertion\",\n\t\t\tsource: `interface Props {\n\t\t\t\tas?: string;\n\t\t\t\thref?: string;\n\t\t\t}\n\t\t\tconst { as: Component, href } = Astro.props as Props;`,\n\t\t\twant: makeProps(\"Props\", \"\", \"\"),\n\t\t},\n\t}\n}\n\n// checks if two Props are equal and reports errors\nfunc assertPropsEqual(t *testing.T, got, want Props, source string) {\n\tt.Helper()\n\n\tif got.Ident != want.Ident {\n\t\tt.Errorf(\"Ident mismatch:\\n  got:  %q\\n  want: %q\", got.Ident, want.Ident)\n\t\tt.Logf(\"Source:\\n%s\", source)\n\t}\n\tif got.Statement != want.Statement {\n\t\tt.Errorf(\"Statement mismatch:\\n  got:  %q\\n  want: %q\", got.Statement, want.Statement)\n\t}\n\tif got.Generics != want.Generics {\n\t\tt.Errorf(\"Generics mismatch:\\n  got:  %q\\n  want: %q\", got.Generics, want.Generics)\n\t}\n}\n\nfunc TestGetPropsType(t *testing.T) {\n\ttests := getPropsTypeTestCases()\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tgot := GetPropsType([]byte(tt.source))\n\t\t\tassertPropsEqual(t, got, tt.want, tt.source)\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/js_scanner/testdata/fuzz/FuzzHoistImport/ec55358ab2929fbf4deab52587664e42682f0a6ea201a325c5c33f9d18c50456",
    "content": "go test fuzz v1\nstring(\"import\\\"\\nimport \\\"\\\";\")\n"
  },
  {
    "path": "internal/loc/diagnostics.go",
    "content": "package loc\n\ntype DiagnosticCode int\n\nconst (\n\tERROR                             DiagnosticCode = 1000\n\tERROR_UNTERMINATED_JS_COMMENT     DiagnosticCode = 1001\n\tERROR_FRAGMENT_SHORTHAND_ATTRS    DiagnosticCode = 1002\n\tERROR_UNMATCHED_IMPORT            DiagnosticCode = 1003\n\tERROR_UNSUPPORTED_SLOT_ATTRIBUTE  DiagnosticCode = 1004\n\tERROR_UNTERMINATED_STRING         DiagnosticCode = 1005\n\tERROR_MISSING_FRONTMATTER_FENCE   DiagnosticCode = 1006\n\tWARNING                           DiagnosticCode = 2000\n\tWARNING_UNTERMINATED_HTML_COMMENT DiagnosticCode = 2001\n\tWARNING_UNCLOSED_HTML_TAG         DiagnosticCode = 2002\n\tWARNING_DEPRECATED_DIRECTIVE      DiagnosticCode = 2003\n\tWARNING_IGNORED_DIRECTIVE         DiagnosticCode = 2004\n\tWARNING_UNSUPPORTED_EXPRESSION    DiagnosticCode = 2005\n\tWARNING_SET_WITH_CHILDREN         DiagnosticCode = 2006\n\tWARNING_CANNOT_DEFINE_VARS        DiagnosticCode = 2007\n\tWARNING_INVALID_SPREAD            DiagnosticCode = 2008\n\tWARNING_UNEXPECTED_CHARACTER      DiagnosticCode = 2009\n\tWARNING_CANNOT_RERUN              DiagnosticCode = 2010\n\tINFO                              DiagnosticCode = 3000\n\tHINT                              DiagnosticCode = 4000\n)\n"
  },
  {
    "path": "internal/loc/loc.go",
    "content": "package loc\n\ntype Loc struct {\n\t// This is the 0-based index of this location from the start of the file, in bytes\n\tStart int\n}\n\ntype Range struct {\n\tLoc Loc\n\tLen int\n}\n\nfunc (r Range) End() int {\n\treturn r.Loc.Start + r.Len\n}\n\n// span is a range of bytes in a Tokenizer's buffer. The start is inclusive,\n// the end is exclusive.\ntype Span struct {\n\tStart, End int\n}\n\ntype TSXRange struct {\n\tStart int `js:\"start\"`\n\tEnd   int `js:\"end\"`\n}\n\n// A NodeType is the type of a Node.\ntype DiagnosticSeverity int\n\nconst (\n\tErrorType       DiagnosticSeverity = 1\n\tWarningType     DiagnosticSeverity = 2\n\tInformationType DiagnosticSeverity = 3\n\tHintType        DiagnosticSeverity = 4\n)\n\ntype DiagnosticMessage struct {\n\tSeverity int                 `js:\"severity\"`\n\tCode     int                 `js:\"code\"`\n\tLocation *DiagnosticLocation `js:\"location\"`\n\tHint     string              `js:\"hint\"`\n\tText     string              `js:\"text\"`\n}\n\ntype DiagnosticLocation struct {\n\tFile   string `js:\"file\"`\n\tLine   int    `js:\"line\"`\n\tColumn int    `js:\"column\"`\n\tLength int    `js:\"length\"`\n}\n\ntype ErrorWithRange struct {\n\tCode  DiagnosticCode\n\tText  string\n\tHint  string\n\tRange Range\n}\n\nfunc (e *ErrorWithRange) Error() string {\n\treturn e.Text\n}\n\nfunc (e *ErrorWithRange) ToMessage(location *DiagnosticLocation) DiagnosticMessage {\n\treturn DiagnosticMessage{\n\t\tCode:     int(e.Code),\n\t\tText:     e.Error(),\n\t\tHint:     e.Hint,\n\t\tLocation: location,\n\t}\n}\n"
  },
  {
    "path": "internal/node.go",
    "content": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\nimport (\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"golang.org/x/net/html/atom\"\n)\n\n// A NodeType is the type of a Node.\ntype NodeType uint32\n\nconst (\n\tErrorNode NodeType = iota\n\tTextNode\n\tDocumentNode\n\tElementNode\n\tCommentNode\n\tDoctypeNode\n\t// RawNode nodes are not returned by the parser, but can be part of the\n\t// Node tree passed to func Render to insert raw HTML (without escaping).\n\t// If so, this package makes no guarantee that the rendered HTML is secure\n\t// (from e.g. Cross Site Scripting attacks) or well-formed.\n\tRawNode\n\tscopeMarkerNode\n\t// Extensions\n\tFrontmatterNode\n\tExpressionNode\n\tRenderHeadNode\n)\n\nfunc (t NodeType) String() string {\n\tswitch t {\n\tcase ErrorNode:\n\t\treturn \"error\"\n\tcase TextNode:\n\t\treturn \"text\"\n\tcase DocumentNode:\n\t\treturn \"root\"\n\tcase ElementNode:\n\t\treturn \"element\"\n\tcase CommentNode:\n\t\treturn \"comment\"\n\tcase DoctypeNode:\n\t\treturn \"doctype\"\n\tcase FrontmatterNode:\n\t\treturn \"frontmatter\"\n\tcase ExpressionNode:\n\t\treturn \"expression\"\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n\n// Used as an Attribute Key to mark implicit nodes\nconst ImplicitNodeMarker = \"\\x00implicit\"\n\n// Section 12.2.4.3 says \"The markers are inserted when entering applet,\n// object, marquee, template, td, th, and caption elements, and are used\n// to prevent formatting from \"leaking\" into applet, object, marquee,\n// template, td, th, and caption elements\".\nvar scopeMarker = Node{Type: scopeMarkerNode}\n\ntype HydratedComponentMetadata struct {\n\tExportName   string\n\tLocalName    string\n\tSpecifier    string\n\tResolvedPath string\n}\n\n// A Node consists of a NodeType and some Data (tag name for element nodes,\n// content for text) and are part of a tree of Nodes. Element nodes may also\n// have a Namespace and contain a slice of Attributes. Data is unescaped, so\n// that it looks like \"a<b\" rather than \"a&lt;b\". For element nodes, DataAtom\n// is the atom for Data, or zero if Data is not a known tag name.\n//\n// An empty Namespace implies a \"http://www.w3.org/1999/xhtml\" namespace.\n// Similarly, \"math\" is short for \"http://www.w3.org/1998/Math/MathML\", and\n// \"svg\" is short for \"http://www.w3.org/2000/svg\".\ntype Node struct {\n\tFragment        bool\n\tCustomElement   bool\n\tComponent       bool\n\tExpression      bool\n\tTransition      bool\n\tTransitionScope string\n\t// Whether this node is a script that should be rendered with the `renderScript` runtime,\n\t// so that the runtime handles how this is bundled and referenced.\n\tHandledScript bool\n\n\tParent, FirstChild, LastChild, PrevSibling, NextSibling *Node\n\n\t// These are only accessible from the document root Node\n\tStyles, Scripts          []*Node\n\tHydratedComponentNodes   []*Node\n\tHydratedComponents       []*HydratedComponentMetadata\n\tClientOnlyComponentNodes []*Node\n\tClientOnlyComponents     []*HydratedComponentMetadata\n\tHydrationDirectives      map[string]bool\n\tServerComponents         []*HydratedComponentMetadata\n\tContainsHead             bool\n\tHeadPropagation          bool\n\n\tType      NodeType\n\tDataAtom  atom.Atom\n\tData      string\n\tNamespace string\n\tAttr      []Attribute\n\tLoc       []loc.Loc\n}\n\n// InsertBefore inserts newChild as a child of n, immediately before oldChild\n// in the sequence of n's children. oldChild may be nil, in which case newChild\n// is appended to the end of n's children.\n//\n// It will panic if newChild already has a parent or siblings.\nfunc (n *Node) InsertBefore(newChild, oldChild *Node) {\n\tif newChild.Parent != nil || newChild.PrevSibling != nil || newChild.NextSibling != nil {\n\t\tpanic(\"html: InsertBefore called for an attached child Node\")\n\t}\n\tvar prev, next *Node\n\tif oldChild != nil {\n\t\tprev, next = oldChild.PrevSibling, oldChild\n\t} else {\n\t\tprev = n.LastChild\n\t}\n\tif prev != nil {\n\t\tprev.NextSibling = newChild\n\t} else {\n\t\tn.FirstChild = newChild\n\t}\n\tif next != nil {\n\t\tnext.PrevSibling = newChild\n\t} else {\n\t\tn.LastChild = newChild\n\t}\n\tnewChild.Parent = n\n\tnewChild.PrevSibling = prev\n\tnewChild.NextSibling = next\n}\n\n// AppendChild adds a node c as a child of n.\n//\n// It will panic if c already has a parent or siblings.\nfunc (n *Node) AppendChild(c *Node) {\n\tif c.Parent != nil || c.PrevSibling != nil || c.NextSibling != nil {\n\t\tpanic(\"html: AppendChild called for an attached child Node\")\n\t}\n\tlast := n.LastChild\n\tif last != nil {\n\t\tlast.NextSibling = c\n\t} else {\n\t\tn.FirstChild = c\n\t}\n\tn.LastChild = c\n\tc.Parent = n\n\tc.PrevSibling = last\n}\n\n// RemoveChild removes a node c that is a child of n. Afterwards, c will have\n// no parent and no siblings.\n//\n// It will panic if c's parent is not n.\nfunc (n *Node) RemoveChild(c *Node) {\n\tif c.Parent != n {\n\t\tpanic(\"html: RemoveChild called for a non-child Node\")\n\t}\n\tif n.FirstChild == c {\n\t\tn.FirstChild = c.NextSibling\n\t}\n\tif c.NextSibling != nil {\n\t\tc.NextSibling.PrevSibling = c.PrevSibling\n\t}\n\tif n.LastChild == c {\n\t\tn.LastChild = c.PrevSibling\n\t}\n\tif c.PrevSibling != nil {\n\t\tc.PrevSibling.NextSibling = c.NextSibling\n\t}\n\tc.Parent = nil\n\tc.PrevSibling = nil\n\tc.NextSibling = nil\n}\n\nfunc (n *Node) Closest(check func(*Node) bool) *Node {\n\tp := n\n\tfor {\n\t\tif check(p) {\n\t\t\treturn p\n\t\t}\n\t\tp = p.Parent\n\t\tif p == nil {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc GetAttribute(n *Node, key string) *Attribute {\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == key {\n\t\t\treturn &attr\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (n *Node) RemoveAttribute(key string) {\n\tfor i, attr := range n.Attr {\n\t\tif attr.Key == key {\n\t\t\tn.Attr = append(n.Attr[:i], n.Attr[i+1:]...)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// reparentChildren reparents all of src's child nodes to dst.\nfunc reparentChildren(dst, src *Node) {\n\tfor {\n\t\tchild := src.FirstChild\n\t\tif child == nil {\n\t\t\tbreak\n\t\t}\n\t\tsrc.RemoveChild(child)\n\t\tdst.AppendChild(child)\n\t}\n}\n\n// clone returns a new node with the same type, data and attributes.\n// The clone has no parent, no siblings and no children.\nfunc (n *Node) clone() *Node {\n\tm := &Node{\n\t\tType:          n.Type,\n\t\tDataAtom:      n.DataAtom,\n\t\tData:          n.Data,\n\t\tAttr:          make([]Attribute, len(n.Attr)),\n\t\tCustomElement: n.CustomElement,\n\t\tComponent:     n.Component,\n\t\tHandledScript: n.HandledScript,\n\t\tLoc:           n.Loc,\n\t}\n\tcopy(m.Attr, n.Attr)\n\treturn m\n}\n\n// nodeStack is a stack of nodes.\ntype nodeStack []*Node\n\n// pop pops the stack. It will panic if s is empty.\nfunc (s *nodeStack) pop() *Node {\n\ti := len(*s)\n\tif i > 0 {\n\t\tn := (*s)[i-1]\n\t\t*s = (*s)[:i-1]\n\t\treturn n\n\t}\n\treturn nil\n}\n\n// top returns the most recently pushed node, or nil if s is empty.\nfunc (s *nodeStack) top() *Node {\n\tif i := len(*s); i > 0 {\n\t\treturn (*s)[i-1]\n\t}\n\treturn nil\n}\n\n// index returns the index of the top-most occurrence of n in the stack, or -1\n// if n is not present.\nfunc (s *nodeStack) index(n *Node) int {\n\tfor i := len(*s) - 1; i >= 0; i-- {\n\t\tif (*s)[i] == n {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\n// contains returns whether a is within s.\nfunc (s *nodeStack) contains(a atom.Atom) bool {\n\tfor _, n := range *s {\n\t\tif n.DataAtom == a && n.Namespace == \"\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// insert inserts a node at the given index.\nfunc (s *nodeStack) insert(i int, n *Node) {\n\t(*s) = append(*s, nil)\n\tcopy((*s)[i+1:], (*s)[i:])\n\t(*s)[i] = n\n}\n\n// remove removes a node from the stack. It is a no-op if n is not present.\nfunc (s *nodeStack) remove(n *Node) {\n\ti := s.index(n)\n\tif i == -1 {\n\t\treturn\n\t}\n\tcopy((*s)[i:], (*s)[i+1:])\n\tj := len(*s) - 1\n\t(*s)[j] = nil\n\t*s = (*s)[:j]\n}\n\ntype insertionModeStack []insertionMode\n\nfunc (s *insertionModeStack) pop() (im insertionMode) {\n\ti := len(*s)\n\tim = (*s)[i-1]\n\t*s = (*s)[:i-1]\n\treturn im\n}\n\nfunc (s *insertionModeStack) top() insertionMode {\n\tif i := len(*s); i > 0 {\n\t\treturn (*s)[i-1]\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "internal/parser.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\ta \"golang.org/x/net/html/atom\"\n)\n\n// A parser implements the HTML5 parsing algorithm:\n// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction\ntype parser struct {\n\t// tokenizer provides the tokens for the parser.\n\ttokenizer *Tokenizer\n\t// tok is the most recently read token.\n\ttok  Token\n\tltok Token\n\t// Self-closing tags like <hr/> are treated as start tags, except that\n\t// hasSelfClosingToken is set while they are being processed.\n\thasSelfClosingToken bool\n\t// flag to signal that frontmatter has been added\n\t// if we don't have frontmatter and we enter a tag, we add empty frontmatter\n\tfrontmatterState FrontmatterState\n\t// doc is the document root element.\n\tdoc *Node\n\t// fm is the document's frontmatter node\n\tfm *Node\n\t// The stack of open elements (section 12.2.4.2) and active formatting\n\t// elements (section 12.2.4.3).\n\toe, afe nodeStack\n\t// Element pointers (section 12.2.4.4).\n\thead, form *Node\n\t// Other parsing state flags (section 12.2.4.5).\n\tscripting, framesetOK bool\n\t// The stack of template insertion modes\n\ttemplateStack insertionModeStack\n\t// im is the current insertion mode.\n\tim insertionMode\n\t// originalIM is the insertion mode to go back to after completing a text\n\t// or inTableText insertion mode.\n\toriginalIM    insertionMode\n\texitLiteralIM func() bool\n\t// fosterParenting is whether new elements should be inserted according to\n\t// the foster parenting rules (section 12.2.6.1).\n\tfosterParenting bool\n\t// quirks is whether the parser is operating in \"quirks mode.\"\n\tquirks bool\n\t// fragment is whether the parser is parsing an HTML fragment.\n\tfragment bool\n\t// literal is whether the parser should handle exceptions literally.\n\tliteral bool\n\t// context is the context element when parsing an HTML fragment\n\t// (section 12.4).\n\tcontext *Node\n\thandler *handler.Handler\n}\n\nfunc (p *parser) top() *Node {\n\tif n := p.oe.top(); n != nil {\n\t\treturn n\n\t}\n\treturn p.doc\n}\n\n// Stop tags for use in popUntil. These come from section 12.2.4.2.\nvar (\n\tdefaultScopeStopTags = map[string][]a.Atom{\n\t\t\"\":     {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template},\n\t\t\"math\": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},\n\t\t\"svg\":  {a.Desc, a.ForeignObject, a.Title},\n\t}\n)\n\ntype scope int\n\nconst (\n\tdefaultScope scope = iota\n\tlistItemScope\n\tbuttonScope\n\ttableScope\n\ttableRowScope\n\ttableBodyScope\n\tselectScope\n)\n\n// popUntil pops the stack of open elements at the highest element whose tag\n// is in matchTags, provided there is no higher element in the scope's stop\n// tags (as defined in section 12.2.4.2). It returns whether or not there was\n// such an element. If there was not, popUntil leaves the stack unchanged.\n//\n// For example, the set of stop tags for table scope is: \"html\", \"table\". If\n// the stack was:\n// [\"html\", \"body\", \"font\", \"table\", \"b\", \"i\", \"u\"]\n// then popUntil(tableScope, \"font\") would return false, but\n// popUntil(tableScope, \"i\") would return true and the stack would become:\n// [\"html\", \"body\", \"font\", \"table\", \"b\"]\n//\n// If an element's tag is in both the stop tags and matchTags, then the stack\n// will be popped and the function returns true (provided, of course, there was\n// no higher element in the stack that was also in the stop tags). For example,\n// popUntil(tableScope, \"table\") returns true and leaves:\n// [\"html\", \"body\", \"font\"]\nfunc (p *parser) popUntil(s scope, matchTags ...a.Atom) bool {\n\tif i := p.indexOfElementInScope(s, matchTags...); i != -1 {\n\t\tp.oe = p.oe[:i]\n\t\treturn true\n\t}\n\treturn false\n}\n\n// indexOfElementInScope returns the index in p.oe of the highest element whose\n// tag is in matchTags that is in scope. If no matching element is in scope, it\n// returns -1.\nfunc (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\ttagAtom := p.oe[i].DataAtom\n\t\tif p.oe[i].Namespace == \"\" {\n\t\t\tfor _, t := range matchTags {\n\t\t\t\tif t == tagAtom {\n\t\t\t\t\treturn i\n\t\t\t\t}\n\t\t\t}\n\t\t\tswitch s {\n\t\t\tcase defaultScope:\n\t\t\t\t// No-op.\n\t\t\tcase listItemScope:\n\t\t\t\tif tagAtom == a.Ol || tagAtom == a.Ul {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tcase buttonScope:\n\t\t\t\tif tagAtom == a.Button {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tcase tableScope:\n\t\t\t\tif tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tcase selectScope:\n\t\t\t\tif tagAtom != a.Optgroup && tagAtom != a.Option {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\tpanic(\"unreachable\")\n\t\t\t}\n\t\t}\n\t\tswitch s {\n\t\tcase defaultScope, listItemScope, buttonScope:\n\t\t\tfor _, t := range defaultScopeStopTags[p.oe[i].Namespace] {\n\t\t\t\tif t == tagAtom {\n\t\t\t\t\treturn -1\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn -1\n}\n\n// elementInScope is like popUntil, except that it doesn't modify the stack of\n// open elements.\nfunc (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool {\n\treturn p.indexOfElementInScope(s, matchTags...) != -1\n}\n\n// clearStackToContext pops elements off the stack of open elements until a\n// scope-defined element is found.\nfunc (p *parser) clearStackToContext(s scope) {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\ttagAtom := p.oe[i].DataAtom\n\t\tswitch s {\n\t\tcase tableScope:\n\t\t\tif tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\treturn\n\t\t\t}\n\t\tcase tableRowScope:\n\t\t\tif tagAtom == a.Html || tagAtom == a.Tr || tagAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\treturn\n\t\t\t}\n\t\tcase tableBodyScope:\n\t\t\tif tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead || tagAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\treturn\n\t\t\t}\n\t\tdefault:\n\t\t\tpanic(\"unreachable\")\n\t\t}\n\t}\n}\n\n// parseGenericRawTextElements implements the generic raw text element parsing\n// algorithm defined in 12.2.6.2.\n// https://html.spec.whatwg.org/multipage/parsing.html#parsing-elements-that-contain-only-text\n// TODO: Since both RAWTEXT and RCDATA states are treated as tokenizer's part\n// officially, need to make tokenizer consider both states.\nfunc (p *parser) parseGenericRawTextElement() {\n\tp.addElement()\n\tp.originalIM = p.im\n\tp.im = textIM\n}\n\nfunc (p *parser) generateLoc() []loc.Loc {\n\tlocs := make([]loc.Loc, 0, 2)\n\tlocs = append(locs, p.tok.Loc)\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tlocs = append(locs, loc.Loc{Start: p.tok.Loc.Start + len(p.tok.Data)})\n\tcase CommentToken:\n\t\tlocs = append(locs, loc.Loc{Start: p.tok.Loc.Start + len(p.tok.Data) + 3})\n\t}\n\treturn locs\n}\n\nfunc (p *parser) addLoc() {\n\tn := p.oe.top()\n\tif n != nil {\n\t\tn.Loc = append(n.Loc, p.tok.Loc)\n\t}\n}\n\n// generateImpliedEndTags pops nodes off the stack of open elements as long as\n// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc.\n// If exceptions are specified, nodes with that name will not be popped off.\nfunc (p *parser) generateImpliedEndTags(exceptions ...string) {\n\tvar i int\nloop:\n\tfor i = len(p.oe) - 1; i >= 0; i-- {\n\t\tn := p.oe[i]\n\t\tif n.Type != ElementNode {\n\t\t\tbreak\n\t\t}\n\t\tswitch n.DataAtom {\n\t\tcase a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc:\n\t\t\tfor _, except := range exceptions {\n\t\t\t\tif n.Data == except {\n\t\t\t\t\tbreak loop\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tbreak\n\t}\n\n\tp.oe = p.oe[:i+1]\n}\n\n// addChild adds a child node n to the top element, and pushes n onto the stack\n// of open elements if it is an element node.\nfunc (p *parser) addChild(n *Node) {\n\tif p.shouldFosterParent() {\n\t\tp.fosterParent(n)\n\t} else {\n\t\tp.top().AppendChild(n)\n\t}\n\n\tif n.Type == ElementNode {\n\t\tp.oe = append(p.oe, n)\n\t}\n}\n\n// shouldFosterParent returns whether the next node to be added should be\n// foster parented.\nfunc (p *parser) shouldFosterParent() bool {\n\tif p.fosterParenting {\n\t\tswitch p.top().DataAtom {\n\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// fosterParent adds a child node according to the foster parenting rules.\n// Section 12.2.6.1, \"foster parenting\".\nfunc (p *parser) fosterParent(n *Node) {\n\tvar table, parent, prev, template *Node\n\tvar i int\n\tfor i = len(p.oe) - 1; i >= 0; i-- {\n\t\tif p.oe[i].DataAtom == a.Table {\n\t\t\ttable = p.oe[i]\n\t\t\tbreak\n\t\t}\n\t}\n\n\tvar j int\n\tfor j = len(p.oe) - 1; j >= 0; j-- {\n\t\tif p.oe[j].DataAtom == a.Template {\n\t\t\ttemplate = p.oe[j]\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif template != nil && (table == nil || j > i) {\n\t\ttemplate.AppendChild(n)\n\t\treturn\n\t}\n\n\tif table == nil {\n\t\t// The foster parent is the html element.\n\t\tparent = p.oe[0]\n\t} else {\n\t\tparent = table.Parent\n\t}\n\tif parent == nil {\n\t\tparent = p.oe[i-1]\n\t}\n\n\tif table != nil {\n\t\tprev = table.PrevSibling\n\t} else {\n\t\tprev = parent.LastChild\n\t}\n\tif prev != nil && prev.Type == TextNode && n.Type == TextNode {\n\t\tprev.Data += n.Data\n\t\treturn\n\t}\n\n\tparent.InsertBefore(n, table)\n}\n\n// addText adds text to the preceding node if it is a text node, or else it\n// calls addChild with a new text node.\nfunc (p *parser) addText(text string) {\n\tif text == \"\" {\n\t\treturn\n\t}\n\n\tif p.shouldFosterParent() {\n\t\tp.fosterParent(&Node{\n\t\t\tType: TextNode,\n\t\t\tData: text,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn\n\t}\n\n\tt := p.top()\n\tif n := t.LastChild; n != nil && n.Type == TextNode {\n\t\tn.Data += text\n\t\treturn\n\t}\n\tp.addChild(&Node{\n\t\tType: TextNode,\n\t\tData: text,\n\t\tLoc:  p.generateLoc(),\n\t})\n}\n\nfunc (p *parser) addFrontmatter(empty bool) {\n\tif p.frontmatterState == FrontmatterInitial {\n\t\tif p.doc.FirstChild != nil {\n\t\t\tp.fm = &Node{\n\t\t\t\tType: FrontmatterNode,\n\t\t\t\tLoc:  p.generateLoc(),\n\t\t\t}\n\t\t\tp.doc.InsertBefore(p.fm, p.doc.FirstChild)\n\t\t} else {\n\t\t\tp.fm = &Node{\n\t\t\t\tType: FrontmatterNode,\n\t\t\t\tLoc:  p.generateLoc(),\n\t\t\t}\n\t\t\tp.doc.AppendChild(p.fm)\n\t\t}\n\t\tif empty {\n\t\t\tp.frontmatterState = FrontmatterClosed\n\t\t\tp.fm.Attr = append(p.fm.Attr, Attribute{Key: ImplicitNodeMarker, Type: EmptyAttribute})\n\t\t} else {\n\t\t\tp.frontmatterState = FrontmatterOpen\n\t\t\tp.oe = append(p.oe, p.fm)\n\t\t}\n\t}\n}\n\n// addExpression adds a child expression based on the current token.\nfunc (p *parser) addExpression() {\n\tp.addChild(&Node{\n\t\tType:          ElementNode,\n\t\tDataAtom:      a.Template,\n\t\tData:          \"astro:expression\",\n\t\tAttr:          make([]Attribute, 0),\n\t\tExpression:    true,\n\t\tComponent:     false,\n\t\tCustomElement: false,\n\t\tHandledScript: false,\n\t\tLoc:           p.generateLoc(),\n\t\tNamespace:     p.top().Namespace,\n\t})\n\n}\n\nfunc isFragment(data string) bool {\n\treturn len(data) == 0 || data == \"Fragment\"\n}\n\nfunc isSlot(data string) bool {\n\treturn data == \"slot\"\n}\n\nfunc isComponent(data string) bool {\n\tif strings.Contains(data, \".\") {\n\t\treturn true\n\t}\n\treturn !isFragment(data) && data[0] >= 'A' && data[0] <= 'Z'\n}\n\nfunc isCustomElement(data string) bool {\n\treturn strings.Contains(data, \"-\")\n}\n\nfunc (p *parser) isInsideHead() bool {\n\tn := p.oe.top()\n\tfor n != nil {\n\t\tif n.DataAtom == a.Head {\n\t\t\treturn true\n\t\t}\n\t\tn = n.Parent\n\t}\n\treturn false\n}\n\n// addElement adds a child element based on the current token.\nfunc (p *parser) addElement() {\n\tp.addChild(&Node{\n\t\tType:          ElementNode,\n\t\tDataAtom:      p.tok.DataAtom,\n\t\tData:          p.tok.Data,\n\t\tAttr:          p.tok.Attr,\n\t\tFragment:      isFragment(p.tok.Data),\n\t\tComponent:     isComponent(p.tok.Data),\n\t\tCustomElement: isCustomElement(p.tok.Data),\n\t\tHandledScript: false,\n\t\tLoc:           p.generateLoc(),\n\t})\n}\n\n// Section 12.2.4.3.\nfunc (p *parser) addFormattingElement() {\n\ttagAtom, attr := p.tok.DataAtom, p.tok.Attr\n\tp.addElement()\n\n\t// Implement the Noah's Ark clause, but with three per family instead of two.\n\tidenticalElements := 0\nfindIdenticalElements:\n\tfor i := len(p.afe) - 1; i >= 0; i-- {\n\t\tn := p.afe[i]\n\t\tif n.Type == scopeMarkerNode {\n\t\t\tbreak\n\t\t}\n\t\tif n.Type != ElementNode {\n\t\t\tcontinue\n\t\t}\n\t\tif n.Namespace != \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tif n.DataAtom != tagAtom {\n\t\t\tcontinue\n\t\t}\n\t\tif len(n.Attr) != len(attr) {\n\t\t\tcontinue\n\t\t}\n\tcompareAttributes:\n\t\tfor _, t0 := range n.Attr {\n\t\t\tfor _, t1 := range attr {\n\t\t\t\tif t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val {\n\t\t\t\t\t// Found a match for this attribute, continue with the next attribute.\n\t\t\t\t\tcontinue compareAttributes\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If we get here, there is no attribute that matches a.\n\t\t\t// Therefore the element is not identical to the new one.\n\t\t\tcontinue findIdenticalElements\n\t\t}\n\n\t\tidenticalElements++\n\t\tif identicalElements >= 3 {\n\t\t\tp.afe.remove(n)\n\t\t}\n\t}\n\n\tp.afe = append(p.afe, p.top())\n}\n\n// Section 12.2.4.3.\nfunc (p *parser) clearActiveFormattingElements() {\n\tfor {\n\t\tif n := p.afe.pop(); len(p.afe) == 0 || n.Type == scopeMarkerNode {\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// Section 12.2.4.3.\nfunc (p *parser) reconstructActiveFormattingElements() {\n\tn := p.afe.top()\n\tif n == nil {\n\t\treturn\n\t}\n\tif n.Type == scopeMarkerNode || p.oe.index(n) != -1 {\n\t\treturn\n\t}\n\ti := len(p.afe) - 1\n\tfor n.Type != scopeMarkerNode && p.oe.index(n) == -1 {\n\t\tif i == 0 {\n\t\t\ti = -1\n\t\t\tbreak\n\t\t}\n\t\ti--\n\t\tn = p.afe[i]\n\t}\n\tfor {\n\t\ti++\n\t\tclone := p.afe[i].clone()\n\t\tp.addChild(clone)\n\t\tp.afe[i] = clone\n\t\tif i == len(p.afe)-1 {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Section 12.2.5.\nfunc (p *parser) acknowledgeSelfClosingTag() {\n\tp.hasSelfClosingToken = false\n}\n\n// An insertion mode (section 12.2.4.1) is the state transition function from\n// a particular state in the HTML5 parser's state machine. It updates the\n// parser's fields depending on parser.tok (where ErrorToken means EOF).\n// It returns whether the token was consumed.\ntype insertionMode func(*parser) bool\n\n// setOriginalIM sets the insertion mode to return to after completing a text or\n// inTableText insertion mode.\n// Section 12.2.4.1, \"using the rules for\".\nfunc (p *parser) setOriginalIM() {\n\tif p.originalIM != nil {\n\t\tpanic(\"html: bad parser state: originalIM was set twice\")\n\t}\n\tp.originalIM = p.im\n}\n\n// Section 12.2.4.1, \"reset the insertion mode\".\nfunc (p *parser) resetInsertionMode() {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\tn := p.oe[i]\n\t\tlast := i == 0\n\t\tif last && p.context != nil {\n\t\t\tn = p.context\n\t\t}\n\n\t\tswitch n.DataAtom {\n\t\tcase a.Select:\n\t\t\tif !last {\n\t\t\t\tfor ancestor, first := n, p.oe[0]; ancestor != first; {\n\t\t\t\t\tancestor = p.oe[p.oe.index(ancestor)-1]\n\t\t\t\t\tswitch ancestor.DataAtom {\n\t\t\t\t\tcase a.Template:\n\t\t\t\t\t\tp.im = inSelectIM\n\t\t\t\t\t\treturn\n\t\t\t\t\tcase a.Table:\n\t\t\t\t\t\tp.im = inSelectInTableIM\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.im = inSelectIM\n\t\tcase a.Td, a.Th:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\t\tp.im = inCellIM\n\t\tcase a.Tr:\n\t\t\tp.im = inRowIM\n\t\tcase a.Tbody, a.Thead, a.Tfoot:\n\t\t\tp.im = inTableBodyIM\n\t\tcase a.Caption:\n\t\t\tp.im = inCaptionIM\n\t\tcase a.Colgroup:\n\t\t\tp.im = inColumnGroupIM\n\t\tcase a.Table:\n\t\t\tp.im = inTableIM\n\t\tcase a.Template:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\tif n.Namespace != \"\" {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tp.im = p.templateStack.top()\n\t\tcase a.Head:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\t\tp.im = inHeadIM\n\t\tcase a.Body:\n\t\t\tp.im = inBodyIM\n\t\tcase a.Frameset:\n\t\t\tp.im = inFramesetIM\n\t\tcase a.Html:\n\t\t\tif p.head == nil {\n\t\t\t\tp.im = beforeHeadIM\n\t\t\t} else {\n\t\t\t\tp.im = afterHeadIM\n\t\t\t}\n\t\tdefault:\n\t\t\tif last {\n\t\t\t\tp.im = inBodyIM\n\t\t\t\treturn\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\treturn\n\t}\n}\n\nconst whitespace = \" \\t\\r\\n\\f\"\n\n// Section 12.2.6.4.1.\nfunc initialIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase FrontmatterFenceToken:\n\t\tp.setOriginalIM()\n\t\tp.im = frontmatterIM\n\t\treturn false\n\tcase TextToken:\n\t\tp.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(p.tok.Data) == 0 {\n\t\t\t// It was all whitespace, so ignore it.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\tn, quirks := parseDoctype(p.tok.Data)\n\t\tp.doc.AppendChild(n)\n\t\tp.quirks = quirks\n\t\tp.im = beforeHTMLIM\n\t\treturn true\n\t}\n\tif p.frontmatterState == FrontmatterInitial {\n\t\tp.addFrontmatter(true)\n\t}\n\tp.quirks = true\n\tp.im = beforeHTMLIM\n\treturn false\n}\n\n// Section 12.2.6.4.2.\nfunc beforeHTMLIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase TextToken:\n\t\tp.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(p.tok.Data) == 0 {\n\t\t\t// It was all whitespace, so ignore it.\n\t\t\treturn true\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\tp.addElement()\n\t\t\tp.im = beforeHeadIM\n\t\t\treturn true\n\t\tcase a.Script:\n\t\t\tp.addElement()\n\t\t\tif p.originalIM == nil {\n\t\t\t\tp.setOriginalIM()\n\t\t\t}\n\t\t\tp.im = textIM\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.addLoc()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t\tif isComponent(p.tok.Data) {\n\t\t\tp.addElement()\n\t\t\tp.im = inBodyIM\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\t\tif p.literal {\n\t\t\tp.im = inLiteralIM\n\t\t\tp.originalIM = beforeHTMLIM\n\t\t\treturn false\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Script:\n\t\t\tp.oe.pop()\n\t\t\treturn true\n\t\tcase a.Head, a.Body, a.Html, a.Br:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Html, a.Html.String())\n\t\t\treturn false\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\t}\n\tp.parseImpliedToken(StartTagToken, a.Html, a.Html.String())\n\treturn false\n}\n\n// Section 12.2.6.4.3.\nfunc beforeHeadIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tp.addText(p.tok.Data)\n\t\treturn true\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.addLoc()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Head:\n\t\t\tp.addElement()\n\t\t\tp.head = p.top()\n\t\t\tp.im = inHeadIM\n\t\t\treturn true\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Head, a.Body, a.Html, a.Br:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Head, a.Head.String())\n\t\t\treturn false\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase StartExpressionToken:\n\t\tp.parseImpliedToken(StartTagToken, a.Head, a.Head.String())\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.setOriginalIM()\n\t\tp.im = inExpressionIM\n\t\treturn true\n\t}\n\tp.parseImpliedToken(StartTagToken, a.Head, a.Head.String())\n\treturn false\n}\n\n// Section 12.2.6.4.4.\nfunc inHeadIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) < len(p.tok.Data) {\n\t\t\t// Add the initial whitespace to the current node.\n\t\t\tp.addText(p.tok.Data[:len(p.tok.Data)-len(s)])\n\t\t\tif s == \"\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.tok.Data = s\n\t\t\treturn textIM(p)\n\t\t} else if p.oe.top() != nil && (isComponent(p.oe.top().Data) || isFragment((p.oe.top().Data))) {\n\t\t\tp.addText(p.tok.Data)\n\t\t\treturn true\n\t\t}\n\tcase StartTagToken:\n\t\t// Allow components in Head\n\t\tif isComponent(p.tok.Data) || isFragment(p.tok.Data) {\n\t\t\tp.im = inLiteralIM\n\t\t\tp.originalIM = inHeadIM\n\t\t\tp.exitLiteralIM = getExitLiteralFunc(p)\n\t\t\treturn false\n\t\t}\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\treturn true\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.addLoc()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Noscript:\n\t\t\tp.addElement()\n\t\t\tp.im = inHeadNoscriptIM\n\t\t\t// Don't let the tokenizer go into raw text mode when scripting is disabled.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\treturn true\n\t\tcase a.Script, a.Title:\n\t\t\tp.addElement()\n\t\t\tif p.originalIM == nil {\n\t\t\t\tp.setOriginalIM()\n\t\t\t}\n\t\t\tp.im = textIM\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.addLoc()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Noframes, a.Style:\n\t\t\tp.parseGenericRawTextElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.addLoc()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Head:\n\t\t\t// Ignore the token, but copy attributes and remove implicit marker\n\t\t\t// if an explicit <head> tag is encountered (fixes issue #1124)\n\t\t\tif p.head != nil {\n\t\t\t\tcopyAttributes(p.head, p.tok)\n\t\t\t\tremoveImplicitMarker(p.head)\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// We don't handle all of the corner cases when mixing foreign\n\t\t\t// content (i.e. <math> or <svg>) with <template>. Without this\n\t\t\t// early return, we can get into an infinite loop, possibly because\n\t\t\t// of the \"TODO... further divergence\" a little below.\n\t\t\t//\n\t\t\t// As a workaround, if we are mixing foreign content and templates,\n\t\t\t// just ignore the rest of the HTML. Foreign content is rare and a\n\t\t\t// relatively old HTML feature. Templates are also rare and a\n\t\t\t// relatively new HTML feature. Their combination is very rare.\n\t\t\tfor _, e := range p.oe {\n\t\t\t\tif e.Namespace != \"\" {\n\t\t\t\t\tp.im = ignoreTheRemainingTokens\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tp.addElement()\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inTemplateIM\n\t\t\tp.templateStack = append(p.templateStack, inTemplateIM)\n\t\t\treturn true\n\t\t}\n\n\t\tif p.oe.top() != nil && (isSlot(p.oe.top().Data) || isComponent(p.oe.top().Data) || isFragment((p.oe.top().Data))) {\n\t\t\tp.addElement()\n\t\t\tif p.originalIM == nil {\n\t\t\t\tp.setOriginalIM()\n\t\t\t}\n\t\t\tp.im = inBodyIM\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.addLoc()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tif isComponent(p.tok.Data) || isFragment(p.tok.Data) {\n\t\t\tp.addLoc()\n\t\t\tp.oe.pop()\n\t\t\treturn true\n\t\t}\n\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Head:\n\t\t\tp.addLoc()\n\t\t\tp.popUntil(defaultScope, a.Head)\n\t\t\tp.im = afterHeadIM\n\t\t\treturn true\n\t\tcase a.Body, a.Html, a.Br:\n\t\t\tp.addLoc()\n\t\t\tp.oe.pop()\n\t\t\tp.originalIM = nil\n\t\t\tp.im = afterHeadIM\n\t\t\treturn false\n\t\tcase a.Template:\n\t\t\tif !p.oe.contains(a.Template) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// TODO: remove this further divergence from the HTML5 spec.\n\t\t\t//\n\t\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\t\tp.generateImpliedEndTags()\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tif n := p.oe[i]; n.Namespace == \"\" && n.DataAtom == a.Template {\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.templateStack.pop()\n\t\t\tp.resetInsertionMode()\n\t\t\treturn true\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\tp.addLoc()\n\t\t\tp.oe.pop()\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.templateStack = append(p.templateStack, inExpressionIM)\n\t\tif p.originalIM == nil {\n\t\t\tp.setOriginalIM()\n\t\t}\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\treturn true\n\t}\n\n\tp.parseImpliedToken(EndTagToken, a.Head, a.Head.String())\n\treturn false\n}\n\n// 12.2.6.4.5.\nfunc inHeadNoscriptIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Style:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Head:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Noscript:\n\t\t\t// Don't let the tokenizer go into raw text mode even when a <noscript>\n\t\t\t// tag is in \"in head noscript\" insertion mode.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tdefault:\n\t\t\t// #519: handle any content inside <noscript>\n\t\t\tp.im = inLiteralIM\n\t\t\tp.originalIM = inHeadIM\n\t\t\treturn false\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Noscript, a.Br:\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\tp.addLoc()\n\t\t\treturn true\n\t\t}\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) == 0 {\n\t\t\t// It was all whitespace.\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase CommentToken:\n\t\treturn inHeadIM(p)\n\t}\n\tp.oe.pop()\n\tp.im = inHeadIM\n\treturn p.tok.DataAtom == a.Noscript\n}\n\n// Section 12.2.6.4.6.\nfunc afterHeadIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) < len(p.tok.Data) {\n\t\t\t// Add the initial whitespace to the current node.\n\t\t\tp.addText(p.tok.Data[:len(p.tok.Data)-len(s)])\n\t\t\tif s == \"\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.tok.Data = s\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Body:\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inBodyIM\n\t\t\treturn true\n\t\tcase a.Frameset:\n\t\t\tp.addElement()\n\t\t\tp.im = inFramesetIM\n\t\t\treturn true\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:\n\t\t\tp.oe = append(p.oe, p.head)\n\t\t\tdefer p.oe.remove(p.head)\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Head:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Body, a.Html, a.Br:\n\t\t\t// Drop down to creating an implied <body> tag.\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\tp.addLoc()\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\t// Ignore the token.\n\t\treturn true\n\t}\n\n\tp.parseImpliedToken(StartTagToken, a.Body, a.Body.String())\n\tp.framesetOK = true\n\treturn false\n}\n\n// copyAttributes copies attributes of src not found on dst to dst.\nfunc copyAttributes(dst *Node, src Token) {\n\tif len(src.Attr) == 0 {\n\t\treturn\n\t}\n\tattr := map[string]string{}\n\tfor _, t := range dst.Attr {\n\t\tattr[t.Key] = t.Val\n\t}\n\tfor _, t := range src.Attr {\n\t\tif _, ok := attr[t.Key]; !ok {\n\t\t\tdst.Attr = append(dst.Attr, t)\n\t\t\tattr[t.Key] = t.Val\n\t\t}\n\t}\n}\n\n// removeImplicitMarker removes the ImplicitNodeMarker attribute from a node.\n// This is used when an explicit tag is encountered for a node that was\n// previously created implicitly.\nfunc removeImplicitMarker(n *Node) {\n\tfor i, attr := range n.Attr {\n\t\tif attr.Key == ImplicitNodeMarker {\n\t\t\tn.Attr = append(n.Attr[:i], n.Attr[i+1:]...)\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// Section 12.2.6.4.7.\nfunc inBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase FrontmatterFenceToken:\n\t\t// If originalIM is already set, we have a closing fence without an opening one\n\t\tif p.originalIM != nil {\n\t\t\tp.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\tCode: loc.ERROR_MISSING_FRONTMATTER_FENCE,\n\t\t\t\tText: \"The closing frontmatter fence (---) is missing an opening fence\",\n\t\t\t\tHint: \"Add --- at the beginning of your file before any import statements or code\",\n\t\t\t\tRange: loc.Range{\n\t\t\t\t\tLoc: p.tok.Loc,\n\t\t\t\t\tLen: 3,\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn true\n\t\t}\n\t\tp.setOriginalIM()\n\t\tp.im = frontmatterIM\n\t\treturn false\n\tcase TextToken:\n\t\td := p.tok.Data\n\t\tswitch n := p.top(); n.DataAtom {\n\t\tcase a.Pre, a.Listing:\n\t\t\tif n.FirstChild == nil {\n\t\t\t\t// Ignore a newline at the start of a <pre> block.\n\t\t\t\tif d != \"\" && d[0] == '\\r' {\n\t\t\t\t\td = d[1:]\n\t\t\t\t}\n\t\t\t\tif d != \"\" && d[0] == '\\n' {\n\t\t\t\t\td = d[1:]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\td = strings.Replace(d, \"\\x00\", \"\", -1)\n\t\tif d == \"\" {\n\t\t\treturn true\n\t\t}\n\t\tp.reconstructActiveFormattingElements()\n\t\tp.addText(d)\n\t\tif p.framesetOK && strings.TrimLeft(d, whitespace) != \"\" {\n\t\t\t// There were non-whitespace characters inserted.\n\t\t\tp.framesetOK = false\n\t\t}\n\tcase StartTagToken:\n\t\t// if literal and we only have html and body open\n\t\tif p.literal {\n\t\t\tp.im = inLiteralIM\n\t\t\tp.originalIM = inBodyIM\n\t\t\treturn false\n\t\t}\n\t\t// Handle <html> tag first before the originalIM check, so that\n\t\t// the implicit <head> is not converted to <body> when an explicit\n\t\t// <html> tag is encountered (fixes issue #1124)\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\tif p.inTemplateFragmentContext() {\n\t\t\t\tp.addElement()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif p.oe.contains(a.Template) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif len(p.oe) > 0 {\n\t\t\t\tcopyAttributes(p.oe[0], p.tok)\n\t\t\t\t// Remove ImplicitNodeMarker if an explicit <html> tag is encountered\n\t\t\t\t// This ensures that when a JSX comment appears between DOCTYPE and <html>,\n\t\t\t\t// the explicit <html> tag is properly rendered (fixes issue #1124)\n\t\t\t\tremoveImplicitMarker(p.oe[0])\n\t\t\t}\n\t\t\t// Clear originalIM so that the subsequent <head> tag is not converted to <body>\n\t\t\tp.originalIM = nil\n\t\t\treturn true\n\t\t}\n\t\t// It's possible we were moved here from inHeadIM\n\t\t// via the children of a Component. We need to clear the originalIM\n\t\t// and switch the implicit `head` tag to `body`\n\t\tif p.originalIM != nil {\n\t\t\ti := p.indexOfElementInScope(defaultScope, a.Head)\n\t\t\tif i != -1 {\n\t\t\t\tp.oe[i].Data = \"body\"\n\t\t\t\tp.oe[i].DataAtom = a.Body\n\t\t\t\tp.originalIM = nil\n\t\t\t}\n\t\t}\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\t// Already handled above\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Body:\n\t\t\tif p.inTemplateFragmentContext() {\n\t\t\t\tp.addElement()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif p.oe.contains(a.Template) {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif len(p.oe) > 1 {\n\t\t\t\tbody := p.oe[1]\n\t\t\t\tif body.Type == ElementNode && body.DataAtom == a.Body {\n\t\t\t\t\tp.framesetOK = false\n\t\t\t\t\tcopyAttributes(body, p.tok)\n\t\t\t\t}\n\t\t\t}\n\t\tcase a.Frameset:\n\t\t\tif !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tbody := p.oe[1]\n\t\t\tif body.Parent != nil {\n\t\t\t\tbody.Parent.RemoveChild(body)\n\t\t\t}\n\t\t\tp.oe = p.oe[:1]\n\t\t\tp.addElement()\n\t\t\tp.im = inFramesetIM\n\t\t\treturn true\n\t\tcase a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Main, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tswitch n := p.top(); n.DataAtom {\n\t\t\tcase a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Pre, a.Listing:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\t\t// The newline, if any, will be dealt with by the TextToken case.\n\t\t\tp.framesetOK = false\n\t\tcase a.Form:\n\t\t\tif p.form != nil && !p.oe.contains(a.Template) {\n\t\t\t\t// Ignore the token\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\t\tif !p.oe.contains(a.Template) {\n\t\t\t\tp.form = p.top()\n\t\t\t}\n\t\tcase a.Li:\n\t\t\tp.framesetOK = false\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tnode := p.oe[i]\n\t\t\t\tswitch node.DataAtom {\n\t\t\t\tcase a.Li:\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\tcase a.Address, a.Div, a.P:\n\t\t\t\t\tcontinue\n\t\t\t\tdefault:\n\t\t\t\t\tif !isSpecialElement(node) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.Dd, a.Dt:\n\t\t\tp.framesetOK = false\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tnode := p.oe[i]\n\t\t\t\tswitch node.DataAtom {\n\t\t\t\tcase a.Dd, a.Dt:\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\tcase a.Address, a.Div, a.P:\n\t\t\t\t\tcontinue\n\t\t\t\tdefault:\n\t\t\t\t\tif !isSpecialElement(node) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.Plaintext:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\tcase a.Button:\n\t\t\tp.popUntil(defaultScope, a.Button)\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\tcase a.A:\n\t\t\tfor i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {\n\t\t\t\tif n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {\n\t\t\t\t\tp.inBodyEndTagFormatting(a.A, \"a\")\n\t\t\t\t\tp.oe.remove(n)\n\t\t\t\t\tp.afe.remove(n)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addFormattingElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.afe.pop()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\tcase a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addFormattingElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.afe.pop()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\tcase a.Nobr:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tif p.elementInScope(defaultScope, a.Nobr) {\n\t\t\t\tp.inBodyEndTagFormatting(a.Nobr, \"nobr\")\n\t\t\t\tp.reconstructActiveFormattingElements()\n\t\t\t}\n\t\t\tp.addFormattingElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.afe.pop()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\tcase a.Applet, a.Marquee, a.Object:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.framesetOK = false\n\t\tcase a.Table:\n\t\t\tif !p.quirks {\n\t\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inTableIM\n\t\t\treturn true\n\t\tcase a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\tif p.tok.DataAtom == a.Input {\n\t\t\t\tfor _, t := range p.tok.Attr {\n\t\t\t\t\tif t.Key == \"type\" {\n\t\t\t\t\t\tif strings.ToLower(t.Val) == \"hidden\" {\n\t\t\t\t\t\t\t// Skip setting framesetOK = false\n\t\t\t\t\t\t\treturn true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.framesetOK = false\n\t\tcase a.Param, a.Source, a.Track:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\tcase a.Hr:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\tp.framesetOK = false\n\t\tcase a.Image:\n\t\t\tp.tok.DataAtom = a.Img\n\t\t\tp.tok.Data = a.Img.String()\n\t\t\treturn false\n\t\tcase a.Textarea:\n\t\t\tp.addElement()\n\t\t\tp.originalIM = inBodyIM\n\t\t\tp.framesetOK = false\n\t\t\tp.im = textIM\n\t\tcase a.Xmp:\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.framesetOK = false\n\t\t\tp.parseGenericRawTextElement()\n\t\tcase a.Iframe:\n\t\t\tp.framesetOK = false\n\t\t\tp.parseGenericRawTextElement()\n\t\tcase a.Noembed:\n\t\t\tp.parseGenericRawTextElement()\n\t\tcase a.Noscript:\n\t\t\tif p.scripting {\n\t\t\t\tp.parseGenericRawTextElement()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\t// Don't let the tokenizer go into raw text mode when scripting is disabled.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectIM\n\t\t\treturn true\n\t\tcase a.Optgroup, a.Option:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\tcase a.Rb, a.Rtc:\n\t\t\tif p.elementInScope(defaultScope, a.Ruby) {\n\t\t\t\tp.generateImpliedEndTags()\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\tcase a.Rp, a.Rt:\n\t\t\tif p.elementInScope(defaultScope, a.Ruby) {\n\t\t\t\tp.generateImpliedEndTags(\"rtc\")\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\tcase a.Math, a.Svg:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tif p.tok.DataAtom == a.Math {\n\t\t\t\tadjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)\n\t\t\t} else {\n\t\t\t\tadjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)\n\t\t\t}\n\t\t\tadjustForeignAttributes(p.tok.Attr)\n\t\t\tp.addElement()\n\t\t\tp.top().Namespace = p.tok.Data\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Head:\n\t\t\tif p.inTemplateFragmentContext() {\n\t\t\t\tp.addElement()\n\t\t\t\tp.im = inHeadIM\n\t\t\t\treturn true\n\t\t\t}\n\t\tdefault:\n\t\t\t// Special handling for selectedcontent as a void element\n\t\t\tif p.tok.Data == \"selectedcontent\" {\n\t\t\t\tp.reconstructActiveFormattingElements()\n\t\t\t\tp.addElement()\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t}\n\t\tif p.hasSelfClosingToken {\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t}\n\tcase EndTagToken:\n\t\tif isComponent(p.tok.Data) {\n\t\t\tp.addLoc()\n\t\t\tp.oe.pop()\n\t\t\treturn true\n\t\t}\n\n\t\t// Special handling for selectedcontent end tag - just ignore it\n\t\t// since it's treated as a void element\n\t\tif p.tok.Data == \"selectedcontent\" {\n\t\t\treturn true\n\t\t}\n\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Body:\n\t\t\tp.addLoc()\n\t\t\tif p.elementInScope(defaultScope, a.Body) {\n\t\t\t\tp.im = afterBodyIM\n\t\t\t}\n\t\t\tif p.literal {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\tcase a.Html:\n\t\t\tp.addLoc()\n\t\t\tif p.elementInScope(defaultScope, a.Body) {\n\t\t\t\tp.parseImpliedToken(EndTagToken, a.Body, a.Body.String())\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tif p.literal {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Main, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:\n\t\t\tp.addLoc()\n\t\t\tp.popUntil(defaultScope, p.tok.DataAtom)\n\t\tcase a.Form:\n\t\t\tif p.oe.contains(a.Template) {\n\t\t\t\ti := p.indexOfElementInScope(defaultScope, a.Form)\n\t\t\t\tif i == -1 {\n\t\t\t\t\t// Ignore the token.\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tp.generateImpliedEndTags()\n\t\t\t\tif p.oe[i].DataAtom != a.Form {\n\t\t\t\t\t// Ignore the token.\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tp.addLoc()\n\t\t\t\tp.popUntil(defaultScope, a.Form)\n\t\t\t} else {\n\t\t\t\tnode := p.form\n\t\t\t\tp.form = nil\n\t\t\t\ti := p.indexOfElementInScope(defaultScope, a.Form)\n\t\t\t\tif node == nil || i == -1 || p.oe[i] != node {\n\t\t\t\t\t// Ignore the token.\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t\tp.generateImpliedEndTags()\n\t\t\t\tp.oe.remove(node)\n\t\t\t}\n\t\tcase a.P:\n\t\t\tif !p.elementInScope(buttonScope, a.P) {\n\t\t\t\tp.parseImpliedToken(StartTagToken, a.P, a.P.String())\n\t\t\t}\n\t\t\tp.addLoc()\n\t\t\tp.popUntil(buttonScope, a.P)\n\t\tcase a.Li:\n\t\t\tp.addLoc()\n\t\t\tp.popUntil(listItemScope, a.Li)\n\t\tcase a.Dd, a.Dt:\n\t\t\tp.addLoc()\n\t\t\tp.popUntil(defaultScope, p.tok.DataAtom)\n\t\tcase a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:\n\t\t\tp.addLoc()\n\t\t\tp.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)\n\t\tcase a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:\n\t\t\tp.addLoc()\n\t\t\tp.inBodyEndTagFormatting(p.tok.DataAtom, p.tok.Data)\n\t\tcase a.Applet, a.Marquee, a.Object:\n\t\t\tp.addLoc()\n\t\t\tif p.popUntil(defaultScope, p.tok.DataAtom) {\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t}\n\t\tcase a.Br:\n\t\t\tp.tok.Type = StartTagToken\n\t\t\treturn false\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:\n\t\t\treturn inHeadIM(p)\n\t\tdefault:\n\t\t\tp.inBodyEndTagOther(p.tok.DataAtom, p.tok.Data)\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inBodyIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\treturn true\n\tcase ErrorToken:\n\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\tif len(p.templateStack) > 0 {\n\t\t\tp.im = inTemplateIM\n\t\t\treturn false\n\t\t}\n\t\tfor _, e := range p.oe {\n\t\t\tswitch e.DataAtom {\n\t\t\tcase a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc, a.Tbody, a.Td, a.Tfoot, a.Th,\n\t\t\t\ta.Thead, a.Tr, a.Body, a.Html:\n\t\t\tdefault:\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\tif p.frontmatterState == FrontmatterInitial {\n\t\tp.addFrontmatter(true)\n\t}\n\treturn true\n}\n\nfunc (p *parser) inTemplateFragmentContext() bool {\n\treturn len(p.oe) == 1 && p.context != nil && p.context.DataAtom == a.Template\n}\n\nfunc (p *parser) inBodyEndTagFormatting(tagAtom a.Atom, tagName string) {\n\t// This is the \"adoption agency\" algorithm, described at\n\t// https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency\n\n\t// TODO: this is a fairly literal line-by-line translation of that algorithm.\n\t// Once the code successfully parses the comprehensive test suite, we should\n\t// refactor this code to be more idiomatic.\n\n\t// Steps 1-2\n\tif current := p.oe.top(); current.Data == tagName && p.afe.index(current) == -1 {\n\t\tp.oe.pop()\n\t\treturn\n\t}\n\n\t// Steps 3-5. The outer loop.\n\tfor i := 0; i < 8; i++ {\n\t\t// Step 6. Find the formatting element.\n\t\tvar formattingElement *Node\n\t\tfor j := len(p.afe) - 1; j >= 0; j-- {\n\t\t\tif p.afe[j].Type == scopeMarkerNode {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif p.afe[j].DataAtom == tagAtom {\n\t\t\t\tformattingElement = p.afe[j]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif formattingElement == nil {\n\t\t\tp.inBodyEndTagOther(tagAtom, tagName)\n\t\t\treturn\n\t\t}\n\n\t\t// Step 7. Ignore the tag if formatting element is not in the stack of open elements.\n\t\tfeIndex := p.oe.index(formattingElement)\n\t\tif feIndex == -1 {\n\t\t\tp.afe.remove(formattingElement)\n\t\t\treturn\n\t\t}\n\t\t// Step 8. Ignore the tag if formatting element is not in the scope.\n\t\tif !p.elementInScope(defaultScope, tagAtom) {\n\t\t\t// Ignore the tag.\n\t\t\treturn\n\t\t}\n\n\t\t// Step 9. This step is omitted because it's just a parse error but no need to return.\n\n\t\t// Steps 10-11. Find the furthest block.\n\t\tvar furthestBlock *Node\n\t\tfor _, e := range p.oe[feIndex:] {\n\t\t\tif isSpecialElement(e) {\n\t\t\t\tfurthestBlock = e\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif furthestBlock == nil {\n\t\t\te := p.oe.pop()\n\t\t\tfor e != formattingElement {\n\t\t\t\te = p.oe.pop()\n\t\t\t}\n\t\t\tp.afe.remove(e)\n\t\t\treturn\n\t\t}\n\n\t\t// Steps 12-13. Find the common ancestor and bookmark node.\n\t\tcommonAncestor := p.oe[feIndex-1]\n\t\tbookmark := p.afe.index(formattingElement)\n\n\t\t// Step 14. The inner loop. Find the lastNode to reparent.\n\t\tlastNode := furthestBlock\n\t\tnode := furthestBlock\n\t\tx := p.oe.index(node)\n\t\t// Step 14.1.\n\t\tj := 0\n\t\tfor {\n\t\t\t// Step 14.2.\n\t\t\tj++\n\t\t\t// Step. 14.3.\n\t\t\tx--\n\t\t\tnode = p.oe[x]\n\t\t\t// Step 14.4. Go to the next step if node is formatting element.\n\t\t\tif node == formattingElement {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// Step 14.5. Remove node from the list of active formatting elements if\n\t\t\t// inner loop counter is greater than three and node is in the list of\n\t\t\t// active formatting elements.\n\t\t\tif ni := p.afe.index(node); j > 3 && ni > -1 {\n\t\t\t\tp.afe.remove(node)\n\t\t\t\t// If any element of the list of active formatting elements is removed,\n\t\t\t\t// we need to take care whether bookmark should be decremented or not.\n\t\t\t\t// This is because the value of bookmark may exceed the size of the\n\t\t\t\t// list by removing elements from the list.\n\t\t\t\tif ni <= bookmark {\n\t\t\t\t\tbookmark--\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Step 14.6. Continue the next inner loop if node is not in the list of\n\t\t\t// active formatting elements.\n\t\t\tif p.afe.index(node) == -1 {\n\t\t\t\tp.oe.remove(node)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Step 14.7.\n\t\t\tclone := node.clone()\n\t\t\tp.afe[p.afe.index(node)] = clone\n\t\t\tp.oe[p.oe.index(node)] = clone\n\t\t\tnode = clone\n\t\t\t// Step 14.8.\n\t\t\tif lastNode == furthestBlock {\n\t\t\t\tbookmark = p.afe.index(node) + 1\n\t\t\t}\n\t\t\t// Step 14.9.\n\t\t\tif lastNode.Parent != nil {\n\t\t\t\tlastNode.Parent.RemoveChild(lastNode)\n\t\t\t}\n\t\t\tnode.AppendChild(lastNode)\n\t\t\t// Step 14.10.\n\t\t\tlastNode = node\n\t\t}\n\n\t\t// Step 15. Reparent lastNode to the common ancestor,\n\t\t// or for misnested table nodes, to the foster parent.\n\t\tif lastNode.Parent != nil {\n\t\t\tlastNode.Parent.RemoveChild(lastNode)\n\t\t}\n\t\tswitch commonAncestor.DataAtom {\n\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\tp.fosterParent(lastNode)\n\t\tdefault:\n\t\t\tcommonAncestor.AppendChild(lastNode)\n\t\t}\n\n\t\t// Steps 16-18. Reparent nodes from the furthest block's children\n\t\t// to a clone of the formatting element.\n\t\tclone := formattingElement.clone()\n\t\treparentChildren(clone, furthestBlock)\n\t\tfurthestBlock.AppendChild(clone)\n\n\t\t// Step 19. Fix up the list of active formatting elements.\n\t\tif oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {\n\t\t\t// Move the bookmark with the rest of the list.\n\t\t\tbookmark--\n\t\t}\n\t\tp.afe.remove(formattingElement)\n\t\tp.afe.insert(bookmark, clone)\n\n\t\t// Step 20. Fix up the stack of open elements.\n\t\tp.oe.remove(formattingElement)\n\t\tp.oe.insert(p.oe.index(furthestBlock)+1, clone)\n\t}\n}\n\n// inBodyEndTagOther performs the \"any other end tag\" algorithm for inBodyIM.\n// \"Any other end tag\" handling from 12.2.6.5 The rules for parsing tokens in foreign content\n// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign\nfunc (p *parser) inBodyEndTagOther(tagAtom a.Atom, tagName string) {\n\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t// Two element nodes have the same tag if they have the same Data (a\n\t\t// string-typed field). As an optimization, for common HTML tags, each\n\t\t// Data string is assigned a unique, non-zero DataAtom (a uint32-typed\n\t\t// field), since integer comparison is faster than string comparison.\n\t\t// Uncommon (custom) tags get a zero DataAtom.\n\t\t//\n\t\t// The if condition here is equivalent to (p.oe[i].Data == tagName).\n\t\tif (p.oe[i].DataAtom == tagAtom) &&\n\t\t\t((tagAtom != 0) || (p.oe[i].Data == tagName)) {\n\t\t\tp.addLoc()\n\t\t\t// If we only have a single element, just ignore it\n\t\t\tif len(p.oe) > 1 {\n\t\t\t\tp.oe = p.oe[:i]\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t\tif isSpecialElement(p.oe[i]) {\n\t\t\tp.addLoc()\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// Section 12.2.6.4.8.\nfunc textIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase ErrorToken:\n\t\tif p.inTemplateFragmentContext() {\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase TextToken:\n\t\td := p.tok.Data\n\t\tif n := p.oe.top(); n != nil && n.DataAtom == a.Textarea && n.FirstChild == nil {\n\t\t\t// Ignore a newline at the start of a <textarea> block.\n\t\t\tif d != \"\" && d[0] == '\\r' {\n\t\t\t\td = d[1:]\n\t\t\t}\n\t\t\tif d != \"\" && d[0] == '\\n' {\n\t\t\t\td = d[1:]\n\t\t\t}\n\t\t}\n\t\tif d == \"\" {\n\t\t\treturn true\n\t\t}\n\t\tp.addText(d)\n\t\treturn true\n\tcase EndTagToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\tif p.tok.DataAtom == a.Form {\n\t\t\tp.form = nil\n\t\t}\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\treturn true\n\t}\n\tp.im = p.originalIM\n\tp.originalIM = nil\n\treturn p.tok.Type == EndTagToken\n}\n\n// Section 12.2.6.4.9.\nfunc inTableIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tp.tok.Data = strings.Replace(p.tok.Data, \"\\x00\", \"\", -1)\n\t\ttop := p.oe.top()\n\t\tif top != nil {\n\t\t\tswitch top.DataAtom {\n\t\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\t\tif strings.Trim(p.tok.Data, whitespace) == \"\" {\n\t\t\t\t\tp.addText(p.tok.Data)\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inTableIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase StartTagToken:\n\t\tif isComponent(p.tok.Data) || isFragment(p.tok.Data) {\n\t\t\tp.originalIM = inTableIM\n\t\t\tp.im = inLiteralIM\n\t\t\treturn false\n\t\t}\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Caption:\n\t\t\tp.clearStackToContext(tableScope)\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.addElement()\n\t\t\tp.im = inCaptionIM\n\t\t\treturn true\n\t\tcase a.Colgroup:\n\t\t\tp.clearStackToContext(tableScope)\n\t\t\tp.addElement()\n\t\t\tp.im = inColumnGroupIM\n\t\t\treturn true\n\t\tcase a.Col:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Colgroup, a.Colgroup.String())\n\t\t\treturn false\n\t\tcase a.Tbody, a.Tfoot, a.Thead:\n\t\t\tp.clearStackToContext(tableScope)\n\t\t\tp.addElement()\n\t\t\tp.im = inTableBodyIM\n\t\t\treturn true\n\t\tcase a.Td, a.Th, a.Tr:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Tbody, a.Tbody.String())\n\t\t\treturn false\n\t\tcase a.Table:\n\t\t\tif p.popUntil(tableScope, a.Table) {\n\t\t\t\tp.resetInsertionMode()\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Style, a.Script, a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Input:\n\t\t\tfor _, t := range p.tok.Attr {\n\t\t\t\tif t.Key == \"type\" && strings.ToLower(t.Val) == \"hidden\" {\n\t\t\t\t\tp.addElement()\n\t\t\t\t\tp.oe.pop()\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Otherwise drop down to the default action.\n\t\tcase a.Form:\n\t\t\tif p.oe.contains(a.Template) || p.form != nil {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tp.form = p.oe.pop()\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tswitch p.top().DataAtom {\n\t\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\t\tp.fosterParenting = true\n\t\t\t}\n\t\t\tp.addElement()\n\t\t\tp.fosterParenting = false\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectInTableIM\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Table:\n\t\t\tif p.popUntil(tableScope, a.Table) {\n\t\t\t\tp.resetInsertionMode()\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Slot:\n\t\t\tp.oe.pop()\n\t\t\treturn true\n\t\t}\n\t\tif isComponent(p.tok.Data) {\n\t\t\tp.oe.pop()\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase ErrorToken:\n\t\treturn inBodyIM(p)\n\t}\n\n\tp.fosterParenting = true\n\tdefer func() { p.fosterParenting = false }()\n\treturn inBodyIM(p)\n}\n\n// Section 12.2.6.4.11.\nfunc inCaptionIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Thead, a.Tr:\n\t\t\tif !p.popUntil(tableScope, a.Caption) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.im = inTableIM\n\t\t\treturn false\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectInTableIM\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Caption:\n\t\t\tif p.popUntil(tableScope, a.Caption) {\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t\tp.im = inTableIM\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Table:\n\t\t\tif !p.popUntil(tableScope, a.Caption) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.im = inTableIM\n\t\t\treturn false\n\t\tcase a.Body, a.Col, a.Colgroup, a.Html, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inBodyIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.oe.pop()\n\t\treturn true\n\t}\n\treturn inBodyIM(p)\n}\n\n// Section 12.2.6.4.12.\nfunc inColumnGroupIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) < len(p.tok.Data) {\n\t\t\t// Add the initial whitespace to the current node.\n\t\t\tp.addText(p.tok.Data[:len(p.tok.Data)-len(s)])\n\t\t\tif s == \"\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.tok.Data = s\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Col:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Colgroup:\n\t\t\tif p.oe.top().DataAtom == a.Colgroup {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableIM\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Col:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase ErrorToken:\n\t\treturn inBodyIM(p)\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inTableIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.oe.pop()\n\t\treturn true\n\t}\n\tif p.oe.top().DataAtom != a.Colgroup {\n\t\treturn true\n\t}\n\tp.oe.pop()\n\tp.im = inTableIM\n\treturn false\n}\n\n// Section 12.2.6.4.13.\nfunc inTableBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Tr:\n\t\t\tp.clearStackToContext(tableBodyScope)\n\t\t\tp.addElement()\n\t\t\tp.im = inRowIM\n\t\t\treturn true\n\t\tcase a.Td, a.Th:\n\t\t\tp.parseImpliedToken(StartTagToken, a.Tr, a.Tr.String())\n\t\t\treturn false\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:\n\t\t\tif p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) {\n\t\t\t\tp.im = inTableIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Tbody, a.Tfoot, a.Thead:\n\t\t\tif p.elementInScope(tableScope, p.tok.DataAtom) {\n\t\t\t\tp.clearStackToContext(tableBodyScope)\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.im = inTableIM\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Table:\n\t\t\tif p.popUntil(tableScope, a.Tbody, a.Thead, a.Tfoot) {\n\t\t\t\tp.im = inTableIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th, a.Tr:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inTableIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.oe.pop()\n\t\treturn true\n\t}\n\n\treturn inTableIM(p)\n}\n\n// Section 12.2.6.4.14.\nfunc inRowIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inRowIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Td, a.Th:\n\t\t\tp.clearStackToContext(tableRowScope)\n\t\t\tp.addElement()\n\t\t\tp.afe = append(p.afe, &scopeMarker)\n\t\t\tp.im = inCellIM\n\t\t\treturn true\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\tif p.popUntil(tableScope, a.Tr) {\n\t\t\t\tp.im = inTableBodyIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Tr:\n\t\t\tif p.popUntil(tableScope, a.Tr) {\n\t\t\t\tp.im = inTableBodyIM\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Table:\n\t\t\tif p.popUntil(tableScope, a.Tr) {\n\t\t\t\tp.im = inTableBodyIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Tbody, a.Tfoot, a.Thead:\n\t\t\tif p.elementInScope(tableScope, p.tok.DataAtom) {\n\t\t\t\tp.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String())\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html, a.Td, a.Th:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase EndExpressionToken:\n\t\tp.oe.pop()\n\t\treturn true\n\t}\n\treturn inTableIM(p)\n}\n\n// Section 12.2.6.4.15.\nfunc inCellIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inBodyIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.oe.pop()\n\t\treturn true\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Slot:\n\t\t\tp.addElement()\n\t\t\tif p.hasSelfClosingToken {\n\t\t\t\tp.oe.pop()\n\t\t\t\tp.acknowledgeSelfClosingTag()\n\t\t\t}\n\t\t\treturn true\n\t\tcase a.Caption, a.Col, a.Colgroup, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:\n\t\t\tif p.popUntil(tableScope, a.Td, a.Th) {\n\t\t\t\t// Close the cell and reprocess.\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t\tp.im = inRowIM\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Select:\n\t\t\tp.reconstructActiveFormattingElements()\n\t\t\tp.addElement()\n\t\t\tp.framesetOK = false\n\t\t\tp.im = inSelectInTableIM\n\t\t\treturn true\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Td, a.Th:\n\t\t\tif !p.popUntil(tableScope, p.tok.DataAtom) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.clearActiveFormattingElements()\n\t\t\tp.im = inRowIM\n\t\t\treturn true\n\t\tcase a.Body, a.Caption, a.Col, a.Colgroup, a.Html:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:\n\t\t\tif !p.elementInScope(tableScope, p.tok.DataAtom) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// Close the cell and reprocess.\n\t\t\tif p.popUntil(tableScope, a.Td, a.Th) {\n\t\t\t\tp.clearActiveFormattingElements()\n\t\t\t}\n\t\t\tp.im = inRowIM\n\t\t\treturn false\n\t\t}\n\t}\n\treturn inBodyIM(p)\n}\n\n// Section 12.2.6.4.16.\nfunc inSelectIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tp.addText(strings.Replace(p.tok.Data, \"\\x00\", \"\", -1))\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Option:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Optgroup:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tif p.top().DataAtom == a.Optgroup {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\t\tp.addElement()\n\t\tcase a.Select:\n\t\t\tif !p.popUntil(selectScope, a.Select) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.resetInsertionMode()\n\t\tcase a.Input, a.Keygen, a.Textarea:\n\t\t\tif p.elementInScope(selectScope, a.Select) {\n\t\t\t\tp.parseImpliedToken(EndTagToken, a.Select, a.Select.String())\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// In order to properly ignore <textarea>, we need to change the tokenizer mode.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tcase a.Script, a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Iframe, a.Noembed, a.Noframes, a.Noscript, a.Plaintext, a.Style, a.Title, a.Xmp:\n\t\t\t// Don't let the tokenizer go into raw text mode when there are raw tags\n\t\t\t// to be ignored. These tags should be ignored from the tokenizer\n\t\t\t// properly.\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\tdefault:\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Option:\n\t\t\tif p.top().DataAtom == a.Option {\n\t\t\t\tp.oe.pop()\n\t\t\t}\n\t\tcase a.Optgroup:\n\t\t\ti := len(p.oe) - 1\n\t\t\tif p.oe[i].DataAtom == a.Option {\n\t\t\t\ti--\n\t\t\t}\n\t\t\tif p.oe[i].DataAtom == a.Optgroup {\n\t\t\t\tp.oe = p.oe[:i]\n\t\t\t}\n\t\tcase a.Select:\n\t\t\tif !p.popUntil(selectScope, a.Select) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tp.resetInsertionMode()\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tdefault:\n\t\t\t// Handle closing tags for elements that are allowed in customizable select\n\t\t\t// (like button for the new HTML select element)\n\t\t\tif p.tok.Data == \"button\" {\n\t\t\t\t// Close the button if it's open\n\t\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\t\tif p.oe[i].Data == \"button\" {\n\t\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.originalIM = inBodyIM\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\treturn inBodyIM(p)\n\tcase DoctypeToken:\n\t\t// Ignore the token.\n\t\treturn true\n\tcase ErrorToken:\n\t\treturn inBodyIM(p)\n\t}\n\n\treturn true\n}\n\n// Section 12.2.6.4.17.\nfunc inSelectInTableIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase StartTagToken, EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Caption, a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr, a.Td, a.Th:\n\t\t\tif p.tok.Type == EndTagToken && !p.elementInScope(tableScope, p.tok.DataAtom) {\n\t\t\t\t// Ignore the token.\n\t\t\t\treturn true\n\t\t\t}\n\t\t\t// This is like p.popUntil(selectScope, a.Select), but it also\n\t\t\t// matches <math select>, not just <select>. Matching the MathML\n\t\t\t// tag is arguably incorrect (conceptually), but it mimics what\n\t\t\t// Chromium does.\n\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\tif n := p.oe[i]; n.DataAtom == a.Select {\n\t\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.resetInsertionMode()\n\t\t\treturn false\n\t\t}\n\t}\n\treturn inSelectIM(p)\n}\n\n// Section 12.2.6.4.18.\nfunc inTemplateIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken, CommentToken, DoctypeToken, FrontmatterFenceToken:\n\t\treturn inBodyIM(p)\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:\n\t\t\treturn inHeadIM(p)\n\t\tcase a.Caption, a.Colgroup, a.Tbody, a.Tfoot, a.Thead:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inTableIM)\n\t\t\tp.im = inTableIM\n\t\t\treturn false\n\t\tcase a.Col:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inColumnGroupIM)\n\t\t\tp.im = inColumnGroupIM\n\t\t\treturn false\n\t\tcase a.Tr:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inTableBodyIM)\n\t\t\tp.im = inTableBodyIM\n\t\t\treturn false\n\t\tcase a.Td, a.Th:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inRowIM)\n\t\t\tp.im = inRowIM\n\t\t\treturn false\n\t\tdefault:\n\t\t\tp.templateStack.pop()\n\t\t\tp.templateStack = append(p.templateStack, inBodyIM)\n\t\t\tp.im = inBodyIM\n\t\t\treturn false\n\t\t}\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\tp.templateStack.pop()\n\t\tp.templateStack = append(p.templateStack, inExpressionIM)\n\t\tp.im = inExpressionIM\n\t\treturn true\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Template:\n\t\t\treturn inHeadIM(p)\n\t\tdefault:\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\tcase ErrorToken:\n\t\tif !p.oe.contains(a.Template) {\n\t\t\t// Ignore the token.\n\t\t\treturn true\n\t\t}\n\t\t// TODO: remove this divergence from the HTML5 spec.\n\t\t//\n\t\t// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668\n\t\tp.generateImpliedEndTags()\n\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\tif n := p.oe[i]; n.Namespace == \"\" && n.DataAtom == a.Template {\n\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tp.clearActiveFormattingElements()\n\t\tp.templateStack.pop()\n\t\tp.resetInsertionMode()\n\t\treturn false\n\t}\n\treturn false\n}\n\n// Section 12.2.6.4.19.\nfunc afterBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase ErrorToken:\n\t\t// Stop parsing.\n\t\treturn true\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) == 0 {\n\t\t\t// It was all whitespace.\n\t\t\treturn true\n\t\t}\n\tcase StartTagToken:\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tif p.literal {\n\t\t\tp.im = inLiteralIM\n\t\t\tp.originalIM = afterBodyIM\n\t\t\treturn false\n\t\t}\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\tif !p.fragment {\n\t\t\t\tp.im = afterAfterBodyIM\n\t\t\t}\n\t\t\treturn true\n\t\t}\n\tcase CommentToken:\n\t\t// The comment is attached to the <html> element.\n\t\tif len(p.oe) < 1 || p.oe[0].DataAtom != a.Html {\n\t\t\tpanic(\"html: bad parser state: <html> element not found, in the after-body insertion mode\")\n\t\t}\n\t\tp.oe[0].AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\t}\n\tp.im = inBodyIM\n\treturn false\n}\n\n// Section 12.2.6.4.20.\nfunc inFramesetIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\tcase TextToken:\n\t\t// Ignore all text but whitespace.\n\t\ts := strings.Map(func(c rune) rune {\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\t', '\\n', '\\f', '\\r':\n\t\t\t\treturn c\n\t\t\t}\n\t\t\treturn -1\n\t\t}, p.tok.Data)\n\t\tif s != \"\" {\n\t\t\tp.addText(s)\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Frameset:\n\t\t\tp.addElement()\n\t\tcase a.Frame:\n\t\t\tp.addElement()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\tcase a.Noframes:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Frameset:\n\t\t\tif p.oe.top().DataAtom != a.Html {\n\t\t\t\tp.oe.pop()\n\t\t\t\tif p.oe.top().DataAtom != a.Frameset {\n\t\t\t\t\tp.im = afterFramesetIM\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\n// Section 12.2.6.4.21.\nfunc afterFramesetIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\tcase TextToken:\n\t\t// Ignore all text but whitespace.\n\t\ts := strings.Map(func(c rune) rune {\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\t', '\\n', '\\f', '\\r':\n\t\t\t\treturn c\n\t\t\t}\n\t\t\treturn -1\n\t\t}, p.tok.Data)\n\t\tif s != \"\" {\n\t\t\tp.addText(s)\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Noframes:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase EndTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\tp.im = afterAfterFramesetIM\n\t\t\treturn true\n\t\t}\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\n// Section 12.2.6.4.22.\nfunc afterAfterBodyIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase ErrorToken:\n\t\t// Stop parsing.\n\t\treturn true\n\tcase TextToken:\n\t\ts := strings.TrimLeft(p.tok.Data, whitespace)\n\t\tif len(s) == 0 {\n\t\t\t// It was all whitespace.\n\t\t\treturn true\n\t\t}\n\tcase StartTagToken:\n\t\tif p.tok.DataAtom == a.Html {\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\tcase DoctypeToken:\n\t\treturn inBodyIM(p)\n\t}\n\tp.im = inBodyIM\n\treturn false\n}\n\n// Section 12.2.6.4.23.\nfunc afterAfterFramesetIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase CommentToken:\n\t\tp.doc.AppendChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\tcase TextToken:\n\t\t// Ignore all text but whitespace.\n\t\ts := strings.Map(func(c rune) rune {\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\t', '\\n', '\\f', '\\r':\n\t\t\t\treturn c\n\t\t\t}\n\t\t\treturn -1\n\t\t}, p.tok.Data)\n\t\tif s != \"\" {\n\t\t\tp.tok.Data = s\n\t\t\treturn inBodyIM(p)\n\t\t}\n\tcase StartTagToken:\n\t\tswitch p.tok.DataAtom {\n\t\tcase a.Html:\n\t\t\treturn inBodyIM(p)\n\t\tcase a.Noframes:\n\t\t\treturn inHeadIM(p)\n\t\t}\n\tcase DoctypeToken:\n\t\treturn inBodyIM(p)\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\n// Handle Frontmatter content, depending on p.frontmatterState\nfunc frontmatterIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase FrontmatterFenceToken:\n\t\tif p.frontmatterState == FrontmatterInitial {\n\t\t\tp.addFrontmatter(false)\n\t\t\treturn true\n\t\t} else {\n\t\t\tp.frontmatterState = FrontmatterClosed\n\t\t\tp.fm.Loc = append(p.fm.Loc, p.tok.Loc)\n\t\t\tfor range p.oe {\n\t\t\t\t// This removes any elements in the Frontmatter from the stack\n\t\t\t\t// Note that we can't pop the root <html> element — we need it for ParseFragment\n\t\t\t\tif p.oe.top().DataAtom != a.Html {\n\t\t\t\t\tp.oe.pop()\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.im = p.originalIM\n\t\t\tp.originalIM = nil\n\t\t\treturn true\n\t\t}\n\tcase TextToken:\n\t\tp.addText(p.tok.Data)\n\t\treturn true\n\tcase StartTagToken:\n\t\t// If we're inside of a frontmatter node and there's no space before this tag,\n\t\t// it's probably a type param.\n\t\tif p.top().Type == FrontmatterNode && p.ltok.Data[len(p.ltok.Data)-1:] != \" \" {\n\t\t\tp.addText(\"<\")\n\t\t\tp.addText(p.tok.Data)\n\t\t\tp.addText(\">\")\n\t\t\treturn true\n\t\t}\n\n\t\tp.addElement()\n\t\tif p.hasSelfClosingToken {\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t}\n\t\treturn true\n\tcase EndTagToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\treturn true\n\tdefault:\n\t\t// Might be EOF, make sure to capture last location\n\t\tp.addLoc()\n\t\tp.im = p.originalIM\n\t\tp.originalIM = nil\n\t\treturn false\n\t}\n}\n\n// Handle content very literally\nfunc inLiteralIM(p *parser) bool {\n\tshouldExit := p.exitLiteralIM()\n\tswitch p.tok.Type {\n\tcase StartTagToken:\n\t\tp.addElement()\n\t\tif p.hasSelfClosingToken {\n\t\t\tp.addLoc()\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t} else {\n\t\t\t// always continue `inLiteralIM`\n\t\t\treturn true\n\t\t}\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\t// always continue `inLiteralIM`\n\t\treturn true\n\tcase ErrorToken:\n\t\t// Stop parsing.\n\tcase TextToken:\n\t\tp.addText(p.tok.Data)\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\tcase EndTagToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t}\n\tif shouldExit {\n\t\tp.im = p.originalIM\n\t\tp.originalIM = nil\n\t}\n\treturn true\n}\n\nfunc inExpressionIM(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase ErrorToken:\n\t\tp.oe.pop()\n\tcase TextToken:\n\t\treturn textIM(p)\n\tcase StartTagToken:\n\t\tif p.isInsideHead() {\n\t\t\t// Allow components in Head Expression\n\t\t\tif isComponent(p.tok.Data) || isFragment(p.tok.Data) {\n\t\t\t\torigIm := p.originalIM\n\t\t\t\tp.originalIM = nil\n\t\t\t\tret := inLiteralIM(p)\n\t\t\t\tp.im = inExpressionIM\n\t\t\t\tp.originalIM = origIm\n\t\t\t\treturn ret\n\t\t\t}\n\t\t\tswitch p.tok.DataAtom {\n\t\t\tcase a.Noframes, a.Style, a.Script, a.Title, a.Noscript, a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Slot:\n\t\t\t\torigIm := p.originalIM\n\t\t\t\tp.originalIM = nil\n\t\t\t\tret := inHeadIM(p)\n\t\t\t\tp.im = inExpressionIM\n\t\t\t\tp.originalIM = origIm\n\t\t\t\treturn ret\n\t\t\tdefault:\n\t\t\t\tp.im = inLiteralIM\n\t\t\t\tp.originalIM = inExpressionIM\n\t\t\t\tp.exitLiteralIM = getExitLiteralFunc(p)\n\t\t\t\treturn false\n\t\t\t}\n\t\t} else {\n\t\t\tswitch p.tok.DataAtom {\n\t\t\tcase a.Table, a.Tbody, a.Thead, a.Tr, a.Td, a.Th:\n\t\t\t\tp.im = inLiteralIM\n\t\t\t\tp.originalIM = inExpressionIM\n\t\t\t\tp.exitLiteralIM = getExitLiteralFunc(p)\n\t\t\t\treturn false\n\t\t\tdefault:\n\t\t\t\treturn inBodyIM(p)\n\t\t\t}\n\t\t}\n\tcase EndTagToken:\n\t\treturn inBodyIM(p)\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\tp.resetInsertionMode()\n\t\treturn true\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\t\treturn true\n\t}\n\tp.im = p.originalIM\n\tp.originalIM = nil\n\treturn p.tok.Type == EndTagToken\n}\n\nfunc ignoreTheRemainingTokens(p *parser) bool {\n\treturn true\n}\n\n// Generate a function that will exit `inLiteralIM` when all expressions are closed\nfunc getExitLiteralFunc(p *parser) func() bool {\n\toe := len(p.oe)\n\treturn func() bool {\n\t\treturn len(p.oe) == oe\n\t}\n}\n\nconst whitespaceOrNUL = whitespace + \"\\x00\"\n\n// Section 12.2.6.5\nfunc parseForeignContent(p *parser) bool {\n\tswitch p.tok.Type {\n\tcase TextToken:\n\t\tif p.framesetOK {\n\t\t\tp.framesetOK = strings.TrimLeft(p.tok.Data, whitespaceOrNUL) == \"\"\n\t\t}\n\t\tp.tok.Data = strings.Replace(p.tok.Data, \"\\x00\", \"\\ufffd\", -1)\n\t\tp.addText(p.tok.Data)\n\tcase CommentToken:\n\t\tp.addChild(&Node{\n\t\t\tType: CommentNode,\n\t\t\tData: p.tok.Data,\n\t\t\tLoc:  p.generateLoc(),\n\t\t})\n\tcase StartTagToken:\n\t\tif !p.fragment {\n\t\t\tb := breakout[p.tok.Data]\n\t\t\tif p.tok.DataAtom == a.Font {\n\t\t\tloop:\n\t\t\t\tfor _, attr := range p.tok.Attr {\n\t\t\t\t\tswitch attr.Key {\n\t\t\t\t\tcase \"color\", \"face\", \"size\":\n\t\t\t\t\t\tb = true\n\t\t\t\t\t\tbreak loop\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif b {\n\t\t\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\t\t\tn := p.oe[i]\n\t\t\t\t\tif n.Namespace == \"\" || htmlIntegrationPoint(n) || mathMLTextIntegrationPoint(n) {\n\t\t\t\t\t\tp.oe = p.oe[:i+1]\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\tcurrent := p.adjustedCurrentNode()\n\t\tswitch current.Namespace {\n\t\tcase \"math\":\n\t\t\tadjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)\n\t\tcase \"svg\":\n\t\t\t// Adjust SVG tag names. The tokenizer lower-cases tag names, but\n\t\t\t// SVG wants e.g. \"foreignObject\" with a capital second \"O\".\n\t\t\tif x := svgTagNameAdjustments[p.tok.Data]; x != \"\" {\n\t\t\t\tp.tok.DataAtom = a.Lookup([]byte(x))\n\t\t\t\tp.tok.Data = x\n\t\t\t}\n\t\t\tadjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)\n\t\tdefault:\n\t\t\tpanic(\"html: bad parser state: unexpected namespace\")\n\t\t}\n\t\tadjustForeignAttributes(p.tok.Attr)\n\t\tnamespace := current.Namespace\n\t\tp.addElement()\n\t\tp.top().Namespace = namespace\n\t\tif namespace != \"\" {\n\t\t\t// Don't let the tokenizer go into raw text mode in foreign content\n\t\t\t// (e.g. in an SVG <title> tag).\n\t\t\tp.tokenizer.NextIsNotRawText()\n\t\t}\n\t\tif p.hasSelfClosingToken {\n\t\t\tp.oe.pop()\n\t\t\tp.acknowledgeSelfClosingTag()\n\t\t}\n\tcase EndTagToken:\n\t\tfor i := len(p.oe) - 1; i >= 0; i-- {\n\t\t\tif p.oe[i].Namespace == \"\" {\n\t\t\t\treturn p.im(p)\n\t\t\t}\n\t\t\tif strings.EqualFold(p.oe[i].Data, p.tok.Data) {\n\t\t\t\tp.oe = p.oe[:i]\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\treturn true\n\tcase StartExpressionToken:\n\t\tp.addExpression()\n\t\tp.afe = append(p.afe, &scopeMarker)\n\t\treturn true\n\tcase EndExpressionToken:\n\t\tp.addLoc()\n\t\tp.oe.pop()\n\t\treturn true\n\tdefault:\n\t\t// Ignore the token.\n\t}\n\treturn true\n}\n\n// Section 12.2.4.2.\nfunc (p *parser) adjustedCurrentNode() *Node {\n\tif len(p.oe) == 1 && p.fragment && p.context != nil {\n\t\treturn p.context\n\t}\n\treturn p.oe.top()\n}\n\n// Section 12.2.6.\nfunc (p *parser) inForeignContent() bool {\n\tif len(p.oe) == 0 {\n\t\treturn false\n\t}\n\tn := p.adjustedCurrentNode()\n\tif n.Namespace == \"\" {\n\t\treturn false\n\t}\n\tif mathMLTextIntegrationPoint(n) {\n\t\tif p.tok.Type == StartTagToken && p.tok.DataAtom != a.Mglyph && p.tok.DataAtom != a.Malignmark {\n\t\t\treturn false\n\t\t}\n\t\tif p.tok.Type == TextToken {\n\t\t\treturn false\n\t\t}\n\t}\n\tif n.Namespace == \"math\" && n.DataAtom == a.AnnotationXml && p.tok.Type == StartTagToken && p.tok.DataAtom == a.Svg {\n\t\treturn false\n\t}\n\tif htmlIntegrationPoint(n) && (p.tok.Type == StartTagToken || p.tok.Type == TextToken) {\n\t\treturn false\n\t}\n\tif p.tok.Type == ErrorToken {\n\t\treturn false\n\t}\n\treturn true\n}\n\n// parseImpliedToken parses a token as though it had appeared in the parser's\n// input.\nfunc (p *parser) parseImpliedToken(t TokenType, dataAtom a.Atom, data string) {\n\trealToken, selfClosing := p.tok, p.hasSelfClosingToken\n\tp.tok = Token{\n\t\tType:     t,\n\t\tDataAtom: dataAtom,\n\t\tData:     data,\n\t\tAttr:     []Attribute{{Key: ImplicitNodeMarker, Type: EmptyAttribute}},\n\t}\n\tp.hasSelfClosingToken = false\n\tp.parseCurrentToken()\n\tp.tok, p.hasSelfClosingToken = realToken, selfClosing\n}\n\n// parseCurrentToken runs the current token through the parsing routines\n// until it is consumed.\nfunc (p *parser) parseCurrentToken() {\n\tif p.tok.Type == SelfClosingTagToken {\n\t\tp.hasSelfClosingToken = true\n\t\tp.tok.Type = StartTagToken\n\t}\n\n\tconsumed := false\n\tfor !consumed {\n\t\tif p.inForeignContent() {\n\t\t\tconsumed = parseForeignContent(p)\n\t\t} else {\n\t\t\tif p.im == nil {\n\t\t\t\tp.im = inBodyIM\n\t\t\t}\n\t\t\tconsumed = p.im(p)\n\t\t}\n\t}\n\n\tif p.hasSelfClosingToken {\n\t\t// This is a parse error, but ignore it.\n\t\tp.hasSelfClosingToken = false\n\t}\n}\n\nfunc (p *parser) parse() error {\n\t// Iterate until EOF. Any other error will cause an early return.\n\tvar err error\n\tfor err != io.EOF {\n\t\t// CDATA sections are allowed only in foreign content.\n\t\tn := p.oe.top()\n\t\tp.tokenizer.AllowCDATA(n != nil && n.Namespace != \"\")\n\t\tp.ltok = p.tok\n\t\t// Read and parse the next token.\n\t\tp.tokenizer.Next()\n\t\tp.tok = p.tokenizer.Token()\n\t\tif p.tok.Type == ErrorToken {\n\t\t\terr = p.tokenizer.Err()\n\t\t\tif err != nil && err != io.EOF {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\tp.parseCurrentToken()\n\t}\n\treturn nil\n}\n\n// Parse returns the parse tree for the HTML from the given Reader.\n//\n// It implements the HTML5 parsing algorithm\n// (https://html.spec.whatwg.org/multipage/syntax.html#tree-construction),\n// which is very complicated. The resultant tree can contain implicitly created\n// nodes that have no explicit <tag> listed in r's data, and nodes' parents can\n// differ from the nesting implied by a naive processing of start and end\n// <tag>s. Conversely, explicit <tag>s in r's data can be silently dropped,\n// with no corresponding node in the resulting tree.\n//\n// The input is assumed to be UTF-8 encoded.\nfunc Parse(r io.Reader) (*Node, error) {\n\treturn ParseWithOptions(r)\n}\n\n// ParseOption configures a parser.\ntype ParseOption func(p *parser)\n\nfunc ParseOptionWithHandler(h *handler.Handler) ParseOption {\n\treturn func(p *parser) {\n\t\tp.handler = h\n\t\tp.tokenizer.handler = h\n\t}\n}\n\n// ParseOptionEnableScripting configures the scripting flag.\n// https://html.spec.whatwg.org/multipage/webappapis.html#enabling-and-disabling-scripting\n//\n// By default, scripting is enabled.\nfunc ParseOptionEnableScripting(enable bool) ParseOption {\n\treturn func(p *parser) {\n\t\tp.scripting = enable\n\t}\n}\n\nfunc ParseOptionEnableLiteral(enable bool) ParseOption {\n\treturn func(p *parser) {\n\t\tp.literal = enable\n\t}\n}\n\n// ParseWithOptions is like Parse, with options.\nfunc ParseWithOptions(r io.Reader, opts ...ParseOption) (*Node, error) {\n\tp := &parser{\n\t\ttokenizer: NewTokenizer(r),\n\t\tdoc: &Node{\n\t\t\tType:                DocumentNode,\n\t\t\tHydrationDirectives: make(map[string]bool),\n\t\t},\n\t\tframesetOK:       true,\n\t\tim:               initialIM,\n\t\tfrontmatterState: FrontmatterInitial,\n\t\texitLiteralIM:    func() bool { return false },\n\t}\n\n\tfor _, f := range opts {\n\t\tf(p)\n\t}\n\n\tif err := p.parse(); err != nil {\n\t\treturn nil, err\n\t}\n\treturn p.doc, nil\n}\n\n// ParseFragmentWithOptions parses a fragment of HTML and returns the nodes that were\n// found. If the fragment is the InnerHTML for an existing element, pass that\n// element in context.\nfunc ParseFragmentWithOptions(r io.Reader, context *Node, opts ...ParseOption) ([]*Node, error) {\n\tcontextTag := \"\"\n\tif context != nil {\n\t\tif context.Type != ElementNode {\n\t\t\treturn nil, errors.New(\"html: ParseFragment of non-element Node\")\n\t\t}\n\t\t// The next check isn't just context.DataAtom.String() == context.Data because\n\t\t// it is valid to pass an element whose tag isn't a known atom. For example,\n\t\t// DataAtom == 0 and Data = \"tagfromthefuture\" is perfectly consistent.\n\t\tif context.DataAtom != a.Lookup([]byte(context.Data)) {\n\t\t\treturn nil, fmt.Errorf(\"html: inconsistent Node: DataAtom=%q, Data=%q\", context.DataAtom, context.Data)\n\t\t}\n\t\tcontextTag = context.DataAtom.String()\n\t}\n\tp := &parser{\n\t\tdoc: &Node{\n\t\t\tType: DocumentNode,\n\t\t},\n\t\tscripting:        true,\n\t\tfragment:         true,\n\t\tcontext:          context,\n\t\tfrontmatterState: FrontmatterInitial,\n\t\texitLiteralIM:    func() bool { return false },\n\t}\n\tif context != nil && context.Namespace != \"\" {\n\t\tp.tokenizer = NewTokenizer(r)\n\t} else {\n\t\tp.tokenizer = NewTokenizerFragment(r, contextTag)\n\t}\n\n\tfor _, f := range opts {\n\t\tf(p)\n\t}\n\n\tif p.handler == nil {\n\t\treturn nil, errors.New(\"html: handler must be passed to ParseFragmentWithOptions\")\n\t}\n\n\troot := &Node{\n\t\tType:     ElementNode,\n\t\tDataAtom: a.Html,\n\t\tData:     a.Html.String(),\n\t\tLoc:      p.generateLoc(),\n\t}\n\tp.doc.AppendChild(root)\n\tp.oe = nodeStack{root}\n\tif context != nil && context.DataAtom == a.Template {\n\t\tp.templateStack = append(p.templateStack, inTemplateIM)\n\t}\n\tp.resetInsertionMode()\n\n\tfor n := context; n != nil; n = n.Parent {\n\t\tif n.Type == ElementNode && n.DataAtom == a.Form {\n\t\t\tp.form = n\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif err := p.parse(); err != nil {\n\t\treturn nil, err\n\t}\n\n\tparent := p.doc\n\tif context != nil {\n\t\tparent = root\n\t}\n\n\tvar result []*Node\n\n\tif p.fm != nil && p.fm.FirstChild != nil {\n\t\tp.fm.Parent.RemoveChild(p.fm)\n\t\tresult = append(result, p.fm)\n\t}\n\tfor c := parent.FirstChild; c != nil; {\n\t\tnext := c.NextSibling\n\t\tparent.RemoveChild(c)\n\t\tresult = append(result, c)\n\t\tc = next\n\t}\n\n\treturn result, nil\n}\n"
  },
  {
    "path": "internal/parser_test.go",
    "content": "package astro\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"github.com/withastro/compiler/internal/test_utils\"\n)\n\ntype ParserLocTest struct {\n\tname     string\n\tinput    string\n\texpected []int\n}\n\nfunc TestParserLocation(t *testing.T) {\n\tCases := []ParserLocTest{\n\t\t{\n\t\t\t\"end tag I\",\n\t\t\t`<div id=\"target\"></div>`,\n\t\t\t[]int{1, 19},\n\t\t},\n\t\t{\n\t\t\t\"end tag II\",\n\t\t\t`<div class=\"TabBox\">\n\t<div id=\"target\" class=\"tab-bar\">\n\t\t<div id=\"install-npm\" class=\"active toggle\"><h5>npm</h5></div>\n\t\t<div id=\"install-yarn\" class=\"toggle\"><h5>yarn</h5></div>\n\t</div>\n</div>`,\n\t\t\t[]int{23, 184},\n\t\t},\n\t\t{\n\t\t\t\"end tag III\",\n\t\t\t`<span id=\"target\" class:list={[\"link pixel variant\", className]} {style}>\n\t<a {href}>\n\t\t<span><slot /></span>\n\t</a>\n</span>\n`,\n\t\t\t[]int{1, 118},\n\t\t},\n\t\t{\n\t\t\t\"end tag VI\",\n\t\t\t`<HeadingWrapper id=\"target\">\n\t\t<h2 class=\"heading\"><UIString key=\"rightSidebar.community\" /></h2>\n\t\t{\n\t\t\thideOnLargerScreens && (\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"chevron\"\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\tviewBox=\"0 1 16 16\"\n\t\t\t\t\twidth=\"16\"\n\t\t\t\t\theight=\"16\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\tfill-rule=\"evenodd\"\n\t\t\t\t\t\td=\"M6.22 3.22a.75.75 0 011.06 0l4.25 4.25a.75.75 0 010 1.06l-4.25 4.25a.75.75 0 01-1.06-1.06L9.94 8 6.22 4.28a.75.75 0 010-1.06z\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t)\n\t\t}\n\t</HeadingWrapper>`,\n\t\t\t[]int{1, 492},\n\t\t},\n\t}\n\n\trunParserLocTest(t, Cases)\n}\n\nfunc runParserLocTest(t *testing.T, suite []ParserLocTest) {\n\tfor _, tt := range suite {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tcode := test_utils.Dedent(tt.input)\n\n\t\t\tdoc, err := Parse(strings.NewReader(code))\n\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\ttarget := findTargetNode(doc)\n\n\t\t\tlocs := make([]loc.Loc, 0)\n\t\t\tfor _, start := range tt.expected {\n\t\t\t\tlocs = append(locs, loc.Loc{Start: start})\n\t\t\t}\n\n\t\t\tif target == nil {\n\t\t\t\tt.Errorf(\"Loc = nil\\nExpected = %v\", locs)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif !reflect.DeepEqual(target.Loc, locs) {\n\t\t\t\tt.Errorf(\"Loc = %v\\nExpected = %v\", target.Loc, locs)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc walk(doc *Node, cb func(*Node)) {\n\tvar f func(*Node)\n\tf = func(n *Node) {\n\t\tcb(n)\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tf(c)\n\t\t}\n\t}\n\tf(doc)\n}\n\nfunc findTargetNode(doc *Node) *Node {\n\tvar target *Node = nil\n\twalk(doc, func(n *Node) {\n\t\tif target != nil {\n\t\t\treturn\n\t\t}\n\t\tfor _, attr := range n.Attr {\n\t\t\tif attr.Key == \"id\" && attr.Val == \"target\" {\n\t\t\t\ttarget = n\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t})\n\treturn target\n}\n"
  },
  {
    "path": "internal/print-to-source.go",
    "content": "package astro\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc PrintToSource(buf *strings.Builder, node *Node) {\n\tswitch node.Type {\n\tcase DocumentNode:\n\t\tfor c := node.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tPrintToSource(buf, c)\n\t\t}\n\tcase FrontmatterNode:\n\t\tif node.FirstChild != nil {\n\t\t\tbuf.WriteString(\"---\")\n\t\t\tfor c := node.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\tPrintToSource(buf, c)\n\t\t\t}\n\t\t\tbuf.WriteString(\"---\")\n\t\t}\n\tcase TextNode:\n\t\tbuf.WriteString(node.Data)\n\tcase ElementNode:\n\t\tisImplicit := false\n\t\tfor _, a := range node.Attr {\n\t\t\tif a.Key == ImplicitNodeMarker {\n\t\t\t\tisImplicit = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !isImplicit {\n\t\t\tif node.Expression {\n\t\t\t\tbuf.WriteString(\"{\")\n\t\t\t} else {\n\t\t\t\tbuf.WriteString(fmt.Sprintf(`<%s`, node.Data))\n\t\t\t}\n\t\t\tfor _, attr := range node.Attr {\n\t\t\t\tif attr.Key == ImplicitNodeMarker {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif attr.Namespace != \"\" {\n\t\t\t\t\tbuf.WriteString(attr.Namespace)\n\t\t\t\t\tbuf.WriteString(\":\")\n\t\t\t\t}\n\t\t\t\tbuf.WriteString(\" \")\n\t\t\t\tswitch attr.Type {\n\t\t\t\tcase QuotedAttribute:\n\t\t\t\t\tbuf.WriteString(attr.Key)\n\t\t\t\t\tbuf.WriteString(\"=\")\n\t\t\t\t\tbuf.WriteString(`\"` + attr.Val + `\"`)\n\t\t\t\tcase EmptyAttribute:\n\t\t\t\t\tbuf.WriteString(attr.Key)\n\t\t\t\tcase ExpressionAttribute:\n\t\t\t\t\tbuf.WriteString(attr.Key)\n\t\t\t\t\tbuf.WriteString(\"=\")\n\t\t\t\t\tbuf.WriteString(`{` + strings.TrimSpace(attr.Val) + `}`)\n\t\t\t\tcase SpreadAttribute:\n\t\t\t\t\tbuf.WriteString(`{...` + strings.TrimSpace(attr.Val) + `}`)\n\t\t\t\tcase ShorthandAttribute:\n\t\t\t\t\tbuf.WriteString(attr.Key)\n\t\t\t\t\tbuf.WriteString(\"=\")\n\t\t\t\t\tbuf.WriteString(`{` + strings.TrimSpace(attr.Key) + `}`)\n\t\t\t\tcase TemplateLiteralAttribute:\n\t\t\t\t\tbuf.WriteString(attr.Key)\n\t\t\t\t\tbuf.WriteString(\"=`\" + strings.TrimSpace(attr.Val) + \"`\")\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !node.Expression {\n\t\t\t\tbuf.WriteString(`>`)\n\t\t\t}\n\t\t}\n\t\tfor c := node.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tPrintToSource(buf, c)\n\t\t}\n\t\tif !isImplicit {\n\t\t\tif node.Expression {\n\t\t\t\tbuf.WriteString(\"}\")\n\t\t\t} else {\n\t\t\t\tbuf.WriteString(fmt.Sprintf(`</%s>`, node.Data))\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "internal/printer/__printer_css__/scopedStyleStrategy___attribute_.snap",
    "content": "\n[TestPrinterCSS/scopedStyleStrategy:_'attribute' - 1]\n## Input\n\n```\n<style>\n          .title {\n            font-family: fantasy;\n            font-size: 28px;\n          }\n\n          .body {\n            font-size: 1em;\n          }\n        </style>\n\n        <h1 class=\"title\">Page Title</h1>\n        <p class=\"body\">I’m a page</p>\n```\n\n## Output\n\n```css\n.title[data-astro-cid-dpohflym]{font-family:fantasy;font-size:28px}.body[data-astro-cid-dpohflym]{font-size:1em}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_css__/scopedStyleStrategy___class_.snap",
    "content": "\n[TestPrinterCSS/scopedStyleStrategy:_'class' - 1]\n## Input\n\n```\n<style>\n          .title {\n            font-family: fantasy;\n            font-size: 28px;\n          }\n\n          .body {\n            font-size: 1em;\n          }\n        </style>\n\n        <h1 class=\"title\">Page Title</h1>\n        <p class=\"body\">I’m a page</p>\n```\n\n## Output\n\n```css\n.title.astro-dpohflym{font-family:fantasy;font-size:28px}.body.astro-dpohflym{font-size:1em}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_css__/styles__no_frontmatter_.snap",
    "content": "\n[TestPrinterCSS/styles_(no_frontmatter) - 1]\n## Input\n\n```\n<style>\n          .title {\n            font-family: fantasy;\n            font-size: 28px;\n          }\n\n          .body {\n            font-size: 1em;\n          }\n        </style>\n\n        <h1 class=\"title\">Page Title</h1>\n        <p class=\"body\">I’m a page</p>\n```\n\n## Output\n\n```css\n.title:where(.astro-dpohflym){font-family:fantasy;font-size:28px}.body:where(.astro-dpohflym){font-size:1em}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/All_components.snap",
    "content": "\n[TestPrinter/All_components - 1]\n## Input\n\n```\n/-/-/-/\nimport { Container, Col, Row } from 'react-bootstrap';\n/-/-/-/\n<Container>\n    <Row>\n        <Col>\n            <h1>Hi!</h1>\n        </Col>\n    </Row>\n</Container>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport { Container, Col, Row } from 'react-bootstrap';\n\nimport * as $$module1 from 'react-bootstrap';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'react-bootstrap', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Container',Container,{},{\"default\": () => $$render`\n    ${$$renderComponent($$result,'Row',Row,{},{\"default\": () => $$render`\n        ${$$renderComponent($$result,'Col',Col,{},{\"default\": () => $$render`\n            ${$$maybeRenderHead($$result)}<h1>Hi!</h1>\n        `,})}\n    `,})}\n`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Component_is_raw.snap",
    "content": "\n[TestPrinter/Component_is:raw - 1]\n## Input\n\n```\n<Component is:raw>{<% awesome %>}</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`{<% awesome %>}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Component_names_A-Z.snap",
    "content": "\n[TestPrinter/Component_names_A-Z - 1]\n## Input\n\n```\n/-/-/-/\nimport AComponent from '../components/AComponent.jsx';\nimport ZComponent from '../components/ZComponent.jsx';\n/-/-/-/\n\n<body>\n  <AComponent />\n  <ZComponent />\n</body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport AComponent from '../components/AComponent.jsx';\nimport ZComponent from '../components/ZComponent.jsx';\n\nimport * as $$module1 from '../components/AComponent.jsx';\nimport * as $$module2 from '../components/ZComponent.jsx';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components/AComponent.jsx', assert: {} }, { module: $$module2, specifier: '../components/ZComponent.jsx', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>\n  ${$$renderComponent($$result,'AComponent',AComponent,{})}\n  ${$$renderComponent($$result,'ZComponent',ZComponent,{})}\n</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Component_siblings_are_siblings.snap",
    "content": "\n[TestPrinter/Component_siblings_are_siblings - 1]\n## Input\n\n```\n<BaseHead></BaseHead><link href=\"test\">\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'BaseHead',BaseHead,{})}<link href=\"test\">`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Component_with_await.snap",
    "content": "\n[TestPrinter/Component_with_await - 1]\n## Input\n\n```\n<body><Component> { await Promise.resolve(\"Awaited\") } </Component></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(async ($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Component',Component,{},{\"default\": async () => $$render`${ await Promise.resolve(\"Awaited\") }`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Empty_attribute_expression.snap",
    "content": "\n[TestPrinter/Empty_attribute_expression - 1]\n## Input\n\n```\n<body attr={}></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body${$$addAttribute((void 0), \"attr\")}></body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Empty_expression.snap",
    "content": "\n[TestPrinter/Empty_expression - 1]\n## Input\n\n```\n<body>({})</body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>(${(void 0)})</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Empty_expression_with_whitespace.snap",
    "content": "\n[TestPrinter/Empty_expression_with_whitespace - 1]\n## Input\n\n```\n<body>({   })</body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>(${(void 0)   })</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Empty_script.snap",
    "content": "\n[TestPrinter/Empty_script - 1]\n## Input\n\n```\n<script hoist></script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderScript($$result,\"?astro&type=script&index=0&lang.ts\")}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Empty_style.snap",
    "content": "\n[TestPrinter/Empty_style - 1]\n## Input\n\n```\n<style define:vars={{ color: \"Gainsboro\" }}></style>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{ color: \"Gainsboro\" }]);\nreturn $$render``;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Expression_in_form_followed_by_other_sibling_forms.snap",
    "content": "\n[TestPrinter/Expression_in_form_followed_by_other_sibling_forms - 1]\n## Input\n\n```\n<form><p>No expression here. So the next form will render.</p></form><form><h3>{data.formLabelA}</h3></form><form><h3>{data.formLabelB}</h3></form><form><p>No expression here, but the last form before me had an expression, so my form didn't render.</p></form><form><h3>{data.formLabelC}</h3></form><div><p>Here is some in-between content</p></div><form><h3>{data.formLabelD}</h3></form>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<form><p>No expression here. So the next form will render.</p></form><form><h3>${data.formLabelA}</h3></form><form><h3>${data.formLabelB}</h3></form><form><p>No expression here, but the last form before me had an expression, so my form didn't render.</p></form><form><h3>${data.formLabelC}</h3></form><div><p>Here is some in-between content</p></div><form><h3>${data.formLabelD}</h3></form>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment.snap",
    "content": "\n[TestPrinter/Fragment - 1]\n## Input\n\n```\n<body><Fragment><div>Default</div><div>Named</div></Fragment></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`<div>Default</div><div>Named</div>`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_literal_only.snap",
    "content": "\n[TestPrinter/Fragment_literal_only - 1]\n## Input\n\n```\n<Fragment>world</Fragment>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`world`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_shorthand.snap",
    "content": "\n[TestPrinter/Fragment_shorthand - 1]\n## Input\n\n```\n<body><><div>Default</div><div>Named</div></></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`<div>Default</div><div>Named</div>`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_shorthand_only.snap",
    "content": "\n[TestPrinter/Fragment_shorthand_only - 1]\n## Input\n\n```\n<>Hello</>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`Hello`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_shorthand_with_await.snap",
    "content": "\n[TestPrinter/Fragment_shorthand_with_await - 1]\n## Input\n\n```\n<body><> { await Promise.resolve(\"Awaited\") } </></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(async ($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": async () => $$render`${ await Promise.resolve(\"Awaited\") }`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_slotted.snap",
    "content": "\n[TestPrinter/Fragment_slotted - 1]\n## Input\n\n```\n<body><Component><><div>Default</div><div>Named</div></></Component></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`<div>Default</div><div>Named</div>`,})}`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_slotted_with_name.snap",
    "content": "\n[TestPrinter/Fragment_slotted_with_name - 1]\n## Input\n\n```\n<body><Component><Fragment slot=named><div>Default</div><div>Named</div></Fragment></Component></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Component',Component,{},{\"named\": () => $$render`${$$renderComponent($$result,'Fragment',Fragment,{\"slot\":\"named\"},{\"default\": () => $$render`<div>Default</div><div>Named</div>`,})}`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_with_await.snap",
    "content": "\n[TestPrinter/Fragment_with_await - 1]\n## Input\n\n```\n<body><Fragment> { await Promise.resolve(\"Awaited\") } </Fragment></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(async ($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": async () => $$render`${ await Promise.resolve(\"Awaited\") }`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Fragment_wrapping_link_with_awaited_href.snap",
    "content": "\n[TestPrinter/Fragment_wrapping_link_with_awaited_href - 1]\n## Input\n\n```\n<head><Fragment><link rel=\"preload\" href={(await import('../fonts/some-font.woff2')).default} as=\"font\" crossorigin /></Fragment></head>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(async ($$result, $$props, $$slots) => {\n\nreturn $$render`<head>${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": async () => $$render`<link rel=\"preload\"${$$addAttribute((await import('../fonts/some-font.woff2')).default, \"href\")} as=\"font\" crossorigin>`,})}${$$renderHead($$result)}</head>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/HTML_comment_in_component_inside_expression_I.snap",
    "content": "\n[TestPrinter/HTML_comment_in_component_inside_expression_I - 1]\n## Input\n\n```\n{(() => <Component><!--Hi--></Component>)}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${(() => $$render`${$$renderComponent($$result,'Component',Component,{},{})}`)}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/HTML_comment_in_component_inside_expression_II.snap",
    "content": "\n[TestPrinter/HTML_comment_in_component_inside_expression_II - 1]\n## Input\n\n```\n{list.map(() => <Component><!--Hi--></Component>)}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${list.map(() => $$render`${$$renderComponent($$result,'Component',Component,{},{})}`)}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Mixed_style_siblings.snap",
    "content": "\n[TestPrinter/Mixed_style_siblings - 1]\n## Input\n\n```\n<head>\n    <style is:global>div { color: red }</style>\n    <style is:scoped>div { color: green }</style>\n    <style>div { color: blue }</style>\n</head>\n<div />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<head>\n\n\n${$$renderHead($$result)}</head>\n<div class=\"astro-lasntlja\"></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Nested_HTML_in_expressions,_wrapped_in_parens.snap",
    "content": "\n[TestPrinter/Nested_HTML_in_expressions,_wrapped_in_parens - 1]\n## Input\n\n```\n/-/-/-/\nconst image = './penguin.png';\nconst canonicalURL = new URL('http://example.com');\n/-/-/-/\n{image && (<meta property=\"og:image\" content={new URL(image, canonicalURL)}>)}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst image = './penguin.png';\nconst canonicalURL = new URL('http://example.com');\n\nreturn $$render`${image && ($$render`<meta property=\"og:image\"${$$addAttribute(new URL(image, canonicalURL), \"content\")}>`)}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/No_extra_script_tag.snap",
    "content": "\n[TestPrinter/No_extra_script_tag - 1]\n## Input\n\n```\n<!-- Global Metadata -->\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width\">\n\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n<link rel=\"alternate icon\" type=\"image/x-icon\" href=\"/favicon.ico\" />\n\n<link rel=\"sitemap\" href=\"/sitemap.xml\"/>\n\n<!-- Global CSS -->\n<link rel=\"stylesheet\" href=\"/theme.css\" />\n<link rel=\"stylesheet\" href=\"/code.css\" />\n<link rel=\"stylesheet\" href=\"/index.css\" />\n\n<!-- Preload Fonts -->\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap\" rel=\"stylesheet\">\n\n<!-- Scrollable a11y code helper -->\n<script type=\"module\" src=\"/make-scrollable-code-focusable.js\" />\n\n<!-- This is intentionally inlined to avoid FOUC -->\n<script is:inline>\n  const root = document.documentElement;\n  const theme = localStorage.getItem('theme');\n  if (theme === 'dark' || (!theme) && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n    root.classList.add('theme-dark');\n  } else {\n    root.classList.remove('theme-dark');\n  }\n</script>\n\n<!-- Global site tag (gtag.js) - Google Analytics -->\n<!-- <script async src=\"https://www.googletagmanager.com/gtag/js?id=G-TEL60V1WM9\"></script>\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n  gtag('config', 'G-TEL60V1WM9');\n</script> -->\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<!-- Global Metadata --><meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width\">\n\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\">\n<link rel=\"alternate icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n\n<link rel=\"sitemap\" href=\"/sitemap.xml\">\n\n<!-- Global CSS -->\n<link rel=\"stylesheet\" href=\"/theme.css\">\n<link rel=\"stylesheet\" href=\"/code.css\">\n<link rel=\"stylesheet\" href=\"/index.css\">\n\n<!-- Preload Fonts -->\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap\" rel=\"stylesheet\">\n\n<!-- Scrollable a11y code helper -->\n<script type=\"module\" src=\"/make-scrollable-code-focusable.js\"></script>\n\n<!-- This is intentionally inlined to avoid FOUC -->\n<script>\n  const root = document.documentElement;\n  const theme = localStorage.getItem('theme');\n  if (theme === 'dark' || (!theme) && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n    root.classList.add('theme-dark');\n  } else {\n    root.classList.remove('theme-dark');\n  }\n</script>\n\n<!-- Global site tag (gtag.js) - Google Analytics -->\n<!-- <script async src=\"https://www.googletagmanager.com/gtag/js?id=G-TEL60V1WM9\"></script>\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n  gtag('config', 'G-TEL60V1WM9');\n</script> -->`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Parser_can_handle_files___4096_chars.snap",
    "content": "\n[TestPrinter/Parser_can_handle_files_>_4096_chars - 1]\n## Input\n\n```\n<html><body>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?<img\n  width=\"1600\"\n  height=\"1131\"\n  class=\"img\"\n  src=\"https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75\"\n  srcSet=\"https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 800w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 1200w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1600&q=75 1600w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=2400&q=75 2400w\"\n  sizes=\"(max-width: 800px) 800px, (max-width: 1200px) 1200px, (max-width: 1600px) 1600px, (max-width: 2400px) 2400px, 1200px\"\n>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>${$$maybeRenderHead($$result)}<body>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\",.?<img width=\"1600\" height=\"1131\" class=\"img\" src=\"https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75\" srcSet=\"https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 800w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 1200w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1600&q=75 1600w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=2400&q=75 2400w\" sizes=\"(max-width: 800px) 800px, (max-width: 1200px) 1200px, (max-width: 1600px) 1600px, (max-width: 2400px) 2400px, 1200px\"></body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_namespaces.snap",
    "content": "\n[TestPrinter/Preserve_namespaces - 1]\n## Input\n\n```\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect xlink:href=\"#id\"></svg>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect xlink:href=\"#id\"></rect></svg>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_namespaces_for_components.snap",
    "content": "\n[TestPrinter/Preserve_namespaces_for_components - 1]\n## Input\n\n```\n<Component some:thing=\"foobar\">\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{\"some:thing\":\"foobar\"})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_namespaces_in_expressions.snap",
    "content": "\n[TestPrinter/Preserve_namespaces_in_expressions - 1]\n## Input\n\n```\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect xlink:href={`#${iconId}`}></svg>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect ${$$addAttribute(`#${iconId}`, \"xlink:href\")}></rect></svg>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_slot_attribute_at_root_level_in_expression.snap",
    "content": "\n[TestPrinter/Preserve_slot_attribute_at_root_level_in_expression - 1]\n## Input\n\n```\n{!href ? <button slot={slotName}>Button</button> : <a href={href} slot={slotName}>Link</a>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${!href ? $$render`${$$maybeRenderHead($$result)}<button${$$addAttribute(slotName, \"slot\")}>Button</button>` : $$render`<a${$$addAttribute(href, \"href\")}${$$addAttribute(slotName, \"slot\")}>Link</a>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_slot_attribute_in_conditional_expression_for_custom_element.snap",
    "content": "\n[TestPrinter/Preserve_slot_attribute_in_conditional_expression_for_custom_element - 1]\n## Input\n\n```\n<body><my-element>{show && <div slot=\"content\">Content</div>}</my-element></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'my-element','my-element',{},{\"default\": () => $$render`${show && $$render`<div slot=\"content\">Content</div>`}`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_slot_attribute_in_expression_for_custom_element.snap",
    "content": "\n[TestPrinter/Preserve_slot_attribute_in_expression_for_custom_element - 1]\n## Input\n\n```\n<body><my-element>{!href ? <button slot={slotName}>Button</button> : <a href={href} slot={slotName}>Link</a>}</my-element></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'my-element','my-element',{},{\"default\": () => $$render`${!href ? $$render`<button${$$addAttribute(slotName, \"slot\")}>Button</button>` : $$render`<a${$$addAttribute(href, \"href\")}${$$addAttribute(slotName, \"slot\")}>Link</a>`}`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_slot_whitespace.snap",
    "content": "\n[TestPrinter/Preserve_slot_whitespace - 1]\n## Input\n\n```\n<Component>\n  <p>Paragraph 1</p>\n  <p>Paragraph 2</p>\n</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`\n  ${$$maybeRenderHead($$result)}<p>Paragraph 1</p>\n  <p>Paragraph 2</p>\n`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Preserve_slots_inside_custom-element.snap",
    "content": "\n[TestPrinter/Preserve_slots_inside_custom-element - 1]\n## Input\n\n```\n<body><my-element><div slot=name>Name</div><div>Default</div></my-element></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderComponent($$result,'my-element','my-element',{},{\"default\": () => $$render`<div slot=\"name\">Name</div><div>Default</div>`,})}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/React_framework_example.snap",
    "content": "\n[TestPrinter/React_framework_example - 1]\n## Input\n\n```\n/-/-/-/\n// Component Imports\nimport Counter from '../components/Counter.jsx'\nconst someProps = {\n  count: 0,\n}\n\n// Full Astro Component Syntax:\n// https://docs.astro.build/core-concepts/astro-components/\n/-/-/-/\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"width=device-width\"\n    />\n    <link rel=\"icon\" type=\"image/x-icon\" href=\"/favicon.ico\" />\n    <style>\n      :global(:root) {\n        font-family: system-ui;\n        padding: 2em 0;\n      }\n      :global(.counter) {\n        display: grid;\n        grid-template-columns: repeat(3, minmax(0, 1fr));\n        place-items: center;\n        font-size: 2em;\n        margin-top: 2em;\n      }\n      :global(.children) {\n        display: grid;\n        place-items: center;\n        margin-bottom: 2em;\n      }\n    </style>\n  </head>\n  <body>\n    <main>\n      <Counter {...someProps} client:visible>\n        <h1>Hello React!</h1>\n      </Counter>\n    </main>\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Counter from '../components/Counter.jsx'\n\n\nimport * as $$module1 from '../components/Counter.jsx';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components/Counter.jsx', assert: {} }], hydratedComponents: [Counter], clientOnlyComponents: [], hydrationDirectives: new Set(['visible']), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\n// Component Imports\n\nconst someProps = {\n  count: 0,\n}\n\n// Full Astro Component Syntax:\n// https://docs.astro.build/core-concepts/astro-components/\n\nreturn $$render`<html lang=\"en\" class=\"astro-hmnnhvcq\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width\">\n    <link rel=\"icon\" type=\"image/x-icon\" href=\"/favicon.ico\">\n  ${$$renderHead($$result)}</head>\n  <body class=\"astro-hmnnhvcq\">\n    <main class=\"astro-hmnnhvcq\">\n      ${$$renderComponent($$result,'Counter',Counter,{...(someProps),\"client:visible\":true,\"client:component-hydration\":\"visible\",\"client:component-path\":(\"../components/Counter.jsx\"),\"client:component-export\":(\"default\"),\"class\":\"astro-hmnnhvcq\"},{\"default\": () => $$render`\n        <h1 class=\"astro-hmnnhvcq\">Hello React!</h1>\n      `,})}\n    </main>\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/SVG_styles.snap",
    "content": "\n[TestPrinter/SVG_styles - 1]\n## Input\n\n```\n<svg><style>path { fill: red; }</style></svg>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<svg><style>path { fill: red; }</style></svg>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Self-closing_components_in_head_can_have_siblings.snap",
    "content": "\n[TestPrinter/Self-closing_components_in_head_can_have_siblings - 1]\n## Input\n\n```\n<html><head><BaseHead /><link href=\"test\"></head><html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html><head>${$$renderComponent($$result,'BaseHead',BaseHead,{})}<link href=\"test\">${$$renderHead($$result)}</head></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Self-closing_components_siblings_are_siblings.snap",
    "content": "\n[TestPrinter/Self-closing_components_siblings_are_siblings - 1]\n## Input\n\n```\n<BaseHead /><link href=\"test\">\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'BaseHead',BaseHead,{})}<link href=\"test\">`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Self-closing_formatting_elements.snap",
    "content": "\n[TestPrinter/Self-closing_formatting_elements - 1]\n## Input\n\n```\n<div id=\"1\"><div id=\"2\"><div id=\"3\"><i/><i/><i/></div></div></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div id=\"1\"><div id=\"2\"><div id=\"3\"><i></i><i></i><i></i></div></div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Self-closing_formatting_elements_2.snap",
    "content": "\n[TestPrinter/Self-closing_formatting_elements_2 - 1]\n## Input\n\n```\n<body>\n  <div id=\"1\"><div id=\"2\"><div id=\"3\"><i id=\"a\" /></div></div></div>\n  <div id=\"4\"><div id=\"5\"><div id=\"6\"><i id=\"b\" /></div></div></div>\n  <div id=\"7\"><div id=\"8\"><div id=\"9\"><i id=\"c\" /></div></div></div>\n</body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>\n  <div id=\"1\"><div id=\"2\"><div id=\"3\"><i id=\"a\"></i></div></div></div>\n  <div id=\"4\"><div id=\"5\"><div id=\"6\"><i id=\"b\"></i></div></div></div>\n  <div id=\"7\"><div id=\"8\"><div id=\"9\"><i id=\"c\"></i></div></div></div>\n</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Self-closing_script_in_head_works.snap",
    "content": "\n[TestPrinter/Self-closing_script_in_head_works - 1]\n## Input\n\n```\n<html><head><script is:inline /></head><html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html><head><script></script>${$$renderHead($$result)}</head></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Self-closing_title.snap",
    "content": "\n[TestPrinter/Self-closing_title - 1]\n## Input\n\n```\n<title />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<title></title>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Self-closing_title_II.snap",
    "content": "\n[TestPrinter/Self-closing_title_II - 1]\n## Input\n\n```\n<html><head><title /></head><body></body></html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html><head><title></title>${$$renderHead($$result)}</head><body></body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/Use_of_interfaces_within_frontmatter.snap",
    "content": "\n[TestPrinter/Use_of_interfaces_within_frontmatter - 1]\n## Input\n\n```\n/-/-/-/\ninterface MarkdownFrontmatter {\n    date: number;\n    image: string;\n    author: string;\n}\nlet allPosts = Astro.fetchContent<MarkdownFrontmatter>('./post/*.md');\n/-/-/-/\n<div>testing</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\ninterface MarkdownFrontmatter {\n    date: number;\n    image: string;\n    author: string;\n}\nlet allPosts = Astro.fetchContent<MarkdownFrontmatter>('./post/*.md');\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>testing</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/XElement.snap",
    "content": "\n[TestPrinter/XElement - 1]\n## Input\n\n```\n<XElement {...attrs}></XElement>{onLoadString ? <script data-something></script> : null }\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'XElement',XElement,{...(attrs)})}${onLoadString ? $$render`<script data-something></script>` : null }`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/_955_ternary_slot_with_elements.snap",
    "content": "\n[TestPrinter/#955_ternary_slot_with_elements - 1]\n## Input\n\n```\n<Component><div>{isLeaf ? <p>Leaf</p> : <p>Branch</p>}</div></Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${$$maybeRenderHead($$result)}<div>${isLeaf ? $$render`<p>Leaf</p>` : $$render`<p>Branch</p>`}</div>`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/_955_ternary_slot_with_text.snap",
    "content": "\n[TestPrinter/#955_ternary_slot_with_text - 1]\n## Input\n\n```\n<Component>Hello{isLeaf ? <p>Leaf</p> : <p>Branch</p>}world</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`Hello${isLeaf ? $$render`${$$maybeRenderHead($$result)}<p>Leaf</p>` : $$render`<p>Branch</p>`}world`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/advanced_svg_expression.snap",
    "content": "\n[TestPrinter/advanced_svg_expression - 1]\n## Input\n\n```\n/-/-/-/\nconst title = 'icon';\n/-/-/-/\n<svg>{title ? <title>{title}</title> : null}</svg>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst title = 'icon';\n\nreturn $$render`${$$maybeRenderHead($$result)}<svg>${title ? $$render`<title>${title}</title>` : null}</svg>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/anchor_content.snap",
    "content": "\n[TestPrinter/anchor_content - 1]\n## Input\n\n```\n<a><div><h3></h3><ul><li>{expr}</li></ul></div></a>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<a><div><h3></h3><ul><li>${expr}</li></ul></div></a>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/anchor_expressions.snap",
    "content": "\n[TestPrinter/anchor_expressions - 1]\n## Input\n\n```\n<a>{expr}</a>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<a>${expr}</a>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/anchor_inside_expression.snap",
    "content": "\n[TestPrinter/anchor_inside_expression - 1]\n## Input\n\n```\n{true && <a>expr</a>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${true && $$render`${$$maybeRenderHead($$result)}<a>expr</a>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/attribute_with_template_literal.snap",
    "content": "\n[TestPrinter/attribute_with_template_literal - 1]\n## Input\n\n```\n<a :href=\"`/home`\">Home</a>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<a :href=\"\\`/home\\`\">Home</a>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/attribute_with_template_literal_interpolation.snap",
    "content": "\n[TestPrinter/attribute_with_template_literal_interpolation - 1]\n## Input\n\n```\n<a :href=\"`/${url}`\">Home</a>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<a :href=\"\\`/\\${url}\\`\">Home</a>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/backtick_in_HTML_comment.snap",
    "content": "\n[TestPrinter/backtick_in_HTML_comment - 1]\n## Input\n\n```\n<body><!-- `npm install astro` --></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body><!-- \\`npm install astro\\` --></body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/basic__frontmatter_.snap",
    "content": "\n[TestPrinter/basic_(frontmatter) - 1]\n## Input\n\n```\n/-/-/-/\nconst href = '/about';\n/-/-/-/\n<a href={href}>About</a>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst href = '/about';\n\nreturn $$render`${$$maybeRenderHead($$result)}<a${$$addAttribute(href, \"href\")}>About</a>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/basic__no_frontmatter_.snap",
    "content": "\n[TestPrinter/basic_(no_frontmatter) - 1]\n## Input\n\n```\n<button>Click</button>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<button>Click</button>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/basic_renderHead.snap",
    "content": "\n[TestPrinter/basic_renderHead - 1]\n## Input\n\n```\n<html><head><title>Ah</title></head></html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html><head><title>Ah</title>${$$renderHead($$result)}</head></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/caption_only.snap",
    "content": "\n[TestPrinter/caption_only - 1]\n## Input\n\n```\n<caption>Hello world!</caption>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<caption>Hello world!</caption>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/class_and_class_list_object.snap",
    "content": "\n[TestPrinter/class_and_class_list_object - 1]\n## Input\n\n```\n<div class=\"two three\" class:list={['hello goodbye', { hello: true, world: true }]} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute(['two three', ['hello goodbye', { hello: true, world: true }]], \"class:list\")}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/class_and_class_list_set.snap",
    "content": "\n[TestPrinter/class_and_class_list_set - 1]\n## Input\n\n```\n<div class=\"two three\" class:list={[ new Set([{hello: true, world: true}]) ]} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute(['two three', [ new Set([{hello: true, world: true}]) ]], \"class:list\")}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/class_and_class_list_simple_array.snap",
    "content": "\n[TestPrinter/class_and_class_list_simple_array - 1]\n## Input\n\n```\n<div class=\"two\" class:list={['one', 'variable']} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute(['two', ['one', 'variable']], \"class:list\")}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/class_list.snap",
    "content": "\n[TestPrinter/class_list - 1]\n## Input\n\n```\n<div class:list={['one', 'variable']} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute(['one', 'variable'], \"class:list\")}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/class_list_with_spread.snap",
    "content": "\n[TestPrinter/class:list_with_spread - 1]\n## Input\n\n```\n<div class:list=\"something\" {...Astro.props} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$maybeRenderHead($$result)}<div class:list=\"something\"${$$spreadAttributes(Astro.props)}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/class_with_spread.snap",
    "content": "\n[TestPrinter/class_with_spread - 1]\n## Input\n\n```\n<div class=\"something\" {...Astro.props} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$maybeRenderHead($$result)}<div class=\"something\"${$$spreadAttributes(Astro.props)}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/client_only_component__default_.snap",
    "content": "\n[TestPrinter/client:only_component_(default) - 1]\n## Input\n\n```\n/-/-/-/\nimport Component from '../components';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <Component client:only />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Component from '../components';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'Component',null,{\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components\")),\"client:component-export\":\"default\"})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/client_only_component__multiple_.snap",
    "content": "\n[TestPrinter/client:only_component_(multiple) - 1]\n## Input\n\n```\n/-/-/-/\nimport Component from '../components';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <Component test=\"a\" client:only />\n    <Component test=\"b\" client:only />\n    <Component test=\"c\" client:only />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Component from '../components';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'Component',null,{\"test\":\"a\",\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components\")),\"client:component-export\":\"default\"})}\n    ${$$renderComponent($$result,'Component',null,{\"test\":\"b\",\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components\")),\"client:component-export\":\"default\"})}\n    ${$$renderComponent($$result,'Component',null,{\"test\":\"c\",\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components\")),\"client:component-export\":\"default\"})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/client_only_component__named_.snap",
    "content": "\n[TestPrinter/client:only_component_(named) - 1]\n## Input\n\n```\n/-/-/-/\nimport { Component } from '../components';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <Component client:only />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport { Component } from '../components';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'Component',null,{\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components\")),\"client:component-export\":\"Component\"})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/client_only_component__namespace_.snap",
    "content": "\n[TestPrinter/client:only_component_(namespace) - 1]\n## Input\n\n```\n/-/-/-/\nimport * as components from '../components';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <components.A client:only />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport * as components from '../components';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components'], hydrationDirectives: new Set(['only']), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'components.A',null,{\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components\")),\"client:component-export\":\"A\"})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/client_only_component__namespaced_default_.snap",
    "content": "\n[TestPrinter/client:only_component_(namespaced_default) - 1]\n## Input\n\n```\n/-/-/-/\nimport defaultImport from '../components/ui-1';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <defaultImport.Counter1 client:only />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport defaultImport from '../components/ui-1';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components/ui-1'], hydrationDirectives: new Set(['only']), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'defaultImport.Counter1',null,{\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components/ui-1\")),\"client:component-export\":\"default.Counter1\"})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/client_only_component__namespaced_named_.snap",
    "content": "\n[TestPrinter/client:only_component_(namespaced_named) - 1]\n## Input\n\n```\n/-/-/-/\nimport { namedImport } from '../components/ui-2';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <namedImport.Counter2 client:only />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport { namedImport } from '../components/ui-2';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: ['../components/ui-2'], hydrationDirectives: new Set(['only']), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'namedImport.Counter2',null,{\"client:only\":true,\"client:component-hydration\":\"only\",\"client:component-path\":($$metadata.resolvePath(\"../components/ui-2\")),\"client:component-export\":\"namedImport.Counter2\"})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/comment_only_expressions_are_removed_I.snap",
    "content": "\n[TestPrinter/comment_only_expressions_are_removed_I - 1]\n## Input\n\n```\n{/* a comment 1 */}<h1>{/* a comment 2*/}Hello</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<h1>Hello</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/comment_only_expressions_are_removed_II.snap",
    "content": "\n[TestPrinter/comment_only_expressions_are_removed_II - 1]\n## Input\n\n```\n{\n    list.map((i) => (\n        <Component>\n            {\n                // hello\n            }\n        </Component>\n    ))\n}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${\n    list.map((i) => (\n        $$render`${$$renderComponent($$result,'Component',Component,{},{})}`\n    ))\n}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/comment_only_expressions_are_removed_III.snap",
    "content": "\n[TestPrinter/comment_only_expressions_are_removed_III - 1]\n## Input\n\n```\n{\n    list.map((i) => (\n        <Component>\n            {\n                /* hello */\n            }\n        </Component>\n    ))\n}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${\n    list.map((i) => (\n        $$render`${$$renderComponent($$result,'Component',Component,{},{})}`\n    ))\n}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/comments_removed_from_attribute_list.snap",
    "content": "\n[TestPrinter/comments_removed_from_attribute_list - 1]\n## Input\n\n```\n<div><h1 {/* comment 1 */} value=\"1\" {/* comment 2 */}>Hello</h1><Component {/* comment 1 */} value=\"1\" {/* comment 2 */} /></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div><h1 value=\"1\">Hello</h1>${$$renderComponent($$result,'Component',Component,{\"value\":\"1\",})}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/complex_nested_template_literal_expression.snap",
    "content": "\n[TestPrinter/complex_nested_template_literal_expression - 1]\n## Input\n\n```\n<div value={`${attr ? `a/b ${`c ${`d ${cool}`}`}` : \"d\"} ahhhh`} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute(`${attr ? `a/b ${`c ${`d ${cool}`}`}` : \"d\"} ahhhh`, \"value\")}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/complex_recursive_component.snap",
    "content": "\n[TestPrinter/complex_recursive_component - 1]\n## Input\n\n```\n{(<Fragment><Fragment set:html={`<${Node.tag} ${stringifyAttributes(Node.attributes)}>`} />{Node.children.map((child) => (<Astro.self node={child} />))}<Fragment set:html={`</${Node.tag}>`} /></Fragment>)}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/components/RenderNode.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$RenderNode = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$RenderNode;\n\nreturn $$render`${($$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${$$unescapeHTML(`<${Node.tag} ${stringifyAttributes(Node.attributes)}>`)}`,})}${Node.children.map((child) => ($$render`${$$renderComponent($$result,'Astro.self',Astro.self,{\"node\":(child)})}`))}${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${$$unescapeHTML(`</${Node.tag}>`)}`,})}`,})}`)}`;\n}, '/projects/app/src/components/RenderNode.astro', undefined);\nexport default $$RenderNode;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/complex_table.snap",
    "content": "\n[TestPrinter/complex_table - 1]\n## Input\n\n```\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"viewport\" content=\"width=device-width\" />\n        <title>Astro Multi Table</title>\n    </head>\n    <body>\n        <main>\n            <section>\n                {Array(3).fill(false).map((item, idx) => <div>\n                    <div class=\"row\">\n                        {'a'}\n                        <table>\n                            <thead>\n                                <tr>\n                                    <>{Array(7).fill(false).map((entry, index) => <th>A</th>)}</>\n                                </tr>\n                            </thead>\n                            <tbody>\n                                <tr><td></td></tr>\n                            </tbody>\n                        </table>\n                    </div>\n                </div>)}\n            </section>\n            <section>\n                <div class=\"row\">\n                    <table>\n                        <thead>\n                            <tr>\n                                <th>B</th>\n                                <th>B</th>\n                                <th>B</th>\n                            </tr>\n                        </thead>\n                        <tbody>\n                            <tr><td></td></tr>\n                        </tbody>\n                    </table>\n                </div>\n            </section>\n        </main>\n    </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <meta name=\"viewport\" content=\"width=device-width\">\n        <title>Astro Multi Table</title>\n    ${$$renderHead($$result)}</head>\n    <body>\n        <main>\n            <section>\n                ${Array(3).fill(false).map((item, idx) => $$render`<div>\n                    <div class=\"row\">\n                        ${'a'}\n                        <table>\n                            <thead>\n                                <tr>\n                                    ${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${Array(7).fill(false).map((entry, index) => $$render`<th>A</th>`)}`,})}\n                                </tr>\n                            </thead>\n                            <tbody>\n                                <tr><td></td></tr>\n                            </tbody>\n                        </table>\n                    </div>\n                </div>`)}\n            </section>\n            <section>\n                <div class=\"row\">\n                    <table>\n                        <thead>\n                            <tr>\n                                <th>B</th>\n                                <th>B</th>\n                                <th>B</th>\n                            </tr>\n                        </thead>\n                        <tbody>\n                            <tr><td></td></tr>\n                        </tbody>\n                    </table>\n                </div>\n            </section>\n        </main>\n    </body>\n</html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/component.snap",
    "content": "\n[TestPrinter/component - 1]\n## Input\n\n```\n/-/-/-/\nimport VueComponent from '../components/Vue.vue';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <VueComponent />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport VueComponent from '../components/Vue.vue';\n\nimport * as $$module1 from '../components/Vue.vue';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components/Vue.vue', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'VueComponent',VueComponent,{})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/component_in_expression_with_its_child_expression_before_its_child_element.snap",
    "content": "\n[TestPrinter/component_in_expression_with_its_child_expression_before_its_child_element - 1]\n## Input\n\n```\n{list.map(() => (<Component>{name}<link rel=\"stylesheet\" /></Component>))}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${list.map(() => ($$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${name}<link rel=\"stylesheet\">`,})}`))}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/component_with_only_a_script.snap",
    "content": "\n[TestPrinter/component_with_only_a_script - 1]\n## Input\n\n```\n<script>console.log('hello world');</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log('hello world');` }] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderScript($$result,\"?astro&type=script&index=0&lang.ts\")}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/component_with_quoted_attributes.snap",
    "content": "\n[TestPrinter/component_with_quoted_attributes - 1]\n## Input\n\n```\n<Component is='\"cool\"' />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{\"is\":\"\\\"cool\\\"\"})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/condition_expressions_at_the_top-level.snap",
    "content": "\n[TestPrinter/condition_expressions_at_the_top-level - 1]\n## Input\n\n```\n{cond && <span></span>}{cond && <strong></strong>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${cond && $$render`${$$maybeRenderHead($$result)}<span></span>`}${cond && $$render`<strong></strong>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/condition_expressions_at_the_top-level_with_head_content.snap",
    "content": "\n[TestPrinter/condition_expressions_at_the_top-level_with_head_content - 1]\n## Input\n\n```\n{cond && <meta charset=utf8>}{cond && <title>My title</title>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${cond && $$render`<meta charset=\"utf8\">`}${cond && $$render`<title>My title</title>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/conditional_iframe.snap",
    "content": "\n[TestPrinter/conditional_iframe - 1]\n## Input\n\n```\n{bool && <iframe src=\"something\">content</iframe>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${bool && $$render`${$$maybeRenderHead($$result)}<iframe src=\"something\">content</iframe>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/conditional_noscript.snap",
    "content": "\n[TestPrinter/conditional_noscript - 1]\n## Input\n\n```\n{mode === \"production\" && <noscript>Hello</noscript>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${mode === \"production\" && $$render`${$$maybeRenderHead($$result)}<noscript>Hello</noscript>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/conditional_render.snap",
    "content": "\n[TestPrinter/conditional_render - 1]\n## Input\n\n```\n<body>{false ? <div>#f</div> : <div>#t</div>}</body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${false ? $$render`<div>#f</div>` : $$render`<div>#t</div>`}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/conditional_rendering_of_title_containing_expression.snap",
    "content": "\n[TestPrinter/conditional_rendering_of_title_containing_expression - 1]\n## Input\n\n```\n{\n  props.title && (\n    <>\n      <title>{props.title}</title>\n      <meta property=\"og:title\" content={props.title} />\n      <meta name=\"twitter:title\" content={props.title} />\n    </>\n  )\n}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${\n  props.title && (\n    $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`\n      <title>${props.title}</title>\n      <meta property=\"og:title\"${$$addAttribute(props.title, \"content\")}>\n      <meta name=\"twitter:title\"${$$addAttribute(props.title, \"content\")}>\n    `,})}`\n  )\n}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/conditional_slot.snap",
    "content": "\n[TestPrinter/conditional_slot - 1]\n## Input\n\n```\n<Component>{value && <div slot=\"test\">foo</div>}</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"test\": () => $$render`${value && $$render`${$$maybeRenderHead($$result)}<div>foo</div>`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/css_comment_doesn’t_produce_semicolon.snap",
    "content": "\n[TestPrinter/css_comment_doesn’t_produce_semicolon - 1]\n## Input\n\n```\n<style>/* comment */.container {\n    padding: 2rem;\n    }\n</style><div class=\"container\">My Text</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div class=\"container astro-sj3wye6h\">My Text</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/css_imports_are_not_included_in_module_metadata.snap",
    "content": "\n[TestPrinter/css_imports_are_not_included_in_module_metadata - 1]\n## Input\n\n```\n/-/-/-/\n            import './styles.css';\n            ---\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport './styles.css';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render``;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/custom-element.snap",
    "content": "\n[TestPrinter/custom-element - 1]\n## Input\n\n```\n{show && <client-only-element></client-only-element>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${show && $$render`${$$renderComponent($$result,'client-only-element','client-only-element',{})}`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/custom_elements.snap",
    "content": "\n[TestPrinter/custom_elements - 1]\n## Input\n\n```\n/-/-/-/\nimport 'test';\n/-/-/-/\n<my-element></my-element>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport 'test';\n\nimport * as $$module1 from 'test';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'my-element','my-element',{})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_a_module_script_with_imports.snap",
    "content": "\n[TestPrinter/define:vars_on_a_module_script_with_imports - 1]\n## Input\n\n```\n<script type=\"module\" define:vars={{foo:'bar'}}>import 'foo';\\nvar three = foo;</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script type=\"module\">${$$defineScriptVars({foo:'bar'})}import 'foo';\\\\nvar three = foo;</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_non-root_elements.snap",
    "content": "\n[TestPrinter/define:vars_on_non-root_elements - 1]\n## Input\n\n```\n<style define:vars={{color:'green'}}>h1{color:var(--color)}</style>{true ? <h1>foo</h1> : <h1>bar</h1>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'}]);\nreturn $$render`${true ? $$render`${$$maybeRenderHead($$result)}<h1 class=\"astro-34ao5s3b\"${$$addAttribute($$definedVars, \"style\")}>foo</h1>` : $$render`<h1 class=\"astro-34ao5s3b\"${$$addAttribute($$definedVars, \"style\")}>bar</h1>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_script_with_StaticExpression_turned_on.snap",
    "content": "\n[TestPrinter/define:vars_on_script_with_StaticExpression_turned_on - 1]\n## Input\n\n```\n<script is:inline>var one = 'one';</script><script>var two = 'two';</script><script define:vars={{foo:'bar'}}>var three = foo;</script><script is:inline define:vars={{foo:'bar'}}>var four = foo;</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `var two = 'two';` }] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script>var one = 'one';</script>${$$renderScript($$result,\"?astro&type=script&index=0&lang.ts\")}<script>(function(){${$$defineScriptVars({foo:'bar'})}var three = foo;})();</script><script>(function(){${$$defineScriptVars({foo:'bar'})}var four = foo;})();</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_style.snap",
    "content": "\n[TestPrinter/define:vars_on_style - 1]\n## Input\n\n```\n<style>h1{color:green;}</style><style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1>testing</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'}]);\nreturn $$render`${$$maybeRenderHead($$result)}<h1 class=\"astro-vfs5oemv\"${$$addAttribute($$definedVars, \"style\")}>testing</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_style_tag_with_style_empty_attribute_on_element.snap",
    "content": "\n[TestPrinter/define:vars_on_style_tag_with_style_empty_attribute_on_element - 1]\n## Input\n\n```\n<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style>testing</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'}]);\nreturn $$render`${$$maybeRenderHead($$result)}<h1${$$addAttribute($$definedVars, \"style\")} class=\"astro-yvzw3g7h\">testing</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_style_tag_with_style_expression_attribute_on_element.snap",
    "content": "\n[TestPrinter/define:vars_on_style_tag_with_style_expression_attribute_on_element - 1]\n## Input\n\n```\n<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style={myStyles}>testing</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'}]);\nreturn $$render`${$$maybeRenderHead($$result)}<h1${$$addAttribute(`${myStyles}; ${$$definedVars}`, \"style\")} class=\"astro-zwheddu6\">testing</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_style_tag_with_style_quoted_attribute_on_element.snap",
    "content": "\n[TestPrinter/define:vars_on_style_tag_with_style_quoted_attribute_on_element - 1]\n## Input\n\n```\n<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style='color: yellow;'>testing</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'}]);\nreturn $$render`${$$maybeRenderHead($$result)}<h1${$$addAttribute(`${\"color: yellow;\"}; ${$$definedVars}`, \"style\")} class=\"astro-rrt5rq2h\">testing</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_style_tag_with_style_shorthand_attribute_on_element.snap",
    "content": "\n[TestPrinter/define:vars_on_style_tag_with_style_shorthand_attribute_on_element - 1]\n## Input\n\n```\n<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 {style}>testing</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'}]);\nreturn $$render`${$$maybeRenderHead($$result)}<h1${$$addAttribute(`${style}; ${$$definedVars}`, \"style\")} class=\"astro-yiefzsdv\">testing</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/define_vars_on_style_tag_with_style_template_literal_attribute_on_element.snap",
    "content": "\n[TestPrinter/define:vars_on_style_tag_with_style_template_literal_attribute_on_element - 1]\n## Input\n\n```\n<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style=`color: ${color};`>testing</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'}]);\nreturn $$render`${$$maybeRenderHead($$result)}<h1${$$addAttribute(`${`color: ${color};`}; ${$$definedVars}`, \"style\")} class=\"astro-33xvgaes\">testing</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/division_inside_expression.snap",
    "content": "\n[TestPrinter/division_inside_expression - 1]\n## Input\n\n```\n<div>{16 / 4}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${16 / 4}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/doctype.snap",
    "content": "\n[TestPrinter/doctype - 1]\n## Input\n\n```\n<!DOCTYPE html><div/>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/dot_component.snap",
    "content": "\n[TestPrinter/dot_component - 1]\n## Input\n\n```\n/-/-/-/\nimport * as ns from '../components';\n/-/-/-/\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <ns.Component />\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport * as ns from '../components';\n\nimport * as $$module1 from '../components';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>\n    <title>Hello world</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    ${$$renderComponent($$result,'ns.Component',ns.Component,{})}\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/dynamic_import.snap",
    "content": "\n[TestPrinter/dynamic_import - 1]\n## Input\n\n```\n/-/-/-/\nconst markdownDocs = await Astro.glob('../markdown/*.md')\nconst article2 = await import('../markdown/article2.md')\n/-/-/-/\n<div />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(async ($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nconst markdownDocs = await Astro.glob('../markdown/*.md')\nconst article2 = await import('../markdown/article2.md')\n\nreturn $$render`${$$maybeRenderHead($$result)}<div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/escaped_entity.snap",
    "content": "\n[TestPrinter/escaped_entity - 1]\n## Input\n\n```\n<img alt=\"A person saying &#x22;hello&#x22;\">\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<img alt=\"A person saying &quot;hello&quot;\">`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/export_comments_I.snap",
    "content": "\n[TestPrinter/export_comments_I - 1]\n## Input\n\n```\n/-/-/-/\n// hmm\nexport const foo = 0\n/*\n*/\n/-/-/-/\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nexport const foo = 0\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\n// hmm\n/*\n*/\n\nreturn $$render``;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/export_comments_II.snap",
    "content": "\n[TestPrinter/export_comments_II - 1]\n## Input\n\n```\n/-/-/-/\n// hmm\nexport const foo = 0;\n/*\n*/\n/-/-/-/\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nexport const foo = 0;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\n// hmm\n\n/*\n*/\n\nreturn $$render``;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/export_member_does_not_panic.snap",
    "content": "\n[TestPrinter/export_member_does_not_panic - 1]\n## Input\n\n```\n/-/-/-/\nmod.export();\n/-/-/-/\n<div />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nmod.export();\n\nreturn $$render`${$$maybeRenderHead($$result)}<div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/expression_returning_multiple_elements.snap",
    "content": "\n[TestPrinter/expression_returning_multiple_elements - 1]\n## Input\n\n```\n<Layout title=\"Welcome to Astro.\">\n    <main>\n        <h1>Welcome to <span class=\"text-gradient\">Astro</span></h1>\n        {\n            Object.entries(DUMMY_DATA).map(([dummyKey, dummyValue]) => {\n                return (\n                    <p>\n                        onlyp {dummyKey}\n                    </p>\n                    <h2>\n                        onlyh2 {dummyKey}\n                    </h2>\n                    <div>\n                        <h2>div+h2 {dummyKey}</h2>\n                    </div>\n                    <p>\n                        <h2>p+h2 {dummyKey}</h2>\n                    </p>\n                );\n            })\n        }\n    </main>\n</Layout>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$renderComponent($$result,'Layout',Layout,{\"title\":\"Welcome to Astro.\"},{\"default\": () => $$render`\n    ${$$maybeRenderHead($$result)}<main>\n        <h1>Welcome to <span class=\"text-gradient\">Astro</span></h1>\n        ${\n            Object.entries(DUMMY_DATA).map(([dummyKey, dummyValue]) => {\n                return (\n                    $$render`<p>\n                        onlyp ${dummyKey}\n                    </p>\n                    <h2>\n                        onlyh2 ${dummyKey}\n                    </h2>\n                    <div>\n                        <h2>div+h2 ${dummyKey}</h2>\n                    </div>\n                    <p>\n                        </p><h2>p+h2 ${dummyKey}</h2>\n                    `\n                );\n            })\n        }\n    </main>\n`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/expression_slot.snap",
    "content": "\n[TestPrinter/expression_slot - 1]\n## Input\n\n```\n<Component>{true && <div slot=\"a\">A</div>}{false && <div slot=\"b\">B</div>}</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"a\": () => $$render`${true && $$render`${$$maybeRenderHead($$result)}<div>A</div>`}`,\"b\": () => $$render`${false && $$render`<div>B</div>`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/expression_with_leading_whitespace.snap",
    "content": "\n[TestPrinter/expression_with_leading_whitespace - 1]\n## Input\n\n```\n<section>\n<ul class=\"font-mono text-sm flex flex-col gap-0.5\">\n    {\n        <li>Build: { new Date().toISOString() }</li>\n        <li>NODE_VERSION: { process.env.NODE_VERSION }</li>\n    }\n</ul>\n</section>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<section>\n<ul class=\"font-mono text-sm flex flex-col gap-0.5\">\n    ${\n        $$render`<li>Build: ${ new Date().toISOString() }</li>\n        <li>NODE_VERSION: ${ process.env.NODE_VERSION }</li>`\n    }\n</ul>\n</section>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/expressions_with_JS_comments.snap",
    "content": "\n[TestPrinter/expressions_with_JS_comments - 1]\n## Input\n\n```\n/-/-/-/\nconst items = ['red', 'yellow', 'blue'];\n/-/-/-/\n<div>\n  {items.map((item) => (\n    // foo < > < }\n    <div id={color}>color</div>\n  ))}\n  {items.map((item) => (\n    /* foo < > < } */ <div id={color}>color</div>\n  ))}\n</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst items = ['red', 'yellow', 'blue'];\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>\n  ${items.map((item) => (\n    // foo < > < }\n    $$render`<div${$$addAttribute(color, \"id\")}>color</div>`\n  ))}\n  ${items.map((item) => (\n    /* foo < > < } */ $$render`<div${$$addAttribute(color, \"id\")}>color</div>`\n  ))}\n</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/expressions_with_multiple_curly_braces.snap",
    "content": "\n[TestPrinter/expressions_with_multiple_curly_braces - 1]\n## Input\n\n```\n<div>\n{\n    () => {\n        let generate = (input) => {\n            let a = () => { return; };\n            let b = () => { return; };\n            let c = () => { return; };\n        };\n    }\n}\n</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>\n${\n    () => {\n        let generate = (input) => {\n            let a = () => { return; };\n            let b = () => { return; };\n            let c = () => { return; };\n        };\n    }\n}\n</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/function_expression_slots_I.snap",
    "content": "\n[TestPrinter/function_expression_slots_I - 1]\n## Input\n\n```\n<Component>\n{() => { switch (value) {\ncase 'a': return <div slot=\"a\">A</div>\ncase 'b': return <div slot=\"b\">B</div>\ncase 'c': return <div slot=\"c\">C</div>\n}\n}}\n</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},$$mergeSlots({},() => { switch (value) {\ncase 'a': return {\"a\": () => $$render`${$$maybeRenderHead($$result)}<div>A</div>`}\ncase 'b': return {\"b\": () => $$render`<div>B</div>`}\ncase 'c': return {\"c\": () => $$render`<div>C</div>`}\n}\n}))}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/function_expression_slots_II___959_.snap",
    "content": "\n[TestPrinter/function_expression_slots_II_(#959) - 1]\n## Input\n\n```\n<Layout title=\"Welcome to Astro.\">\n    <main>\n        <Layout title=\"switch bug\">\n            {components.map((component, i) => {\n                switch(component) {\n                    case \"Hero\":\n                        return <div>Hero</div>\n                    case \"Component2\":\n                        return <div>Component2</div>\n                }\n            })}\n        </Layout>\n    </main>\n</Layout>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$renderComponent($$result,'Layout',Layout,{\"title\":\"Welcome to Astro.\"},{\"default\": () => $$render`\n    ${$$maybeRenderHead($$result)}<main>\n        ${$$renderComponent($$result,'Layout',Layout,{\"title\":\"switch bug\"},{\"default\": () => $$render`${components.map((component, i) => {\n                switch(component) {\n                    case \"Hero\":\n                        return $$render`<div>Hero</div>`\n                    case \"Component2\":\n                        return $$render`<div>Component2</div>`\n                }\n            })}`,})}\n    </main>\n`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/getStaticPaths__basic_.snap",
    "content": "\n[TestPrinter/getStaticPaths_(basic) - 1]\n## Input\n\n```\n/-/-/-/\nexport const getStaticPaths = async () => {\n    return { paths: [] }\n}\n/-/-/-/\n<div></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nexport const getStaticPaths = async () => {\n    return { paths: [] }\n}\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/getStaticPaths__hoisted_.snap",
    "content": "\n[TestPrinter/getStaticPaths_(hoisted) - 1]\n## Input\n\n```\n/-/-/-/\nconst a = 0;\nexport const getStaticPaths = async () => {\n    return { paths: [] }\n}\n/-/-/-/\n<div></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nexport const getStaticPaths = async () => {\n    return { paths: [] }\n}\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst a = 0;\n\nreturn $$render`${$$maybeRenderHead($$result)}<div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/getStaticPaths__hoisted_II_.snap",
    "content": "\n[TestPrinter/getStaticPaths_(hoisted_II) - 1]\n## Input\n\n```\n/-/-/-/\nconst a = 0;\nexport async function getStaticPaths() {\n    return { paths: [] }\n}\nconst b = 0;\n/-/-/-/\n<div></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nexport async function getStaticPaths() {\n    return { paths: [] }\n}\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst a = 0;\n\nconst b = 0;\n\nreturn $$render`${$$maybeRenderHead($$result)}<div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/gets_all_potential_hydrated_components.snap",
    "content": "\n[TestPrinter/gets_all_potential_hydrated_components - 1]\n## Input\n\n```\n/-/-/-/\nimport One from 'one';\nimport Two from 'two';\nimport 'custom-element';\nconst name = 'world';\n/-/-/-/\n<One client:load />\n<Two client:load />\n<my-element client:load />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport One from 'one';\nimport Two from 'two';\nimport 'custom-element';\n\nimport * as $$module1 from 'one';\nimport * as $$module2 from 'two';\nimport * as $$module3 from 'custom-element';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'one', assert: {} }, { module: $$module2, specifier: 'two', assert: {} }, { module: $$module3, specifier: 'custom-element', assert: {} }], hydratedComponents: ['my-element', Two, One], clientOnlyComponents: [], hydrationDirectives: new Set(['load']), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst name = 'world';\n\nreturn $$render`${$$renderComponent($$result,'One',One,{\"client:load\":true,\"client:component-hydration\":\"load\",\"client:component-path\":(\"one\"),\"client:component-export\":(\"default\")})}\n${$$renderComponent($$result,'Two',Two,{\"client:load\":true,\"client:component-hydration\":\"load\",\"client:component-path\":(\"two\"),\"client:component-export\":(\"default\")})}\n${$$renderComponent($$result,'my-element','my-element',{\"client:load\":true,\"client:component-hydration\":\"load\"})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/head_content_with_component_first.snap",
    "content": "\n[TestPrinter/head_content_with_component_first - 1]\n## Input\n\n```\n/-/-/-/\nimport Analytics from '../components/Analytics.astro';\n/-/-/-/\n<Analytics />\n<title>{title}</title>\n<meta name=\"description\" content=\"a description\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Analytics from '../components/Analytics.astro';\n\nimport * as $$module1 from '../components/Analytics.astro';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components/Analytics.astro', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Analytics',Analytics,{})}\n<title>${title}</title>\n<meta name=\"description\" content=\"a description\">`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/head_expression.snap",
    "content": "\n[TestPrinter/head_expression - 1]\n## Input\n\n```\n/-/-/-/\nconst name = \"world\";\n/-/-/-/\n<html>\n  <head>\n    <title>Hello {name}</title>\n  </head>\n  <body>\n    <div></div>\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst name = \"world\";\n\nreturn $$render`<html>\n  <head>\n    <title>Hello ${name}</title>\n  ${$$renderHead($$result)}</head>\n  <body>\n    <div></div>\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/head_expression_and_conditional_rendering_of_fragment.snap",
    "content": "\n[TestPrinter/head_expression_and_conditional_rendering_of_fragment - 1]\n## Input\n\n```\n/-/-/-/\nconst testBool = true;\n/-/-/-/\n<html>\n    <head>\n        <meta charset=\"UTF-8\" />\n        <title>{testBool ? \"Hey\" : \"Bye\"}</title>\n        {testBool && (<><meta name=\"description\" content=\"test\" /></>)}\n    </head>\n    <body>\n      <div></div>\n    </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst testBool = true;\n\nreturn $$render`<html>\n    <head>\n        <meta charset=\"UTF-8\">\n        <title>${testBool ? \"Hey\" : \"Bye\"}</title>\n        ${testBool && ($$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`<meta name=\"description\" content=\"test\">`,})}`)}\n    ${$$renderHead($$result)}</head>\n    <body>\n      <div></div>\n    </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/head_inside_slot.snap",
    "content": "\n[TestPrinter/head_inside_slot - 1]\n## Input\n\n```\n<html><slot><head></head></slot></html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>${$$renderSlot($$result,$$slots[\"default\"],$$render`<head>${$$renderHead($$result)}</head>`)}</html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/head_slot.snap",
    "content": "\n[TestPrinter/head_slot - 1]\n## Input\n\n```\n<html><head><slot /></html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html><head>${$$renderSlot($$result,$$slots[\"default\"])}${$$renderHead($$result)}</head></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/head_slot_II.snap",
    "content": "\n[TestPrinter/head_slot_II - 1]\n## Input\n\n```\n<html><head><slot /></head><body class=\"a\"></body></html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html><head>${$$renderSlot($$result,$$slots[\"default\"])}${$$renderHead($$result)}</head><body class=\"a\"></body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/head_slot_III.snap",
    "content": "\n[TestPrinter/head_slot_III - 1]\n## Input\n\n```\n<html><head><slot name=\"baseHeadExtension\"><meta property=\"test2\" content=\"test2\"/></slot></head>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html><head>${$$renderSlot($$result,$$slots[\"baseHeadExtension\"],$$render`<meta property=\"test2\" content=\"test2\">`)}${$$renderHead($$result)}</head></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/html5_boilerplate.snap",
    "content": "\n[TestPrinter/html5_boilerplate - 1]\n## Input\n\n```\n<!doctype html>\n\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n  <title>A Basic HTML5 Template</title>\n  <meta name=\"description\" content=\"A simple HTML5 Template for new projects.\">\n  <meta name=\"author\" content=\"SitePoint\">\n\n  <meta property=\"og:title\" content=\"A Basic HTML5 Template\">\n  <meta property=\"og:type\" content=\"website\">\n  <meta property=\"og:url\" content=\"https://www.sitepoint.com/a-basic-html5-template/\">\n  <meta property=\"og:description\" content=\"A simple HTML5 Template for new projects.\">\n  <meta property=\"og:image\" content=\"image.png\">\n\n  <link rel=\"icon\" href=\"/favicon.ico\">\n  <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\">\n  <link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\">\n\n  <link rel=\"stylesheet\" href=\"css/styles.css?v=1.0\">\n\n</head>\n\n<body>\n  <!-- your content here... -->\n  <script is:inline src=\"js/scripts.js\"></script>\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n  <title>A Basic HTML5 Template</title>\n  <meta name=\"description\" content=\"A simple HTML5 Template for new projects.\">\n  <meta name=\"author\" content=\"SitePoint\">\n\n  <meta property=\"og:title\" content=\"A Basic HTML5 Template\">\n  <meta property=\"og:type\" content=\"website\">\n  <meta property=\"og:url\" content=\"https://www.sitepoint.com/a-basic-html5-template/\">\n  <meta property=\"og:description\" content=\"A simple HTML5 Template for new projects.\">\n  <meta property=\"og:image\" content=\"image.png\">\n\n  <link rel=\"icon\" href=\"/favicon.ico\">\n  <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\">\n  <link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\">\n\n  <link rel=\"stylesheet\" href=\"css/styles.css?v=1.0\">\n\n${$$renderHead($$result)}</head>\n\n<body>\n  <!-- your content here... -->\n  <script src=\"js/scripts.js\"></script>\n  </body>\n</html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/iframe.snap",
    "content": "\n[TestPrinter/iframe - 1]\n## Input\n\n```\n<iframe src=\"something\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<iframe src=\"something\"></iframe>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/import.meta.env.snap",
    "content": "\n[TestPrinter/import.meta.env - 1]\n## Input\n\n```\n/-/-/-/\nimport Header from '../../components/Header.jsx'\nimport Footer from '../../components/Footer.astro'\nimport ProductPageContent from '../../components/ProductPageContent.jsx';\n\nexport async function getStaticPaths() {\n  let products = await fetch(`${import.meta.env.PUBLIC_NETLIFY_URL}/.netlify/functions/get-product-list`)\n    .then(res => res.json()).then((response) => {\n      console.log('--- built product pages ---')\n      return response.products.edges\n    });\n\n  return products.map((p, i) => {\n    return {\n      params: {pid: p.node.handle},\n      props: {product: p},\n    };\n  });\n}\n\nconst { product } = Astro.props;\n/-/-/-/\n\n<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>Shoperoni | Buy {product.node.title}</title>\n\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\">\n  <link rel=\"stylesheet\" href=\"/style/global.css\">\n</head>\n<body>\n  <Header />\n  <div class=\"product-page\">\n    <article>\n      <ProductPageContent client:visible product={product.node} />\n    </article>\n  </div>\n  <Footer />\n</body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Header from '../../components/Header.jsx'\n\nimport Footer from '../../components/Footer.astro'\n\nimport ProductPageContent from '../../components/ProductPageContent.jsx';\n\nimport * as $$module1 from '../../components/Header.jsx';\nimport * as $$module2 from '../../components/Footer.astro';\nimport * as $$module3 from '../../components/ProductPageContent.jsx';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../../components/Header.jsx', assert: {} }, { module: $$module2, specifier: '../../components/Footer.astro', assert: {} }, { module: $$module3, specifier: '../../components/ProductPageContent.jsx', assert: {} }], hydratedComponents: [ProductPageContent], clientOnlyComponents: [], hydrationDirectives: new Set(['visible']), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nexport async function getStaticPaths() {\n  let products = await fetch(`${import.meta.env.PUBLIC_NETLIFY_URL}/.netlify/functions/get-product-list`)\n    .then(res => res.json()).then((response) => {\n      console.log('--- built product pages ---')\n      return response.products.edges\n    });\n\n  return products.map((p, i) => {\n    return {\n      params: {pid: p.node.handle},\n      props: {product: p},\n    };\n  });\n}\nconst $$Component = $$createComponent(async ($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nconst { product } = Astro.props;\n\nreturn $$render`<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>Shoperoni | Buy ${product.node.title}</title>\n\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\">\n  <link rel=\"stylesheet\" href=\"/style/global.css\">\n${$$renderHead($$result)}</head>\n<body>\n  ${$$renderComponent($$result,'Header',Header,{})}\n  <div class=\"product-page\">\n    <article>\n      ${$$renderComponent($$result,'ProductPageContent',ProductPageContent,{\"client:visible\":true,\"product\":(product.node),\"client:component-hydration\":\"visible\",\"client:component-path\":(\"../../components/ProductPageContent.jsx\"),\"client:component-export\":(\"default\")})}\n    </article>\n  </div>\n  ${$$renderComponent($$result,'Footer',Footer,{})}\n</body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/import.meta.snap",
    "content": "\n[TestPrinter/import.meta - 1]\n## Input\n\n```\n/-/-/-/\nconst components = import.meta.glob(\"../components/*.astro\", {\n  import: 'default'\n});\n/-/-/-/\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst components = import.meta.glob(\"../components/*.astro\", {\n  import: 'default'\n});\n\nreturn $$render``;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/import_assertions.snap",
    "content": "\n[TestPrinter/import_assertions - 1]\n## Input\n\n```\n/-/-/-/\nimport data from \"test\" assert { type: 'json' };\n/-/-/-/\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport data from \"test\" assert { type: 'json' };\n\nimport * as $$module1 from 'test' assert {type:'json'};\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {type:'json'} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render``;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/import_order.snap",
    "content": "\n[TestPrinter/import_order - 1]\n## Input\n\n```\n/-/-/-/\nlet testWord = \"Test\"\n// comment\nimport data from \"test\";\n/-/-/-/\n\n<div>{data}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport data from \"test\";\n\nimport * as $$module1 from 'test';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nlet testWord = \"Test\"\n// comment\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${data}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/import_to_identifier_named_assert.snap",
    "content": "\n[TestPrinter/import_to_identifier_named_assert - 1]\n## Input\n\n```\n/-/-/-/\nimport assert from 'test';\n/-/-/-/\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport assert from 'test';\n\nimport * as $$module1 from 'test';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render``;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/includes_comments_for_expression_attribute.snap",
    "content": "\n[TestPrinter/includes_comments_for_expression_attribute - 1]\n## Input\n\n```\n<div><h1 attr={/* comment 1 */ isTrue ? 1 : 2 /* comment 2 */}>Hello</h1><Component attr={/* comment 1 */ isTrue ? 1 : 2 /* comment 2 */}/></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div><h1${$$addAttribute(/* comment 1 */ isTrue ? 1 : 2 /* comment 2 */, \"attr\")}>Hello</h1>${$$renderComponent($$result,'Component',Component,{\"attr\":(/* comment 1 */ isTrue ? 1 : 2 /* comment 2 */)})}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/includes_comments_for_shorthand_attribute.snap",
    "content": "\n[TestPrinter/includes_comments_for_shorthand_attribute - 1]\n## Input\n\n```\n<div><h1 {/* comment 1 */ id /* comment 2 */}>Hello</h1><Component {/* comment 1 */ id /* comment 2 */}/></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div><h1${$$addAttribute(/* comment 1 */ id /* comment 2 */, \"id\")}>Hello</h1>${$$renderComponent($$result,'Component',Component,{\"id\":(/* comment 1 */ id /* comment 2 */)})}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/is_raw.snap",
    "content": "\n[TestPrinter/is:raw - 1]\n## Input\n\n```\n<article is:raw><% awesome %></article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article><% awesome %></article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/jsx_comment_between_doctype_and_html.snap",
    "content": "\n[TestPrinter/jsx_comment_between_doctype_and_html - 1]\n## Input\n\n```\n<!doctype html>\n{/* Comment */}\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n    </head>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html lang=\"en\"><head>\n\n\n        <meta charset=\"UTF-8\">\n    ${$$renderHead($$result)}</head>\n</html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/map_basic.snap",
    "content": "\n[TestPrinter/map_basic - 1]\n## Input\n\n```\n/-/-/-/\nconst items = [0, 1, 2];\n/-/-/-/\n<ul>\n    {items.map(item => {\n        return <li>{item}</li>;\n    })}\n</ul>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst items = [0, 1, 2];\n\nreturn $$render`${$$maybeRenderHead($$result)}<ul>\n    ${items.map(item => {\n        return $$render`<li>${item}</li>`;\n    })}\n</ul>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/map_nested.snap",
    "content": "\n[TestPrinter/map_nested - 1]\n## Input\n\n```\n/-/-/-/\nconst groups = [[0, 1, 2], [3, 4, 5]];\n/-/-/-/\n<div>\n    {groups.map(items => {\n        return <ul>{\n            items.map(item => {\n                return <li>{item}</li>;\n            })\n        }</ul>\n    })}\n</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst groups = [[0, 1, 2], [3, 4, 5]];\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>\n    ${groups.map(items => {\n        return $$render`<ul>${\n            items.map(item => {\n                return $$render`<li>${item}</li>`;\n            })\n        }</ul>`\n    })}\n</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/map_with_component.snap",
    "content": "\n[TestPrinter/map_with_component - 1]\n## Input\n\n```\n<header><nav>{menu.map((item) => <a href={item.href}>{item.title}</a>)}</nav><Hello/></header>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<header><nav>${menu.map((item) => $$render`<a${$$addAttribute(item.href, \"href\")}>${item.title}</a>`)}</nav>${$$renderComponent($$result,'Hello',Hello,{})}</header>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/map_without_component.snap",
    "content": "\n[TestPrinter/map_without_component - 1]\n## Input\n\n```\n<header><nav>{menu.map((item) => <a href={item.href}>{item.title}</a>)}</nav></header>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<header><nav>${menu.map((item) => $$render`<a${$$addAttribute(item.href, \"href\")}>${item.title}</a>`)}</nav></header>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/maybeRenderHead_not_printed_for_hoisted_scripts.snap",
    "content": "\n[TestPrinter/maybeRenderHead_not_printed_for_hoisted_scripts - 1]\n## Input\n\n```\n<script></script><Layout></Layout>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/pages/page.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Page = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderScript($$result,\"/projects/app/src/pages/page.astro?astro&type=script&index=0&lang.ts\")}${$$renderComponent($$result,'Layout',Layout,{})}`;\n}, '/projects/app/src/pages/page.astro', undefined);\nexport default $$Page;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/multibyte_character___script.snap",
    "content": "\n[TestPrinter/multibyte_character_+_script - 1]\n## Input\n\n```\n<script>console.log('foo')</script><a class=\"test\">ツ</a>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log('foo')` }] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderScript($$result,\"?astro&type=script&index=0&lang.ts\")}${$$maybeRenderHead($$result)}<a class=\"test\">ツ</a>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/multibyte_character___style.snap",
    "content": "\n[TestPrinter/multibyte_character_+_style - 1]\n## Input\n\n```\n<style>a { font-size: 16px; }</style><a class=\"test\">ツ</a>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<a class=\"test astro-7vm74pjk\">ツ</a>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/multibyte_characters.snap",
    "content": "\n[TestPrinter/multibyte_characters - 1]\n## Input\n\n```\n/-/-/-/\n/-/-/-/\n<h1>こんにちは</h1>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<h1>こんにちは</h1>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/multiline_class_attribute_on_component.snap",
    "content": "\n[TestPrinter/multiline_class_attribute_on_component - 1]\n## Input\n\n```\n<Component class=\"some-class\n  another-class\n  third-class\">content</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{\"class\":\"some-class\\n  another-class\\n  third-class\"},{\"default\": () => $$render`content`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/multiple_define_vars_on_style.snap",
    "content": "\n[TestPrinter/multiple_define:vars_on_style - 1]\n## Input\n\n```\n<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><style define:vars={{color:'red'}}>h2{color:var(--color)}</style><h1>foo</h1><h2>bar</h2>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst $$definedVars = $$defineStyleVars([{color:'green'},{color:'red'}]);\nreturn $$render`${$$maybeRenderHead($$result)}<h1 class=\"astro-6oxbqcst\"${$$addAttribute($$definedVars, \"style\")}>foo</h1><h2 class=\"astro-6oxbqcst\"${$$addAttribute($$definedVars, \"style\")}>bar</h2>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/namespace_is_preserved_when_inside_an_expression.snap",
    "content": "\n[TestPrinter/namespace_is_preserved_when_inside_an_expression - 1]\n## Input\n\n```\n<svg>{<image />}</svg>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<svg>${$$render`<image></image>`}</svg>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions.snap",
    "content": "\n[TestPrinter/nested_expressions - 1]\n## Input\n\n```\n<article>{(previous || next) && <aside>{previous && <div>Previous Article: <a rel=\"prev\" href={new URL(previous.link, Astro.site).pathname}>{previous.text}</a></div>}{next && <div>Next Article: <a rel=\"next\" href={new URL(next.link, Astro.site).pathname}>{next.text}</a></div>}</aside>}</article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${(previous || next) && $$render`<aside>${previous && $$render`<div>Previous Article: <a rel=\"prev\"${$$addAttribute(new URL(previous.link, Astro.site).pathname, \"href\")}>${previous.text}</a></div>`}${next && $$render`<div>Next Article: <a rel=\"next\"${$$addAttribute(new URL(next.link, Astro.site).pathname, \"href\")}>${next.text}</a></div>`}</aside>`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions_II.snap",
    "content": "\n[TestPrinter/nested_expressions_II - 1]\n## Input\n\n```\n<article>{(previous || next) && <aside>{previous && <div>Previous Article: <a rel=\"prev\" href={new URL(previous.link, Astro.site).pathname}>{previous.text}</a></div>} {next && <div>Next Article: <a rel=\"next\" href={new URL(next.link, Astro.site).pathname}>{next.text}</a></div>}</aside>}</article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${(previous || next) && $$render`<aside>${previous && $$render`<div>Previous Article: <a rel=\"prev\"${$$addAttribute(new URL(previous.link, Astro.site).pathname, \"href\")}>${previous.text}</a></div>`} ${next && $$render`<div>Next Article: <a rel=\"next\"${$$addAttribute(new URL(next.link, Astro.site).pathname, \"href\")}>${next.text}</a></div>`}</aside>`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions_III.snap",
    "content": "\n[TestPrinter/nested_expressions_III - 1]\n## Input\n\n```\n<div>{x.map((x) => x ? <div>{true ? <span>{x}</span> : null}</div> : <div>{false ? null : <span>{x}</span>}</div>)}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${x.map((x) => x ? $$render`<div>${true ? $$render`<span>${x}</span>` : null}</div>` : $$render`<div>${false ? null : $$render`<span>${x}</span>`}</div>`)}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions_IV.snap",
    "content": "\n[TestPrinter/nested_expressions_IV - 1]\n## Input\n\n```\n<div>{() => { if (value > 0.25) { return <span>Default</span> } else if (value > 0.5) { return <span>Another</span> } else if (value > 0.75) { return <span>Other</span> } return <span>Yet Other</span> }}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${() => { if (value > 0.25) { return $$render`<span>Default</span>` } else if (value > 0.5) { return $$render`<span>Another</span>` } else if (value > 0.75) { return $$render`<span>Other</span>` } return $$render`<span>Yet Other</span>` }}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions_V.snap",
    "content": "\n[TestPrinter/nested_expressions_V - 1]\n## Input\n\n```\n<div><h1>title</h1>{list.map(group => <Fragment><h2>{group.label}</h2>{group.items.map(item => <span>{item}</span>)}</Fragment>)}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div><h1>title</h1>${list.map(group => $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`<h2>${group.label}</h2>${group.items.map(item => $$render`<span>${item}</span>`)}`,})}`)}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions_VI.snap",
    "content": "\n[TestPrinter/nested_expressions_VI - 1]\n## Input\n\n```\n<div>{()=>{ if (true) { return <hr />;} if (true) { return <img />;}}}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${()=>{ if (true) { return $$render`<hr>`;} if (true) { return $$render`<img>`;}}}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions_VII.snap",
    "content": "\n[TestPrinter/nested_expressions_VII - 1]\n## Input\n\n```\n<div>{() => { if (value > 0.25) { return <br />;} else if (value > 0.5) { return <hr />;} else if (value > 0.75) { return <div />;} return <div>Yaaay</div>;}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${() => { if (value > 0.25) { return $$render`<br>`;} else if (value > 0.5) { return $$render`<hr>`;} else if (value > 0.75) { return $$render`<div></div>`;} return $$render`<div>Yaaay</div>`;}}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_expressions_VIII.snap",
    "content": "\n[TestPrinter/nested_expressions_VIII - 1]\n## Input\n\n```\n<div>{ items.map(({ type, ...data }) => { switch (type) { case 'card': { return ( <Card {...data} /> ); } case 'paragraph': { return ( <p>{data.body}</p>);}}})}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${ items.map(({ type, ...data }) => { switch (type) { case 'card': { return ( $$render`${$$renderComponent($$result,'Card',Card,{...(data)})}` ); } case 'paragraph': { return ( $$render`<p>${data.body}</p>`);}}})}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_head_content_stays_in_the_head.snap",
    "content": "\n[TestPrinter/nested_head_content_stays_in_the_head - 1]\n## Input\n\n```\n/-/-/-/\nconst meta = { title: 'My App' };\n/-/-/-/\n\n<html>\n    <head>\n        <meta charset=\"utf-8\" />\n\n        {\n            meta && <title>{meta.title}</title>\n        }\n\n        <meta name=\"after\">\n    </head>\n    <body>\n        <h1>My App</h1>\n    </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst meta = { title: 'My App' };\n\nreturn $$render`<html>\n    <head>\n        <meta charset=\"utf-8\">\n\n        ${\n            meta && $$render`<title>${meta.title}</title>`\n        }\n\n        <meta name=\"after\">\n    ${$$renderHead($$result)}</head>\n    <body>\n        <h1>My App</h1>\n    </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/nested_template_literal_expression.snap",
    "content": "\n[TestPrinter/nested_template_literal_expression - 1]\n## Input\n\n```\n<div value={`${attr ? `a/b ${`c`}` : \"d\"} awesome`} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute(`${attr ? `a/b ${`c`}` : \"d\"} awesome`, \"value\")}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n\n[TestPrinter/nested_template_literal_expression#01 - 1]\n## Input\n\n```\n<html lang=\"en\">\n<body>\n{Object.keys(importedAuthors).map(author => <p><div>hello</div></p>)}\n{Object.keys(importedAuthors).map(author => <p><div>{author}</div></p>)}\n</body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html lang=\"en\">\n${$$maybeRenderHead($$result)}<body>\n${Object.keys(importedAuthors).map(author => $$render`<p></p><div>hello</div>`)}\n${Object.keys(importedAuthors).map(author => $$render`<p></p><div>${author}</div>`)}\n</body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/no_expressions_in_math.snap",
    "content": "\n[TestPrinter/no_expressions_in_math - 1]\n## Input\n\n```\n<p>Hello, world! This is a <em>buggy</em> formula: <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>f</mi><mspace></mspace><mspace width=\"0.1111em\"></mspace><mo lspace=\"0em\" rspace=\"0.17em\"></mo><mtext> ⁣</mtext><mo lspace=\"0em\" rspace=\"0em\">:</mo><mspace width=\"0.3333em\"></mspace><mi>X</mi><mo>→</mo><msup><mi mathvariant=\"double-struck\">R</mi><mrow><mn>2</mn><mi>x</mi></mrow></msup></mrow><annotation encoding=\"application/x-tex\">f\\colon X \\to \\mathbb R^{2x}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.8889em;vertical-align:-0.1944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace nobreak\"></span><span class=\"mspace\" style=\"margin-right:0.1111em;\"></span><span class=\"mpunct\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mrel\">:</span></span><span class=\"mspace\" style=\"margin-right:0.3333em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.07847em;\">X</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">→</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.8141em;\"></span><span class=\"mord\"><span class=\"mord mathbb\">R</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span><span class=\"mord mathnormal mtight\">x</span></span></span></span></span></span></span></span></span></span></span></span></span></p>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<p>Hello, world! This is a <em>buggy</em> formula: <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>f</mi><mspace></mspace><mspace width=\"0.1111em\"></mspace><mo lspace=\"0em\" rspace=\"0.17em\"></mo><mtext> ⁣</mtext><mo lspace=\"0em\" rspace=\"0em\">:</mo><mspace width=\"0.3333em\"></mspace><mi>X</mi><mo>→</mo><msup><mi mathvariant=\"double-struck\">R</mi><mrow><mn>2</mn><mi>x</mi></mrow></msup></mrow><annotation encoding=\"application/x-tex\">f\\\\colon X \\\\to \\\\mathbb R^{2x}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.8889em;vertical-align:-0.1944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace nobreak\"></span><span class=\"mspace\" style=\"margin-right:0.1111em;\"></span><span class=\"mpunct\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mrel\">:</span></span><span class=\"mspace\" style=\"margin-right:0.3333em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.07847em;\">X</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">→</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.8141em;\"></span><span class=\"mord\"><span class=\"mord mathbb\">R</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span><span class=\"mord mathnormal mtight\">x</span></span></span></span></span></span></span></span></span></span></span></span></span></p>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n\n[TestPrinter/no_expressions_in_math#01 - 1]\n## Input\n\n```\n<p>Hello, world! This is a <em>buggy</em> formula: <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>f</mi><mspace></mspace><mspace width=\"0.1111em\"></mspace><mo lspace=\"0em\" rspace=\"0.17em\"></mo><mtext> ⁣</mtext><mo lspace=\"0em\" rspace=\"0em\">:</mo><mspace width=\"0.3333em\"></mspace><mi>X</mi><mo>→</mo><msup><mi mathvariant=\"double-struck\">R</mi><mrow><mn>2</mn><mi>x</mi></mrow></msup></mrow><annotation encoding=\"application/x-tex\">f\\colon X \\to \\mathbb R^{2x}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.8889em;vertical-align:-0.1944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace nobreak\"></span><span class=\"mspace\" style=\"margin-right:0.1111em;\"></span><span class=\"mpunct\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mrel\">:</span></span><span class=\"mspace\" style=\"margin-right:0.3333em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.07847em;\">X</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">→</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.8141em;\"></span><span class=\"mord\"><span class=\"mord mathbb\">R</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span><span class=\"mord mathnormal mtight\">x</span></span></span></span></span></span></span></span></span></span></span></span></span></p>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<p>Hello, world! This is a <em>buggy</em> formula: <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>f</mi><mspace></mspace><mspace width=\"0.1111em\"></mspace><mo lspace=\"0em\" rspace=\"0.17em\"></mo><mtext> ⁣</mtext><mo lspace=\"0em\" rspace=\"0em\">:</mo><mspace width=\"0.3333em\"></mspace><mi>X</mi><mo>→</mo><msup><mi mathvariant=\"double-struck\">R</mi><mrow><mn>2</mn><mi>x</mi></mrow></msup></mrow><annotation encoding=\"application/x-tex\">f\\\\colon X \\\\to \\\\mathbb R^{2x}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.8889em;vertical-align:-0.1944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace nobreak\"></span><span class=\"mspace\" style=\"margin-right:0.1111em;\"></span><span class=\"mpunct\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mrel\">:</span></span><span class=\"mspace\" style=\"margin-right:0.3333em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.07847em;\">X</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">→</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.8141em;\"></span><span class=\"mord\"><span class=\"mord mathbb\">R</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span><span class=\"mord mathnormal mtight\">x</span></span></span></span></span></span></span></span></span></span></span></span></span></p>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/noscript_component.snap",
    "content": "\n[TestPrinter/noscript_component - 1]\n## Input\n\n```\n<html>\n  <head></head>\n  <body>\n    <noscript>\n        <Component />\n    </noscript>\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>\n  <head>${$$renderHead($$result)}</head>\n  <body>\n    <noscript>\n        ${$$renderComponent($$result,'Component',Component,{})}\n    </noscript>\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/noscript_deep_styles.snap",
    "content": "\n[TestPrinter/noscript_deep_styles - 1]\n## Input\n\n```\n<body><noscript><div><div><div><style>div { color: red; }</style></div></div></div></noscript></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body><noscript><div><div><div><style>div { color: red; }</style></div></div></div></noscript></body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/noscript_only.snap",
    "content": "\n[TestPrinter/noscript_only - 1]\n## Input\n\n```\n<noscript><h1>Hello world</h1></noscript>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<noscript><h1>Hello world</h1></noscript>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/noscript_styles.snap",
    "content": "\n[TestPrinter/noscript_styles - 1]\n## Input\n\n```\n<noscript><style>div { color: red; }</style></noscript>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<noscript><style>div { color: red; }</style></noscript>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/orphan_slot.snap",
    "content": "\n[TestPrinter/orphan_slot - 1]\n## Input\n\n```\n<slot />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderSlot($$result,$$slots[\"default\"])}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/passes_escaped_filename_into_createComponent_if_it_contains_single_quotes.snap",
    "content": "\n[TestPrinter/passes_escaped_filename_into_createComponent_if_it_contains_single_quotes - 1]\n## Input\n\n```\n<div>test</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/pages/page-with-\\'-quotes.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$PageWithQuotes = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>test</div>`;\n}, '/projects/app/src/pages/page-with-\\'-quotes.astro', undefined);\nexport default $$PageWithQuotes;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/passes_filename_into_createComponent_if_passed_into_the_compiler_options.snap",
    "content": "\n[TestPrinter/passes_filename_into_createComponent_if_passed_into_the_compiler_options - 1]\n## Input\n\n```\n<div>test</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/pages/page.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Page = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>test</div>`;\n}, '/projects/app/src/pages/page.astro', undefined);\nexport default $$Page;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/preserve_is_inline_slot.snap",
    "content": "\n[TestPrinter/preserve_is:inline_slot - 1]\n## Input\n\n```\n<slot is:inline />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<slot></slot>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/preserve_is_inline_slot_II.snap",
    "content": "\n[TestPrinter/preserve_is:inline_slot_II - 1]\n## Input\n\n```\n<slot name=\"test\" is:inline />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<slot name=\"test\"></slot>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script.snap",
    "content": "\n[TestPrinter/script - 1]\n## Input\n\n```\n<main><script>console.log(\"Hello\");</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/src/pages/index.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log(\"Hello\");` }] });\n\nconst $$Index = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main>${$$renderScript($$result,\"/src/pages/index.astro?astro&type=script&index=0&lang.ts\")}</main>`;\n}, '/src/pages/index.astro', undefined);\nexport default $$Index;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_before_elements.snap",
    "content": "\n[TestPrinter/script_before_elements - 1]\n## Input\n\n```\n<script>Here</script><div></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `Here` }] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderScript($$result,\"?astro&type=script&index=0&lang.ts\")}${$$maybeRenderHead($$result)}<div></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_define_vars_I.snap",
    "content": "\n[TestPrinter/script_define:vars_I - 1]\n## Input\n\n```\n<script define:vars={{ value: 0 }}>console.log(value);</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script>(function(){${$$defineScriptVars({ value: 0 })}console.log(value);})();</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_define_vars_II.snap",
    "content": "\n[TestPrinter/script_define:vars_II - 1]\n## Input\n\n```\n<script define:vars={{ \"dash-case\": true }}>console.log(dashCase);</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script>(function(){${$$defineScriptVars({ \"dash-case\": true })}console.log(dashCase);})();</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_external.snap",
    "content": "\n[TestPrinter/script_external - 1]\n## Input\n\n```\n<main><script src=\"./hello.js\"></script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/src/pages/index.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'external', src: './hello.js' }] });\n\nconst $$Index = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main>${$$renderScript($$result,\"/src/pages/index.astro?astro&type=script&index=0&lang.ts\")}</main>`;\n}, '/src/pages/index.astro', undefined);\nexport default $$Index;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_external_in_expression.snap",
    "content": "\n[TestPrinter/script_external_in_expression - 1]\n## Input\n\n```\n<main>{<script src=\"./hello.js\"></script>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/src/pages/index.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'external', src: './hello.js' }] });\n\nconst $$Index = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main>${$$render`${$$renderScript($$result,\"/src/pages/index.astro?astro&type=script&index=0&lang.ts\")}`}</main>`;\n}, '/src/pages/index.astro', undefined);\nexport default $$Index;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_hoist_with_frontmatter.snap",
    "content": "\n[TestPrinter/script_hoist_with_frontmatter - 1]\n## Input\n\n```\n/-/-/-/\n/-/-/-/\n<script type=\"module\" hoist>console.log(\"Hello\");</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log(\"Hello\");` }] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderScript($$result,\"?astro&type=script&index=0&lang.ts\")}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_hoist_without_frontmatter.snap",
    "content": "\n[TestPrinter/script_hoist_without_frontmatter - 1]\n## Input\n\n```\n<main>\n                                <script type=\"module\" hoist>console.log(\"Hello\");</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log(\"Hello\");` }] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main>\n                                ${$$renderScript($$result,\"?astro&type=script&index=0&lang.ts\")}\n</main>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_in__head_.snap",
    "content": "\n[TestPrinter/script_in_<head> - 1]\n## Input\n\n```\n/-/-/-/\nimport Widget from '../components/Widget.astro';\nimport Widget2 from '../components/Widget2.astro';\n/-/-/-/\n<html lang=\"en\">\n  <head>\n    <script type=\"module\" src=\"/regular_script.js\"></script>\n  </head>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Widget from '../components/Widget.astro';\nimport Widget2 from '../components/Widget2.astro';\n\nimport * as $$module1 from '../components/Widget.astro';\nimport * as $$module2 from '../components/Widget2.astro';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: '../components/Widget.astro', assert: {} }, { module: $$module2, specifier: '../components/Widget2.astro', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html lang=\"en\">\n  <head>\n    <script type=\"module\" src=\"/regular_script.js\"></script>\n  ${$$renderHead($$result)}</head></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_in_expression.snap",
    "content": "\n[TestPrinter/script_in_expression - 1]\n## Input\n\n```\n<main>{true && <script>console.log(\"hello\")</script>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/src/pages/index.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log(\"hello\")` }] });\n\nconst $$Index = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main>${true && $$render`${$$renderScript($$result,\"/src/pages/index.astro?astro&type=script&index=0&lang.ts\")}`}</main>`;\n}, '/src/pages/index.astro', undefined);\nexport default $$Index;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_inline.snap",
    "content": "\n[TestPrinter/script_inline - 1]\n## Input\n\n```\n<main><script is:inline type=\"module\">console.log(\"Hello\");</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main><script type=\"module\">console.log(\"Hello\");</script></main>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_mixed_handled_and_inline.snap",
    "content": "\n[TestPrinter/script_mixed_handled_and_inline - 1]\n## Input\n\n```\n<main><script>console.log(\"Hello\");</script><script is:inline>console.log(\"World\");</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/src/pages/index.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log(\"Hello\");` }] });\n\nconst $$Index = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main>${$$renderScript($$result,\"/src/pages/index.astro?astro&type=script&index=0&lang.ts\")}<script>console.log(\"World\");</script></main>`;\n}, '/src/pages/index.astro', undefined);\nexport default $$Index;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/script_multiple.snap",
    "content": "\n[TestPrinter/script_multiple - 1]\n## Input\n\n```\n<main><script>console.log(\"Hello\");</script><script>console.log(\"World\");</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(\"/src/pages/index.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log(\"Hello\");` }, { type: 'inline', value: `console.log(\"World\");` }] });\n\nconst $$Index = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main>${$$renderScript($$result,\"/src/pages/index.astro?astro&type=script&index=0&lang.ts\")}${$$renderScript($$result,\"/src/pages/index.astro?astro&type=script&index=1&lang.ts\")}</main>`;\n}, '/src/pages/index.astro', undefined);\nexport default $$Index;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/scriptinline.snap",
    "content": "\n[TestPrinter/scriptinline - 1]\n## Input\n\n```\n<main><script is:inline type=\"module\">console.log(\"Hello\");</script>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<main><script type=\"module\">console.log(\"Hello\");</script></main>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/select_in_form.snap",
    "content": "\n[TestPrinter/select_in_form - 1]\n## Input\n\n```\n<form><select>{options.map((option) => (<option value={option.id}>{option.title}</option>))}</select><div><label>Title 3</label><input type=\"text\" /></div><button type=\"submit\">Submit</button></form>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<form><select>${options.map((option) => ($$render`<option${$$addAttribute(option.id, \"value\")}>${option.title}</option>`))}</select><div><label>Title 3</label><input type=\"text\"></div><button type=\"submit\">Submit</button></form>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/select_map_expression.snap",
    "content": "\n[TestPrinter/select_map_expression - 1]\n## Input\n\n```\n<select>{[1, 2, 3].map(num => <option>{num}</option>)}</select><div>Hello world!</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<select>${[1, 2, 3].map(num => $$render`<option>${num}</option>`)}</select><div>Hello world!</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/select_nested_option.snap",
    "content": "\n[TestPrinter/select_nested_option - 1]\n## Input\n\n```\n/-/-/-/\nconst value = 'test';\n/-/-/-/\n<select>{value && <option>{value}</option>}</select>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst value = 'test';\n\nreturn $$render`${$$maybeRenderHead($$result)}<select>${value && $$render`<option>${value}</option>`}</select>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/select_option_expression.snap",
    "content": "\n[TestPrinter/select_option_expression - 1]\n## Input\n\n```\n/-/-/-/\nconst value = 'test';\n/-/-/-/\n<select><option>{value}</option></select>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst value = 'test';\n\nreturn $$render`${$$maybeRenderHead($$result)}<select><option>${value}</option></select>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/selectedcontent_element_in_customizable_select.snap",
    "content": "\n[TestPrinter/selectedcontent_element_in_customizable_select - 1]\n## Input\n\n```\n<select><button><selectedcontent></selectedcontent></button><option>Option 1</option><option>Option 2</option></select>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<select><button><selectedcontent></button><option>Option 1</option><option>Option 2</option></select>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/selectedcontent_self-closing_element.snap",
    "content": "\n[TestPrinter/selectedcontent_self-closing_element - 1]\n## Input\n\n```\n<select><button><selectedcontent /></button><option>Option 1</option><option>Option 2</option></select>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<select><button><selectedcontent></button><option>Option 1</option><option>Option 2</option></select>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/self-closing_td.snap",
    "content": "\n[TestPrinter/self-closing_td - 1]\n## Input\n\n```\n<table>{data.map(row => <tr>{row.map(cell => <td set:html={cell} />)}</tr>)}</table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table>${data.map(row => $$render`<tr>${row.map(cell => $$render`<td>${$$unescapeHTML(cell)}</td>`)}</tr>`)}</table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html.snap",
    "content": "\n[TestPrinter/set:html - 1]\n## Input\n\n```\n<article set:html={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${$$unescapeHTML(content)}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_and_set_text.snap",
    "content": "\n[TestPrinter/set:html_and_set:text - 1]\n## Input\n\n```\n<article set:html={content} set:text={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${$$unescapeHTML(content)}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Component.snap",
    "content": "\n[TestPrinter/set:html_on_Component - 1]\n## Input\n\n```\n<Component set:html={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${$$unescapeHTML(content)}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Component_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_Component_with_quoted_attribute - 1]\n## Input\n\n```\n<Component set:html=\"content\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${\"content\"}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Component_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_Component_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<Component set:html=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${`${content}`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Component_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_Component_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<Component set:html=`content` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${`content`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Fragment.snap",
    "content": "\n[TestPrinter/set:html_on_Fragment - 1]\n## Input\n\n```\n<Fragment set:html={\"<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>\"} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${$$unescapeHTML(\"<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>\")}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Fragment_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_Fragment_with_quoted_attribute - 1]\n## Input\n\n```\n<Fragment set:html=\"<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${\"<p><i>This should NOT be italic</i></p>\"}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Fragment_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_Fragment_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<Fragment set:html=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${`${content}`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_Fragment_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_Fragment_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<Fragment set:html=`<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`${`<p><i>This should NOT be italic</i></p>`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_custom-element.snap",
    "content": "\n[TestPrinter/set:html_on_custom-element - 1]\n## Input\n\n```\n<custom-element set:html={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`${$$unescapeHTML(content)}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_custom-element_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_custom-element_with_quoted_attribute - 1]\n## Input\n\n```\n<custom-element set:html=\"content\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`${\"content\"}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_custom-element_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_custom-element_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<custom-element set:html=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`${`${content}`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_custom-element_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_custom-element_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<custom-element set:html=`content` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`${`content`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_empty_tag.snap",
    "content": "\n[TestPrinter/set:html_on_empty_tag - 1]\n## Input\n\n```\n<article set:html={content}></article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${$$unescapeHTML(content)}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_empty_tag_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_empty_tag_with_quoted_attribute - 1]\n## Input\n\n```\n<article set:html=\"content\"></article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${\"content\"}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_empty_tag_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_empty_tag_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<article set:html=`${content}`></article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`${content}`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_empty_tag_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_empty_tag_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<article set:html=`content`></article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`content`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_script.snap",
    "content": "\n[TestPrinter/set:html_on_script - 1]\n## Input\n\n```\n<script set:html={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script>${$$unescapeHTML(content)}</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_script_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_script_with_quoted_attribute - 1]\n## Input\n\n```\n<script set:html=\"alert(1)\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script>${\"alert(1)\"}</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_script_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_script_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<script set:html=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script>${`${content}`}</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_script_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_script_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<script set:html=`alert(1)` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<script>${`alert(1)`}</script>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_self-closing_tag.snap",
    "content": "\n[TestPrinter/set:html_on_self-closing_tag - 1]\n## Input\n\n```\n<article set:html={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${$$unescapeHTML(content)}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_self-closing_tag_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_self-closing_tag_with_quoted_attribute - 1]\n## Input\n\n```\n<article set:html=\"content\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${\"content\"}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_self-closing_tag_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_self-closing_tag_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<article set:html=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`${content}`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_self-closing_tag_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_self-closing_tag_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<article set:html=`content` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`content`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_style.snap",
    "content": "\n[TestPrinter/set:html_on_style - 1]\n## Input\n\n```\n<style set:html={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<style>${$$unescapeHTML(content)}</style>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_style_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_style_with_quoted_attribute - 1]\n## Input\n\n```\n<style set:html=\"h1{color:green;}\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<style>${\"h1{color:green;}\"}</style>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_style_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_style_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<style set:html=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<style>${`${content}`}</style>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_style_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_style_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<style set:html=`h1{color:green;}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<style>${`h1{color:green;}`}</style>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_children.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_children - 1]\n## Input\n\n```\n<article set:html={content}>!!!</article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${$$unescapeHTML(content)}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_children_and_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_children_and_quoted_attribute - 1]\n## Input\n\n```\n<article set:html=\"content\">!!!</article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${\"content\"}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_children_and_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_children_and_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<article set:html=`${content}`>!!!</article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`${content}`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_children_and_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_children_and_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<article set:html=`content`>!!!</article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`content`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_empty_whitespace - 1]\n## Input\n\n```\n<article set:html={content}>   </article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${$$unescapeHTML(content)}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace_and_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_empty_whitespace_and_quoted_attribute - 1]\n## Input\n\n```\n<article set:html=\"content\">   </article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${\"content\"}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace_and_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_empty_whitespace_and_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<article set:html=`${content}`>   </article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`${content}`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace_and_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_on_tag_with_empty_whitespace_and_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<article set:html=`content`>   </article>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`content`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_with_other_attributes.snap",
    "content": "\n[TestPrinter/set:html_with_other_attributes - 1]\n## Input\n\n```\n<article set:html={content} cool=\"true\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article cool=\"true\">${$$unescapeHTML(content)}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:html_with_quoted_attribute - 1]\n## Input\n\n```\n<article set:html=\"content\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${\"content\"}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_with_quoted_attribute_and_other_attributes.snap",
    "content": "\n[TestPrinter/set:html_with_quoted_attribute_and_other_attributes - 1]\n## Input\n\n```\n<article set:html=\"content\" cool=\"true\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article cool=\"true\">${\"content\"}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:html_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<article set:html=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`${content}`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_with_template_literal_attribute_with_variable_and_other_attributes.snap",
    "content": "\n[TestPrinter/set:html_with_template_literal_attribute_with_variable_and_other_attributes - 1]\n## Input\n\n```\n<article set:html=`${content}` cool=\"true\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article cool=\"true\">${`${content}`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:html_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<article set:html=`content` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`content`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_html_with_template_literal_attribute_without_variable_and_other_attributes.snap",
    "content": "\n[TestPrinter/set:html_with_template_literal_attribute_without_variable_and_other_attributes - 1]\n## Input\n\n```\n<article set:html=`content` cool=\"true\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article cool=\"true\">${`content`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text.snap",
    "content": "\n[TestPrinter/set:text - 1]\n## Input\n\n```\n<article set:text={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${content}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_Component.snap",
    "content": "\n[TestPrinter/set:text_on_Component - 1]\n## Input\n\n```\n<Component set:text={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${content}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_Component_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:text_on_Component_with_quoted_attribute - 1]\n## Input\n\n```\n<Component set:text=\"content\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`content`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_Component_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:text_on_Component_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<Component set:text=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${`${content}`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_Component_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:text_on_Component_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<Component set:text=`content` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${`content`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_custom-element.snap",
    "content": "\n[TestPrinter/set:text_on_custom-element - 1]\n## Input\n\n```\n<custom-element set:text={content} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`${content}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_custom-element_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:text_on_custom-element_with_quoted_attribute - 1]\n## Input\n\n```\n<custom-element set:text=\"content\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`content`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_custom-element_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:text_on_custom-element_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<custom-element set:text=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`${`${content}`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_on_custom-element_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:text_on_custom-element_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<custom-element set:text=`content` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{\"default\": () => $$render`${`content`}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_with_quoted_attribute.snap",
    "content": "\n[TestPrinter/set:text_with_quoted_attribute - 1]\n## Input\n\n```\n<article set:text=\"content\" />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>content</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_with_template_literal_attribute_with_variable.snap",
    "content": "\n[TestPrinter/set:text_with_template_literal_attribute_with_variable - 1]\n## Input\n\n```\n<article set:text=`${content}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`${content}`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/set_text_with_template_literal_attribute_without_variable.snap",
    "content": "\n[TestPrinter/set:text_with_template_literal_attribute_without_variable - 1]\n## Input\n\n```\n<article set:text=`content` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<article>${`content`}</article>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/sibling_expressions.snap",
    "content": "\n[TestPrinter/sibling_expressions - 1]\n## Input\n\n```\n<html><body>\n  <table>\n  {true ? (<tr><td>Row 1</td></tr>) : null}\n  {true ? (<tr><td>Row 2</td></tr>) : null}\n  {true ? (<tr><td>Row 3</td></tr>) : null}\n  </table>\n</body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>${$$maybeRenderHead($$result)}<body>\n  <table>\n  ${true ? ($$render`<tr><td>Row 1</td></tr>`) : null}\n  ${true ? ($$render`<tr><td>Row 2</td></tr>`) : null}\n  ${true ? ($$render`<tr><td>Row 3</td></tr>`) : null}\n  </table>\n</body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/simple_ternary.snap",
    "content": "\n[TestPrinter/simple_ternary - 1]\n## Input\n\n```\n<body>{link ? <a href=\"/\">{link}</a> : <div>no link</div>}</body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${link ? $$render`<a href=\"/\">${link}</a>` : $$render`<div>no link</div>`}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slot_inside_of_Base.snap",
    "content": "\n[TestPrinter/slot_inside_of_Base - 1]\n## Input\n\n```\n<Base title=\"Home\"><div>Hello</div></Base>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Base',Base,{\"title\":\"Home\"},{\"default\": () => $$render`${$$maybeRenderHead($$result)}<div>Hello</div>`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slot_with_fallback.snap",
    "content": "\n[TestPrinter/slot_with_fallback - 1]\n## Input\n\n```\n<body><slot><p>Hello world!</p></slot><body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body>${$$renderSlot($$result,$$slots[\"default\"],$$render`<p>Hello world!</p>`)}</body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slot_with_fallback_II.snap",
    "content": "\n[TestPrinter/slot_with_fallback_II - 1]\n## Input\n\n```\n<slot name=\"test\"><p>Hello world!</p></slot>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderSlot($$result,$$slots[\"test\"],$$render`${$$maybeRenderHead($$result)}<p>Hello world!</p>`)}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slot_with_fallback_III.snap",
    "content": "\n[TestPrinter/slot_with_fallback_III - 1]\n## Input\n\n```\n<div><slot name=\"test\"><p>Fallback</p></slot></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${$$renderSlot($$result,$$slots[\"test\"],$$render`<p>Fallback</p>`)}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slot_with_quoted_attributes.snap",
    "content": "\n[TestPrinter/slot_with_quoted_attributes - 1]\n## Input\n\n```\n<Component><div slot='\"name\"' /></Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"\\\"name\\\"\": () => $$render`${$$maybeRenderHead($$result)}<div></div>`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slots__basic_.snap",
    "content": "\n[TestPrinter/slots_(basic) - 1]\n## Input\n\n```\n/-/-/-/\nimport Component from \"test\";\n/-/-/-/\n<Component>\n    <div>Default</div>\n    <div slot=\"named\">Named</div>\n</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Component from \"test\";\n\nimport * as $$module1 from 'test';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`\n    ${$$maybeRenderHead($$result)}<div>Default</div>\n\n`,\"named\": () => $$render`<div>Named</div>`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slots__dynamic_name_.snap",
    "content": "\n[TestPrinter/slots_(dynamic_name) - 1]\n## Input\n\n```\n/-/-/-/\nimport Component from 'test';\nconst name = 'named';\n        ---\n        <Component>\n            <div slot={name}>Named</div>\n        </Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Component from 'test';\n\nimport * as $$module1 from 'test';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst name = 'named';\n\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{[name]: () => $$render`${$$maybeRenderHead($$result)}<div>Named</div>`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slots__expression_.snap",
    "content": "\n[TestPrinter/slots_(expression) - 1]\n## Input\n\n```\n<Component {data}>\n    {items.map(item => <div>{item}</div>)}\n</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{\"data\":(data)},{\"default\": () => $$render`${items.map(item => $$render`${$$maybeRenderHead($$result)}<div>${item}</div>`)}`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slots__named_only_.snap",
    "content": "\n[TestPrinter/slots_(named_only) - 1]\n## Input\n\n```\n<Slotted>\n      <span slot=\"a\">A</span>\n      <span slot=\"b\">B</span>\n      <span slot=\"c\">C</span>\n    </Slotted>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Slotted',Slotted,{},{\"a\": () => $$render`${$$maybeRenderHead($$result)}<span>A</span>`,\"b\": () => $$render`<span>B</span>`,\"c\": () => $$render`<span>C</span>`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/slots__no_comments_.snap",
    "content": "\n[TestPrinter/slots_(no_comments) - 1]\n## Input\n\n```\n/-/-/-/\nimport Component from 'test';\n/-/-/-/\n<Component>\n    <div>Default</div>\n    <!-- A comment! -->\n    <div slot=\"named\">Named</div>\n</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport Component from 'test';\n\nimport * as $$module1 from 'test';\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`\n    ${$$maybeRenderHead($$result)}<div>Default</div>\n\n\n`,\"named\": () => $$render`<div>Named</div>`,})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/small_expression.snap",
    "content": "\n[TestPrinter/small_expression - 1]\n## Input\n\n```\n<div><small>{a}</small>{data.map(a => <Component value={a} />)}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div><small>${a}</small>${data.map(a => $$render`${$$renderComponent($$result,'Component',Component,{\"value\":(a)})}`)}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/solidus_in_template_literal_expression.snap",
    "content": "\n[TestPrinter/solidus_in_template_literal_expression - 1]\n## Input\n\n```\n<div value={`${attr ? `a/b` : \"c\"} awesome`} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute(`${attr ? `a/b` : \"c\"} awesome`, \"value\")}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/spread_with_double_quotation_marks.snap",
    "content": "\n[TestPrinter/spread_with_double_quotation_marks - 1]\n## Input\n\n```\n<div {...propsFn(\"string\")}/>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$spreadAttributes(propsFn(\"string\"))}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/spread_with_style_but_no_explicit_class.snap",
    "content": "\n[TestPrinter/spread_with_style_but_no_explicit_class - 1]\n## Input\n\n```\n<style>div { color: red; }</style><div {...Astro.props} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$spreadAttributes(Astro.props,undefined,{\"class\":\"astro-XXXX\"})}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/spread_without_style_or_class.snap",
    "content": "\n[TestPrinter/spread_without_style_or_class - 1]\n## Input\n\n```\n<div {...Astro.props} />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$spreadAttributes(Astro.props)}></div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/styles__no_frontmatter_.snap",
    "content": "\n[TestPrinter/styles_(no_frontmatter) - 1]\n## Input\n\n```\n<style>\n          .title {\n            font-family: fantasy;\n            font-size: 28px;\n          }\n\n          .body {\n            font-size: 1em;\n          }\n        </style>\n\n        <h1 class=\"title\">Page Title</h1>\n        <p class=\"body\">I’m a page</p>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`\n\n        ${$$maybeRenderHead($$result)}<h1 class=\"title astro-dpohflym\">Page Title</h1>\n        <p class=\"body astro-dpohflym\">I’m a page</p>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/svg_expressions.snap",
    "content": "\n[TestPrinter/svg_expressions - 1]\n## Input\n\n```\n/-/-/-/\nconst title = 'icon';\n/-/-/-/\n<svg>{title ?? null}</svg>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst title = 'icon';\n\nreturn $$render`${$$maybeRenderHead($$result)}<svg>${title ?? null}</svg>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table.snap",
    "content": "\n[TestPrinter/table - 1]\n## Input\n\n```\n<table><tr>{[0,1,2].map(x => (<td>{x}</td>))}</tr></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tr>${[0,1,2].map(x => ($$render`<td>${x}</td>`))}</tr></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_II.snap",
    "content": "\n[TestPrinter/table_II - 1]\n## Input\n\n```\n<table><thead><tr>{['Hey','Ho'].map((item)=> <th scope=\"col\">{item}</th>)}</tr></thead></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><thead><tr>${['Hey','Ho'].map((item)=> $$render`<th scope=\"col\">${item}</th>`)}</tr></thead></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_III.snap",
    "content": "\n[TestPrinter/table_III - 1]\n## Input\n\n```\n<table><tbody><tr><td>Cell</td><Cell /><Cell /><Cell /></tr></tbody></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tbody><tr><td>Cell</td>${$$renderComponent($$result,'Cell',Cell,{})}${$$renderComponent($$result,'Cell',Cell,{})}${$$renderComponent($$result,'Cell',Cell,{})}</tr></tbody></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_IV.snap",
    "content": "\n[TestPrinter/table_IV - 1]\n## Input\n\n```\n<body><div><tr><td>hello world</td></tr></div></body>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<body><div><tr><td>hello world</td></tr></div></body>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_caption_expression.snap",
    "content": "\n[TestPrinter/table_caption_expression - 1]\n## Input\n\n```\n<table><caption>{title}</caption><tr><td>Hello</td></tr></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><caption>${title}</caption><tr><td>Hello</td></tr></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_expression_with_trailing_div.snap",
    "content": "\n[TestPrinter/table_expression_with_trailing_div - 1]\n## Input\n\n```\n<table><tr><td>{title}</td></tr></table><div>Div</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tr><td>${title}</td></tr></table><div>Div</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_expressions__no_implicit_tbody_.snap",
    "content": "\n[TestPrinter/table_expressions_(no_implicit_tbody) - 1]\n## Input\n\n```\n/-/-/-/\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n/-/-/-/\n<table>{items.map(item => (<tr><td>{item}</td></tr>))}</table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n\nreturn $$render`${$$maybeRenderHead($$result)}<table>${items.map(item => ($$render`<tr><td>${item}</td></tr>`))}</table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_simple_case.snap",
    "content": "\n[TestPrinter/table_simple_case - 1]\n## Input\n\n```\n/-/-/-/\nconst content = \"lol\";\n/-/-/-/\n\n<html>\n  <body>\n    <table>\n      <tr>\n        <td>{content}</td>\n      </tr>\n      {\n        (\n          <tr>\n            <td>1</td>\n          </tr>\n        )\n      }\n    </table>Hello\n  </body>\n</html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst content = \"lol\";\n\nreturn $$render`<html>\n  ${$$maybeRenderHead($$result)}<body>\n    <table>\n      <tr>\n        <td>${content}</td>\n      </tr>\n      ${\n        (\n          $$render`<tr>\n            <td>1</td>\n          </tr>`\n        )\n      }\n    </table>Hello\n  </body></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_slot_I.snap",
    "content": "\n[TestPrinter/table_slot_I - 1]\n## Input\n\n```\n<table><slot /></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table>${$$renderSlot($$result,$$slots[\"default\"])}</table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_slot_II.snap",
    "content": "\n[TestPrinter/table_slot_II - 1]\n## Input\n\n```\n<table><tr><slot /></tr></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tr>${$$renderSlot($$result,$$slots[\"default\"])}</tr></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_slot_III.snap",
    "content": "\n[TestPrinter/table_slot_III - 1]\n## Input\n\n```\n<table><td><slot /></td></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><td>${$$renderSlot($$result,$$slots[\"default\"])}</td></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_slot_IV.snap",
    "content": "\n[TestPrinter/table_slot_IV - 1]\n## Input\n\n```\n<table><thead><slot /></thead></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><thead>${$$renderSlot($$result,$$slots[\"default\"])}</thead></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_slot_V.snap",
    "content": "\n[TestPrinter/table_slot_V - 1]\n## Input\n\n```\n<table><tbody><slot /></tbody></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tbody>${$$renderSlot($$result,$$slots[\"default\"])}</tbody></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/table_with_expression_in__th_.snap",
    "content": "\n[TestPrinter/table_with_expression_in_'th' - 1]\n## Input\n\n```\n/-/-/-/\nconst { title, footnotes, tables } = Astro.props;\n\ninterface Table {\n    title: string;\n    data: any[];\n    showTitle: boolean;\n    footnotes: string;\n}\nconsole.log(tables);\n/-/-/-/\n\n<div>\n    <div>\n    <h2>\n        {title}\n    </h2>\n    {\n        tables.map((table: Table) => (\n        <>\n            <div>\n            <h3 class=\"text-3xl sm:text-5xl font-bold\">{table.title}</h3>\n            <table>\n                <thead>\n                {Object.keys(table.data[0]).map((thead) => (\n                    <th>{thead}</th>\n                ))}\n                </thead>\n                <tbody>\n                {table.data.map((trow) => (\n                    <tr>\n                    {Object.values(trow).map((cell, index) => (\n                        <td>\n                        {cell}\n                        </td>\n                    ))}\n                    </tr>\n                ))}\n                </tbody>\n            </table>\n            </div>\n        </>\n        ))\n    }\n    </div>\n</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nconst { title, footnotes, tables } = Astro.props;\n\ninterface Table {\n    title: string;\n    data: any[];\n    showTitle: boolean;\n    footnotes: string;\n}\nconsole.log(tables);\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>\n    <div>\n    <h2>\n        ${title}\n    </h2>\n    ${\n        tables.map((table: Table) => (\n        $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`\n            <div>\n            <h3 class=\"text-3xl sm:text-5xl font-bold\">${table.title}</h3>\n            <table>\n                <thead>\n                ${Object.keys(table.data[0]).map((thead) => (\n                    $$render`<th>${thead}</th>`\n                ))}\n                </thead>\n                <tbody>\n                ${table.data.map((trow) => (\n                    $$render`<tr>\n                    ${Object.values(trow).map((cell, index) => (\n                        $$render`<td>\n                        ${cell}\n                        </td>`\n                    ))}\n                    </tr>`\n                ))}\n                </tbody>\n            </table>\n            </div>\n        `,})}`\n        ))\n    }\n    </div>\n</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/tbody_expressions.snap",
    "content": "\n[TestPrinter/tbody_expressions - 1]\n## Input\n\n```\n/-/-/-/\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n/-/-/-/\n<table><tr><td>Name</td></tr>{items.map(item => (<tr><td>{item}</td></tr>))}</table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tr><td>Name</td></tr>${items.map(item => ($$render`<tr><td>${item}</td></tr>`))}</table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/tbody_expressions_2.snap",
    "content": "\n[TestPrinter/tbody_expressions_2 - 1]\n## Input\n\n```\n/-/-/-/\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n/-/-/-/\n<table><tr><td>Name</td></tr>{items.map(item => (<tr><td>{item}</td><td>{item + 's'}</td></tr>))}</table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tr><td>Name</td></tr>${items.map(item => ($$render`<tr><td>${item}</td><td>${item + 's'}</td></tr>`))}</table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/tbody_expressions_3.snap",
    "content": "\n[TestPrinter/tbody_expressions_3 - 1]\n## Input\n\n```\n<table><tbody>{rows.map(row => (<tr><td><strong>{row}</strong></td></tr>))}</tbody></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tbody>${rows.map(row => ($$render`<tr><td><strong>${row}</strong></td></tr>`))}</tbody></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/td_expressions.snap",
    "content": "\n[TestPrinter/td_expressions - 1]\n## Input\n\n```\n<table><tr><td><h2>Row 1</h2></td><td>{title}</td></tr></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><tr><td><h2>Row 1</h2></td><td>${title}</td></tr></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/td_expressions_II.snap",
    "content": "\n[TestPrinter/td_expressions_II - 1]\n## Input\n\n```\n<table>{data.map(row => <tr>{row.map(cell => <td>{cell}</td>)}</tr>)}</table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table>${data.map(row => $$render`<tr>${row.map(cell => $$render`<td>${cell}</td>`)}</tr>`)}</table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/template_literal_attribute_on_component.snap",
    "content": "\n[TestPrinter/template_literal_attribute_on_component - 1]\n## Input\n\n```\n<Component class=`red` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{\"class\":`red`})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/template_literal_attribute_with_variable_on_component.snap",
    "content": "\n[TestPrinter/template_literal_attribute_with_variable_on_component - 1]\n## Input\n\n```\n<Component class=`${color}` />\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{\"class\":`${color}`})}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/ternary_component.snap",
    "content": "\n[TestPrinter/ternary_component - 1]\n## Input\n\n```\n{special ? <ChildDiv><p>Special</p></ChildDiv> : <p>Not special</p>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${special ? $$render`${$$renderComponent($$result,'ChildDiv',ChildDiv,{},{\"default\": () => $$render`${$$maybeRenderHead($$result)}<p>Special</p>`,})}` : $$render`<p>Not special</p>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/ternary_layout.snap",
    "content": "\n[TestPrinter/ternary_layout - 1]\n## Input\n\n```\n{toggleError ? <BaseLayout><h1>SITE: {Astro.site}</h1></BaseLayout> : <><h1>SITE: {Astro.site}</h1></>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Astro = $$createAstro('https://astro.build');\nconst Astro = $$Astro;\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\nconst Astro = $$result.createAstro($$props, $$slots);\nAstro.self = $$Component;\n\nreturn $$render`${toggleError ? $$render`${$$renderComponent($$result,'BaseLayout',BaseLayout,{},{\"default\": () => $$render`${$$maybeRenderHead($$result)}<h1>SITE: ${Astro.site}</h1>`,})}` : $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{\"default\": () => $$render`<h1>SITE: ${Astro.site}</h1>`,})}`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/ternary_slot.snap",
    "content": "\n[TestPrinter/ternary_slot - 1]\n## Input\n\n```\n<Component>{Math.random() > 0.5 ? <div slot=\"a\">A</div> : <div slot=\"b\">B</div>}</Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{},$$mergeSlots({},Math.random() > 0.5 ? {\"a\": () => $$render`${$$maybeRenderHead($$result)}<div>A</div>`} : {\"b\": () => $$render`<div>B</div>`}))}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/text_after_title_expression.snap",
    "content": "\n[TestPrinter/text_after_title_expression - 1]\n## Input\n\n```\n<title>a {expr} b</title>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<title>a ${expr} b</title>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/text_after_title_expressions.snap",
    "content": "\n[TestPrinter/text_after_title_expressions - 1]\n## Input\n\n```\n<title>a {expr} b {expr} c</title>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<title>a ${expr} b ${expr} c</title>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/text_only.snap",
    "content": "\n[TestPrinter/text_only - 1]\n## Input\n\n```\nFoo\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`Foo`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n\n[TestPrinter/text_only#01 - 1]\n## Input\n\n```\nHello!\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`Hello!`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/textarea.snap",
    "content": "\n[TestPrinter/textarea - 1]\n## Input\n\n```\n/-/-/-/\nconst value = 'test';\n/-/-/-/\n<textarea>{value}</textarea>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nconst value = 'test';\n\nreturn $$render`${$$maybeRenderHead($$result)}<textarea>${value}</textarea>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/textarea_in_form.snap",
    "content": "\n[TestPrinter/textarea_in_form - 1]\n## Input\n\n```\n<html><Component><form><textarea></textarea></form></Component></html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html>${$$renderComponent($$result,'Component',Component,{},{\"default\": () => $$render`${$$maybeRenderHead($$result)}<form><textarea></textarea></form>`,})}</html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/textarea_inside_expression.snap",
    "content": "\n[TestPrinter/textarea_inside_expression - 1]\n## Input\n\n```\n{bool && <textarea>{value}</textarea>} {!bool && <input>}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${bool && $$render`${$$maybeRenderHead($$result)}<textarea>${value}</textarea>`} ${!bool && $$render`<input>`}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/th_expressions.snap",
    "content": "\n[TestPrinter/th_expressions - 1]\n## Input\n\n```\n<table><thead><tr><th>{title}</th></tr></thead></table>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<table><thead><tr><th>${title}</th></tr></thead></table>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/tr_only.snap",
    "content": "\n[TestPrinter/tr_only - 1]\n## Input\n\n```\n<tr><td>col 1</td><td>col 2</td><td>{foo}</td></tr>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<tr><td>col 1</td><td>col 2</td><td>${foo}</td></tr>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/trailing_expression.snap",
    "content": "\n[TestPrinter/trailing_expression - 1]\n## Input\n\n```\n<Component />{}\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{})}${(void 0)}`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/transition_animate_on_Component.snap",
    "content": "\n[TestPrinter/transition:animate_on_Component - 1]\n## Input\n\n```\n<Component class=\"bar\" transition:animate=\"morph\"></Component>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport \"transitions.css\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/pages/page.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Page = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'Component',Component,{\"class\":\"bar\",\"data-astro-transition-scope\":($$renderTransition($$result, \"wkm5vset\", \"morph\", \"\"))})}`;\n}, '/projects/app/src/pages/page.astro', 'self');\nexport default $$Page;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/transition_animate_with_an_expression.snap",
    "content": "\n[TestPrinter/transition:animate_with_an_expression - 1]\n## Input\n\n```\n<div transition:animate={slide({duration:15})}></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport \"transitions.css\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/pages/page.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Page = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute($$renderTransition($$result, \"ih7yuffh\", (slide({duration:15})), \"\"), \"data-astro-transition-scope\")}></div>`;\n}, '/projects/app/src/pages/page.astro', 'self');\nexport default $$Page;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/transition_name_with_an_expression.snap",
    "content": "\n[TestPrinter/transition:name_with_an_expression - 1]\n## Input\n\n```\n<div transition:name={one + '-' + 'two'}></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport \"transitions.css\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/pages/page.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Page = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute($$renderTransition($$result, \"daiq24ry\", \"\", (one + '-' + 'two')), \"data-astro-transition-scope\")}></div>`;\n}, '/projects/app/src/pages/page.astro', 'self');\nexport default $$Page;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/transition_name_with_an_template_literal.snap",
    "content": "\n[TestPrinter/transition:name_with_an_template_literal - 1]\n## Input\n\n```\n<div transition:name=`${one}-two`></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport \"transitions.css\";\n\nexport const $$metadata = $$createMetadata(\"/projects/app/src/pages/page.astro\", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Page = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute($$renderTransition($$result, \"vvov4lyr\", \"\", `${one}-two`), \"data-astro-transition-scope\")}></div>`;\n}, '/projects/app/src/pages/page.astro', 'self');\nexport default $$Page;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/transition_persist-props_converted_to_a_data_attribute.snap",
    "content": "\n[TestPrinter/transition:persist-props_converted_to_a_data_attribute - 1]\n## Input\n\n```\n<my-island transition:persist transition:persist-props=\"false\"></my-island>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport \"transitions.css\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$renderComponent($$result,'my-island','my-island',{\"data-astro-transition-persist-props\":\"false\",\"data-astro-transition-persist\":($$createTransitionScope($$result, \"otghnj5u\"))})}`;\n}, undefined, 'self');\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/transition_persist_converted_to_a_data_attribute.snap",
    "content": "\n[TestPrinter/transition:persist_converted_to_a_data_attribute - 1]\n## Input\n\n```\n<div transition:persist></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport \"transitions.css\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div${$$addAttribute($$createTransitionScope($$result, \"pflz5ime\"), \"data-astro-transition-persist\")}></div>`;\n}, undefined, 'self');\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/transition_persist_uses_transition_name_if_defined.snap",
    "content": "\n[TestPrinter/transition:persist_uses_transition:name_if_defined - 1]\n## Input\n\n```\n<div transition:persist transition:name=\"foo\"></div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport \"transitions.css\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div data-astro-transition-persist=\"foo\"${$$addAttribute($$renderTransition($$result, \"peuy4xf7\", \"\", \"foo\"), \"data-astro-transition-scope\")}></div>`;\n}, undefined, 'self');\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/type_import.snap",
    "content": "\n[TestPrinter/type_import - 1]\n## Input\n\n```\n/-/-/-/\nimport type data from \"test\"\n/-/-/-/\n\n<div>{data}</div>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\nimport type data from \"test\"\n\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`${$$maybeRenderHead($$result)}<div>${data}</div>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/unusual_line_terminator_I.snap",
    "content": "\n[TestPrinter/unusual_line_terminator_I - 1]\n## Input\n\n```\nPre-set & Time-limited \\u2028holiday campaigns\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`Pre-set & Time-limited \\\\u2028holiday campaigns`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/unusual_line_terminator_II.snap",
    "content": "\n[TestPrinter/unusual_line_terminator_II - 1]\n## Input\n\n```\nPre-set & Time-limited  holiday campaigns\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`Pre-set & Time-limited  holiday campaigns`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_js__/user-defined__implicit__is_printed.snap",
    "content": "\n[TestPrinter/user-defined_`implicit`_is_printed - 1]\n## Input\n\n```\n<html implicit></html>\n```\n\n## Output\n\n```js\nimport {\n  Fragment,\n  render as $$render,\n  createAstro as $$createAstro,\n  createComponent as $$createComponent,\n  renderComponent as $$renderComponent,\n  renderHead as $$renderHead,\n  maybeRenderHead as $$maybeRenderHead,\n  unescapeHTML as $$unescapeHTML,\n  renderSlot as $$renderSlot,\n  mergeSlots as $$mergeSlots,\n  addAttribute as $$addAttribute,\n  spreadAttributes as $$spreadAttributes,\n  defineStyleVars as $$defineStyleVars,\n  defineScriptVars as $$defineScriptVars,\n  renderTransition as $$renderTransition,\n  createTransitionScope as $$createTransitionScope,\n  renderScript as $$renderScript,\n  createMetadata as $$createMetadata\n} from \"http://localhost:3000/\";\n\nexport const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });\n\nconst $$Component = $$createComponent(($$result, $$props, $$slots) => {\n\nreturn $$render`<html implicit></html>`;\n}, undefined, undefined);\nexport default $$Component;\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Comment.snap",
    "content": "\n[TestPrintToJSON/Comment - 1]\n## Input\n\n```\n<!--hello-->\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"comment\",\"value\":\"hello\"}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Comment_preserves_whitespace.snap",
    "content": "\n[TestPrintToJSON/Comment_preserves_whitespace - 1]\n## Input\n\n```\n<!-- hello -->\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"comment\",\"value\":\" hello \"}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Component.snap",
    "content": "\n[TestPrintToJSON/Component - 1]\n## Input\n\n```\n<Component />\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"component\",\"name\":\"Component\",\"attributes\":[],\"children\":[]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Doctype.snap",
    "content": "\n[TestPrintToJSON/Doctype - 1]\n## Input\n\n```\n<!DOCTYPE html />\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"doctype\",\"value\":\"html\"}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Fragment_Literal.snap",
    "content": "\n[TestPrintToJSON/Fragment_Literal - 1]\n## Input\n\n```\n<Fragment>World</Fragment>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"fragment\",\"name\":\"Fragment\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"World\"}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Fragment_Shorthand.snap",
    "content": "\n[TestPrintToJSON/Fragment_Shorthand - 1]\n## Input\n\n```\n<>Hello</>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"fragment\",\"name\":\"\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"Hello\"}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Frontmatter.snap",
    "content": "\n[TestPrintToJSON/Frontmatter - 1]\n## Input\n\n```\n/-/-/-/\nconst a = \"hey\"\n/-/-/-/\n<div>{a}</div>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"frontmatter\",\"value\":\"\\nconst a = \\\"hey\\\"\\n\"},{\"type\":\"element\",\"name\":\"div\",\"attributes\":[],\"children\":[{\"type\":\"expression\",\"children\":[{\"type\":\"text\",\"value\":\"a\"}]}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/JSON_escape.snap",
    "content": "\n[TestPrintToJSON/JSON_escape - 1]\n## Input\n\n```\n/-/-/-/\nconst a = \"\\n\"\nconst b = \"\\\"\"\nconst c = '\\''\n/-/-/-/\n{a + b + c}\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"frontmatter\",\"value\":\"\\nconst a = \\\"\\\\n\\\"\\nconst b = \\\"\\\\\\\"\\\"\\nconst c = '\\\\''\\n\"},{\"type\":\"expression\",\"children\":[{\"type\":\"text\",\"value\":\"a + b + c\"}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/Preserve_namespaces.snap",
    "content": "\n[TestPrintToJSON/Preserve_namespaces - 1]\n## Input\n\n```\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect xlink:href=\"#id\"></svg>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"svg\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"xmlns\",\"value\":\"http://www.w3.org/2000/svg\",\"raw\":\"\\\"http://www.w3.org/2000/svg\\\"\"},{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"xmlns:xlink\",\"value\":\"http://www.w3.org/1999/xlink\",\"raw\":\"\\\"http://www.w3.org/1999/xlink\\\"\"}],\"children\":[{\"type\":\"element\",\"name\":\"rect\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"xlink:href\",\"value\":\"#id\",\"raw\":\"\\\"#id\\\"\"}],\"children\":[]}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/basic.snap",
    "content": "\n[TestPrintToJSON/basic - 1]\n## Input\n\n```\n<h1>Hello world!</h1>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"h1\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"Hello world!\"}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/custom-element.snap",
    "content": "\n[TestPrintToJSON/custom-element - 1]\n## Input\n\n```\n<custom-element />\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"custom-element\",\"name\":\"custom-element\",\"attributes\":[],\"children\":[]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/element_with_unterminated_double_quote_attribute.snap",
    "content": "\n[TestPrintToJSON/element_with_unterminated_double_quote_attribute - 1]\n## Input\n\n```\n<main id=\"gotcha />\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"main\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"id\",\"value\":\"gotcha\",\"raw\":\"\\\"gotcha\"}],\"children\":[]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/element_with_unterminated_single_quote_attribute.snap",
    "content": "\n[TestPrintToJSON/element_with_unterminated_single_quote_attribute - 1]\n## Input\n\n```\n<main id='gotcha />\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"main\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"id\",\"value\":\"gotcha\",\"raw\":\"'gotcha\"}],\"children\":[]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/element_with_unterminated_template_literal_attribute.snap",
    "content": "\n[TestPrintToJSON/element_with_unterminated_template_literal_attribute - 1]\n## Input\n\n```\n<main id=`gotcha />\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"main\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"template-literal\",\"name\":\"id\",\"value\":\"gotcha\",\"raw\":\"`gotcha\"}],\"children\":[]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/expression.snap",
    "content": "\n[TestPrintToJSON/expression - 1]\n## Input\n\n```\n<h1>Hello {world}</h1>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"h1\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"Hello \"},{\"type\":\"expression\",\"children\":[{\"type\":\"text\",\"value\":\"world\"}]}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/jsx_comment_between_doctype_and_html.snap",
    "content": "\n[TestPrintToJSON/jsx_comment_between_doctype_and_html - 1]\n## Input\n\n```\n<!doctype html>\n{/* Comment */}\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n    </head>\n</html>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"doctype\",\"value\":\"html\"},{\"type\":\"expression\",\"children\":[{\"type\":\"text\",\"value\":\"/* Comment */\"}]},{\"type\":\"text\",\"value\":\"\\n\"},{\"type\":\"element\",\"name\":\"html\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"lang\",\"value\":\"en\",\"raw\":\"\\\"en\\\"\"}],\"children\":[{\"type\":\"text\",\"value\":\"\\n\\t\"},{\"type\":\"element\",\"name\":\"head\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"\\n\\t\\t\"},{\"type\":\"element\",\"name\":\"meta\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"charset\",\"value\":\"UTF-8\",\"raw\":\"\\\"UTF-8\\\"\"}],\"children\":[]},{\"type\":\"text\",\"value\":\"\\n\\t\"}]},{\"type\":\"text\",\"value\":\"\\n\"}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_after_body_with_component_in_head_and_body.snap",
    "content": "\n[TestPrintToJSON/style_after_body_with_component_in_head_and_body - 1]\n## Input\n\n```\n<html lang=\"en\"><head><BaseHead /></head><body><Header /></body><style>@use \"../styles/global.scss\";</style></html>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"html\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"lang\",\"value\":\"en\",\"raw\":\"\\\"en\\\"\"}],\"children\":[{\"type\":\"element\",\"name\":\"head\",\"attributes\":[],\"children\":[{\"type\":\"component\",\"name\":\"BaseHead\",\"attributes\":[],\"children\":[]}]},{\"type\":\"element\",\"name\":\"body\",\"attributes\":[],\"children\":[{\"type\":\"component\",\"name\":\"Header\",\"attributes\":[],\"children\":[]}]},{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"@use \\\"../styles/global.scss\\\";\"}]}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_after_empty_html.snap",
    "content": "\n[TestPrintToJSON/style_after_empty_html - 1]\n## Input\n\n```\n<html></html><style></style>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"html\",\"attributes\":[],\"children\":[]},{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_after_html.snap",
    "content": "\n[TestPrintToJSON/style_after_html - 1]\n## Input\n\n```\n<html><body><h1>Hello world!</h1></body></html><style></style>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"html\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"body\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"h1\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"Hello world!\"}]}]}]},{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_after_html_with_component_in_head.snap",
    "content": "\n[TestPrintToJSON/style_after_html_with_component_in_head - 1]\n## Input\n\n```\n<html lang=\"en\"><head><BaseHead /></head></html><style>@use \"../styles/global.scss\";</style>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"html\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"lang\",\"value\":\"en\",\"raw\":\"\\\"en\\\"\"}],\"children\":[{\"type\":\"element\",\"name\":\"head\",\"attributes\":[],\"children\":[{\"type\":\"component\",\"name\":\"BaseHead\",\"attributes\":[],\"children\":[]}]}]},{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"@use \\\"../styles/global.scss\\\";\"}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_after_html_with_component_in_head_and_body.snap",
    "content": "\n[TestPrintToJSON/style_after_html_with_component_in_head_and_body - 1]\n## Input\n\n```\n<html lang=\"en\"><head><BaseHead /></head><body><Header /></body></html><style>@use \"../styles/global.scss\";</style>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"html\",\"attributes\":[{\"type\":\"attribute\",\"kind\":\"quoted\",\"name\":\"lang\",\"value\":\"en\",\"raw\":\"\\\"en\\\"\"}],\"children\":[{\"type\":\"element\",\"name\":\"head\",\"attributes\":[],\"children\":[{\"type\":\"component\",\"name\":\"BaseHead\",\"attributes\":[],\"children\":[]}]},{\"type\":\"element\",\"name\":\"body\",\"attributes\":[],\"children\":[{\"type\":\"component\",\"name\":\"Header\",\"attributes\":[],\"children\":[]}]}]},{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"@use \\\"../styles/global.scss\\\";\"}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_before_html.snap",
    "content": "\n[TestPrintToJSON/style_before_html - 1]\n## Input\n\n```\n<style></style><html><body><h1>Hello world!</h1></body></html>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[]},{\"type\":\"element\",\"name\":\"html\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"body\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"h1\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"Hello world!\"}]}]}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_in_body.snap",
    "content": "\n[TestPrintToJSON/style_in_body - 1]\n## Input\n\n```\n<html><body><h1>Hello world!</h1><style></style></body></html>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"html\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"body\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"h1\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"Hello world!\"}]},{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[]}]}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/__printer_json__/style_in_html.snap",
    "content": "\n[TestPrintToJSON/style_in_html - 1]\n## Input\n\n```\n<html><body><h1>Hello world!</h1></body><style></style></html>\n```\n\n## Output\n\n```json\n{\"type\":\"root\",\"children\":[{\"type\":\"element\",\"name\":\"html\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"body\",\"attributes\":[],\"children\":[{\"type\":\"element\",\"name\":\"h1\",\"attributes\":[],\"children\":[{\"type\":\"text\",\"value\":\"Hello world!\"}]}]},{\"type\":\"element\",\"name\":\"style\",\"attributes\":[],\"children\":[]}]}]}\n```\n---\n"
  },
  {
    "path": "internal/printer/print-css.go",
    "content": "package printer\n\nimport (\n\t\"strings\"\n\n\t. \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/sourcemap\"\n\t\"github.com/withastro/compiler/internal/transform\"\n)\n\ntype PrintCSSResult struct {\n\tOutput         [][]byte\n\tSourceMapChunk sourcemap.Chunk\n}\n\nfunc PrintCSS(sourcetext string, doc *Node, opts transform.TransformOptions) PrintCSSResult {\n\tp := &printer{\n\t\topts:    opts,\n\t\tbuilder: sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(sourcetext, len(strings.Split(sourcetext, \"\\n\")))),\n\t}\n\n\tresult := PrintCSSResult{\n\t\tSourceMapChunk: p.builder.GenerateChunk(p.output),\n\t}\n\n\tif len(doc.Styles) > 0 {\n\t\tfor _, style := range doc.Styles {\n\t\t\tif style.FirstChild != nil && strings.TrimSpace(style.FirstChild.Data) != \"\" {\n\t\t\t\tp.addSourceMapping(style.Loc[0])\n\t\t\t\tp.print(strings.TrimSpace(style.FirstChild.Data))\n\t\t\t\tresult.Output = append(result.Output, p.output)\n\t\t\t\tp.output = []byte{}\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result\n}\n"
  },
  {
    "path": "internal/printer/print-to-js.go",
    "content": "// Copyright 2011 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage printer\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"unicode\"\n\n\t. \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/helpers\"\n\t\"github.com/withastro/compiler/internal/js_scanner\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"github.com/withastro/compiler/internal/sourcemap\"\n\t\"github.com/withastro/compiler/internal/transform\"\n\t\"golang.org/x/net/html/atom\"\n)\n\n// Render renders the parse tree n to the given writer.\n//\n// Rendering is done on a 'best effort' basis: calling Parse on the output of\n// Render will always result in something similar to the original tree, but it\n// is not necessarily an exact clone unless the original tree was 'well-formed'.\n// 'Well-formed' is not easily specified; the HTML5 specification is\n// complicated.\n//\n// Calling Parse on arbitrary input typically results in a 'well-formed' parse\n// tree. However, it is possible for Parse to yield a 'badly-formed' parse tree.\n// For example, in a 'well-formed' parse tree, no <a> element is a child of\n// another <a> element: parsing \"<a><a>\" results in two sibling elements.\n// Similarly, in a 'well-formed' parse tree, no <a> element is a child of a\n// <table> element: parsing \"<p><table><a>\" results in a <p> with two sibling\n// children; the <a> is reparented to the <table>'s parent. However, calling\n// Parse on \"<a><table><a>\" does not return an error, but the result has an <a>\n// element with an <a> child, and is therefore not 'well-formed'.\n//\n// Programmatically constructed trees are typically also 'well-formed', but it\n// is possible to construct a tree that looks innocuous but, when rendered and\n// re-parsed, results in a different tree. A simple example is that a solitary\n// text node would become a tree containing <html>, <head> and <body> elements.\n// Another example is that the programmatic equivalent of \"a<head>b</head>c\"\n// becomes \"<html><head><head/><body>abc</body></html>\".\nfunc PrintToJS(sourcetext string, n *Node, cssLen int, opts transform.TransformOptions, h *handler.Handler) PrintResult {\n\tp := &printer{\n\t\tsourcetext: sourcetext,\n\t\topts:       opts,\n\t\tbuilder:    sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(sourcetext, len(strings.Split(sourcetext, \"\\n\")))),\n\t\thandler:    h,\n\t}\n\treturn printToJs(p, n, cssLen, opts)\n}\n\ntype RenderOptions struct {\n\tisRoot           bool\n\tisExpression     bool\n\tdepth            int\n\tcssLen           int\n\topts             transform.TransformOptions\n\tprintedMaybeHead *bool\n\tscriptCount      *int\n}\n\ntype ExtractedStatement struct {\n\tContent string\n\tLoc     loc.Loc\n}\n\nfunc printToJs(p *printer, n *Node, cssLen int, opts transform.TransformOptions) PrintResult {\n\tprintedMaybeHead := false\n\tscriptCount := 0\n\trender1(p, n, RenderOptions{\n\t\tcssLen:           cssLen,\n\t\tisRoot:           true,\n\t\tisExpression:     false,\n\t\tdepth:            0,\n\t\topts:             opts,\n\t\tprintedMaybeHead: &printedMaybeHead,\n\t\tscriptCount:      &scriptCount,\n\t})\n\n\treturn PrintResult{\n\t\tOutput:         p.output,\n\t\tSourceMapChunk: p.builder.GenerateChunk(p.output),\n\t}\n}\n\nconst whitespace = \" \\t\\r\\n\\f\"\n\n// Returns true if the expression only contains a comment block (e.g. {/* a comment */})\nfunc expressionOnlyHasComment(n *Node) bool {\n\tif n.FirstChild == nil {\n\t\treturn false\n\t}\n\tclean := helpers.RemoveComments(n.FirstChild.Data)\n\ttrimmedData := strings.TrimLeft(n.FirstChild.Data, whitespace)\n\tresult := n.FirstChild.NextSibling == nil &&\n\t\tn.FirstChild.Type == TextNode &&\n\t\t// RemoveComments iterates over text and most of the time we won't be parsing comments so lets check if text starts with /* or // before iterating\n\t\t(strings.HasPrefix(trimmedData, \"/*\") || strings.HasPrefix(trimmedData, \"//\")) &&\n\t\tlen(clean) == 0\n\treturn result\n}\n\nfunc emptyTextNodeWithoutSiblings(n *Node) bool {\n\tif strings.TrimSpace(n.Data) != \"\" {\n\t\treturn false\n\t}\n\tif n.PrevSibling == nil {\n\t\treturn n.NextSibling == nil || n.NextSibling.Expression\n\t} else {\n\t\treturn n.PrevSibling.Expression\n\t}\n}\n\nfunc render1(p *printer, n *Node, opts RenderOptions) {\n\tdepth := opts.depth\n\n\tif n.Transition {\n\t\tp.needsTransitionCSS = true\n\t}\n\n\t// Root of the document, print all children\n\tif n.Type == DocumentNode {\n\t\tp.printInternalImports(p.opts.InternalURL, &opts)\n\t\tif n.FirstChild != nil && n.FirstChild.Type != FrontmatterNode {\n\t\t\tp.printCSSImports(opts.cssLen)\n\t\t}\n\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\trender1(p, c, RenderOptions{\n\t\t\t\tisRoot:           false,\n\t\t\t\tisExpression:     false,\n\t\t\t\tdepth:            depth + 1,\n\t\t\t\topts:             opts.opts,\n\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t})\n\t\t}\n\n\t\tp.printReturnClose()\n\t\tp.printFuncSuffix(opts.opts, n)\n\t\treturn\n\t}\n\n\t// Decide whether to print code for `Astro` global variable. Use a loose check for now.\n\tprintAstroGlobal := strings.Contains(p.sourcetext, \"Astro\")\n\n\t// Render frontmatter (will be the first node, if it exists)\n\tif n.Type == FrontmatterNode {\n\t\tif n.FirstChild == nil {\n\t\t\tp.printCSSImports(opts.cssLen)\n\t\t}\n\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif c.Type == TextNode {\n\t\t\t\tp.printInternalImports(p.opts.InternalURL, &opts)\n\n\t\t\t\tstart := 0\n\t\t\t\tif len(n.Loc) > 0 {\n\t\t\t\t\tstart = c.Loc[0].Start\n\t\t\t\t}\n\t\t\t\trender := js_scanner.HoistImports([]byte(c.Data))\n\t\t\t\tif len(render.Hoisted) > 0 {\n\t\t\t\t\tfor i, hoisted := range render.Hoisted {\n\t\t\t\t\t\tif len(bytes.TrimSpace(hoisted)) == 0 {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\thoistedLoc := render.HoistedLocs[i]\n\t\t\t\t\t\tp.printTextWithSourcemap(string(hoisted)+\"\\n\", loc.Loc{Start: start + hoistedLoc.Start})\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.printCSSImports(opts.cssLen)\n\n\t\t\t\t// 1. Component imports, if any exist.\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.printComponentMetadata(n.Parent, opts.opts, []byte(p.sourcetext))\n\n\t\t\t\t// 2. Top-level Astro global.\n\t\t\t\tif printAstroGlobal {\n\t\t\t\t\tp.printTopLevelAstro(opts.opts)\n\t\t\t\t}\n\n\t\t\t\texports := make([][]byte, 0)\n\t\t\t\texportLocs := make([]loc.Loc, 0)\n\t\t\t\tbodies := make([][]byte, 0)\n\t\t\t\tbodiesLocs := make([]loc.Loc, 0)\n\n\t\t\t\tif len(render.Body) > 0 {\n\t\t\t\t\tfor i, innerBody := range render.Body {\n\t\t\t\t\t\tinnerStart := render.BodyLocs[i].Start\n\t\t\t\t\t\tif len(bytes.TrimSpace(innerBody)) == 0 {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Extract exports\n\t\t\t\t\t\tpreprocessed := js_scanner.HoistExports(append(innerBody, '\\n'))\n\t\t\t\t\t\tif len(preprocessed.Hoisted) > 0 {\n\t\t\t\t\t\t\tfor j, exported := range preprocessed.Hoisted {\n\t\t\t\t\t\t\t\texportedLoc := preprocessed.HoistedLocs[j]\n\t\t\t\t\t\t\t\texportLocs = append(exportLocs, loc.Loc{Start: start + innerStart + exportedLoc.Start})\n\t\t\t\t\t\t\t\texports = append(exports, exported)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif len(preprocessed.Body) > 0 {\n\t\t\t\t\t\t\tfor j, body := range preprocessed.Body {\n\t\t\t\t\t\t\t\tbodyLoc := preprocessed.BodyLocs[j]\n\t\t\t\t\t\t\t\tbodiesLocs = append(bodiesLocs, loc.Loc{Start: start + innerStart + bodyLoc.Start})\n\t\t\t\t\t\t\t\tbodies = append(bodies, body)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// PRINT EXPORTS\n\t\t\t\tif len(exports) > 0 {\n\t\t\t\t\tfor i, exported := range exports {\n\t\t\t\t\t\texportLoc := exportLocs[i]\n\t\t\t\t\t\tif len(bytes.TrimSpace(exported)) == 0 {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.printTextWithSourcemap(string(exported), exportLoc)\n\t\t\t\t\t\tp.addNilSourceMapping()\n\t\t\t\t\t\tp.println(\"\")\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tp.printFuncPrelude(opts.opts, printAstroGlobal)\n\t\t\t\t// PRINT BODY\n\t\t\t\tif len(bodies) > 0 {\n\t\t\t\t\tfor i, body := range bodies {\n\t\t\t\t\t\tbodyLoc := bodiesLocs[i]\n\t\t\t\t\t\tif len(bytes.TrimSpace(body)) == 0 {\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.printTextWithSourcemap(string(body), bodyLoc)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Print empty just to ensure a newline\n\t\t\t\tp.println(\"\")\n\t\t\t\tif len(n.Parent.Styles) > 0 {\n\t\t\t\t\tdefinedVars := transform.GetDefineVars(n.Parent.Styles)\n\t\t\t\t\tif len(definedVars) > 0 {\n\t\t\t\t\t\tp.printf(\"const $$definedVars = %s([%s]);\\n\", DEFINE_STYLE_VARS, strings.Join(definedVars, \",\"))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tp.printReturnOpen()\n\t\t\t} else {\n\t\t\t\trender1(p, c, RenderOptions{\n\t\t\t\t\tisRoot:           false,\n\t\t\t\t\tisExpression:     true,\n\t\t\t\t\tdepth:            depth + 1,\n\t\t\t\t\topts:             opts.opts,\n\t\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t\t})\n\t\t\t\tif len(n.Loc) > 1 {\n\t\t\t\t\tp.addSourceMapping(loc.Loc{Start: n.Loc[1].Start - 3})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn\n\t} else if !p.hasFuncPrelude {\n\t\tp.printComponentMetadata(n.Parent, opts.opts, []byte{})\n\t\tif printAstroGlobal {\n\t\t\tp.printTopLevelAstro(opts.opts)\n\t\t}\n\n\t\t// Render func prelude. Will only run for the first non-frontmatter node\n\t\tp.printFuncPrelude(opts.opts, printAstroGlobal)\n\t\t// This just ensures a newline\n\t\tp.println(\"\")\n\n\t\t// If we haven't printed the funcPrelude but we do have Styles/Scripts, we need to print them!\n\t\tif len(n.Parent.Styles) > 0 {\n\t\t\tdefinedVars := transform.GetDefineVars(n.Parent.Styles)\n\t\t\tif len(definedVars) > 0 {\n\t\t\t\tp.printf(\"const $$definedVars = %s([%s]);\\n\", DEFINE_STYLE_VARS, strings.Join(definedVars, \",\"))\n\t\t\t}\n\t\t}\n\n\t\tp.printReturnOpen()\n\t}\n\tswitch n.Type {\n\tcase TextNode:\n\t\tif strings.TrimSpace(n.Data) == \"\" {\n\t\t\tp.addSourceMapping(n.Loc[0])\n\t\t\tp.print(n.Data)\n\t\t\treturn\n\t\t}\n\t\ttext := escapeText(n.Data)\n\t\tp.printTextWithSourcemap(text, n.Loc[0])\n\t\treturn\n\tcase ElementNode:\n\t\t// No-op.\n\tcase CommentNode:\n\t\tstart := n.Loc[0].Start - 4\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.print(\"<!--\")\n\t\tstart += 4\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.printTextWithSourcemap(escapeText(n.Data), n.Loc[0])\n\t\tstart += len(n.Data)\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.print(\"-->\")\n\t\treturn\n\tcase DoctypeNode:\n\t\t// Doctype doesn't get printed because the Astro runtime always appends it\n\t\treturn\n\tcase RawNode:\n\t\tp.print(n.Data)\n\t\treturn\n\tcase RenderHeadNode:\n\t\tp.printMaybeRenderHead()\n\t\t*opts.printedMaybeHead = true\n\t\treturn\n\t}\n\n\t// Tip! Comment this block out to debug expressions\n\tif n.Expression {\n\t\tif n.FirstChild == nil || emptyTextNodeWithoutSiblings(n.FirstChild) {\n\t\t\tp.print(\"${(void 0)\")\n\t\t} else if expressionOnlyHasComment(n) {\n\t\t\t// we do not print expressions that only contain comment blocks\n\t\t\treturn\n\t\t} else {\n\t\t\tp.print(\"${\")\n\t\t}\n\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tp.addSourceMapping(c.Loc[0])\n\t\t\tif c.Type == TextNode {\n\t\t\t\tp.printTextWithSourcemap(c.Data, c.Loc[0])\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Print the opening of a tagged render function before\n\t\t\t// a node, only when it meets either of these conditions:\n\t\t\t// - It does not have a previous sibling.\n\t\t\t// - It has a text node that contains more than just whitespace.\n\t\t\t// - It is the first child of its parent expression.\n\t\t\tif c.PrevSibling == nil || c.PrevSibling == n.FirstChild || (c.PrevSibling.Type == TextNode && strings.TrimSpace(c.PrevSibling.Data) != \"\") {\n\t\t\t\tp.printTemplateLiteralOpen()\n\t\t\t}\n\t\t\trender1(p, c, RenderOptions{\n\t\t\t\tisRoot:           false,\n\t\t\t\tisExpression:     true,\n\t\t\t\tdepth:            depth + 1,\n\t\t\t\topts:             opts.opts,\n\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t})\n\n\t\t\t// Print the closing of a tagged render function after\n\t\t\t// a node, only when it meets either of these conditions:\n\t\t\t// - It does not have a next sibling.\n\t\t\t// - It has a text node that contains more than just whitespace.\n\t\t\t// - It is the last child of its parent expression.\n\t\t\tif c.NextSibling == nil || c.NextSibling == n.LastChild || (c.NextSibling.Type == TextNode && strings.TrimSpace(c.NextSibling.Data) != \"\") {\n\t\t\t\tp.printTemplateLiteralClose()\n\t\t\t}\n\t\t}\n\t\tif len(n.Loc) >= 2 {\n\t\t\tp.addSourceMapping(n.Loc[1])\n\t\t}\n\t\tp.print(\"}\")\n\t\treturn\n\t}\n\n\tisFragment := n.Fragment\n\tisComponent := isFragment || n.Component || n.CustomElement\n\tisClientOnly := isComponent && transform.HasAttr(n, \"client:only\")\n\tisSlot := n.DataAtom == atom.Slot\n\tisImplicit := false\n\tisHandledScript := n.HandledScript\n\tfor _, a := range n.Attr {\n\t\tif isSlot && a.Key == \"is:inline\" {\n\t\t\tisSlot = false\n\t\t}\n\t\tif transform.IsImplicitNodeMarker(a) {\n\t\t\tisImplicit = true\n\t\t}\n\t}\n\n\tp.addSourceMapping(n.Loc[0])\n\tswitch true {\n\tcase isFragment:\n\t\tp.print(fmt.Sprintf(\"${%s(%s,'%s',\", RENDER_COMPONENT, RESULT, \"Fragment\"))\n\tcase isComponent:\n\t\tp.print(fmt.Sprintf(\"${%s(%s,'%s',\", RENDER_COMPONENT, RESULT, n.Data))\n\tcase isSlot:\n\t\tp.print(fmt.Sprintf(\"${%s(%s,%s[\", RENDER_SLOT, RESULT, SLOTS))\n\tcase isHandledScript:\n\t\t// import '/src/pages/index.astro?astro&type=script&index=0&lang.ts';\n\t\tscriptUrl := fmt.Sprintf(\"%s?astro&type=script&index=%v&lang.ts\", p.opts.Filename, *opts.scriptCount)\n\t\tresolvedScriptUrl := transform.ResolveIdForMatch(scriptUrl, &p.opts)\n\t\tescapedScriptUrl := escapeDoubleQuote(resolvedScriptUrl)\n\t\tp.print(fmt.Sprintf(\"${%s(%s,\\\"%s\\\")}\", RENDER_SCRIPT, RESULT, escapedScriptUrl))\n\t\t*opts.scriptCount++\n\t\treturn\n\tcase isImplicit:\n\t\t// do nothing\n\tdefault:\n\t\t// Before the first non-head element, inject $$maybeRender($$result)\n\t\t// This is for pages that do not contain an explicit head element\n\t\tswitch n.DataAtom {\n\t\tcase atom.Html, atom.Head, atom.Base, atom.Basefont, atom.Bgsound, atom.Link, atom.Meta, atom.Noframes, atom.Script, atom.Style, atom.Template, atom.Title:\n\t\t\tbreak\n\t\tdefault:\n\t\t\tif !*opts.printedMaybeHead {\n\t\t\t\t*opts.printedMaybeHead = true\n\t\t\t\tp.printMaybeRenderHead()\n\t\t\t}\n\t\t}\n\t\tp.addSourceMapping(loc.Loc{Start: n.Loc[0].Start - 1})\n\t\tp.print(\"<\")\n\t}\n\n\tp.addSourceMapping(n.Loc[0])\n\tswitch true {\n\tcase isFragment:\n\t\tp.print(\"Fragment\")\n\tcase isClientOnly:\n\t\tp.print(\"null\")\n\tcase !isSlot && n.CustomElement:\n\t\tp.print(fmt.Sprintf(\"'%s'\", n.Data))\n\tcase !isSlot && !isImplicit:\n\t\t// Print the tag name\n\t\tp.print(n.Data)\n\t}\n\n\tp.addNilSourceMapping()\n\tif isImplicit {\n\t\t// do nothing\n\t} else if isComponent {\n\t\tmaybeConvertTransition(n)\n\t\tp.print(\",\")\n\t\tp.printAttributesToObject(n)\n\t} else if isSlot {\n\t\tif len(n.Attr) == 0 {\n\t\t\tp.print(`\"default\"`)\n\t\t} else {\n\t\t\tslotted := false\n\t\t\tfor _, a := range n.Attr {\n\t\t\t\tif a.Key != \"name\" {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tswitch a.Type {\n\t\t\t\tcase QuotedAttribute:\n\t\t\t\t\tp.addSourceMapping(a.ValLoc)\n\t\t\t\t\tp.print(`\"` + escapeDoubleQuote(a.Val) + `\"`)\n\t\t\t\t\tslotted = true\n\t\t\t\tdefault:\n\t\t\t\t\tp.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode:  loc.ERROR_UNSUPPORTED_SLOT_ATTRIBUTE,\n\t\t\t\t\t\tText:  \"slot[name] must be a static string\",\n\t\t\t\t\t\tRange: loc.Range{Loc: a.ValLoc, Len: len(a.Val)},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !slotted {\n\t\t\t\tp.print(`\"default\"`)\n\t\t\t}\n\t\t}\n\t\tp.print(`]`)\n\t} else {\n\t\tmaybeConvertTransition(n)\n\n\t\tfor _, a := range n.Attr {\n\t\t\tif transform.IsImplicitNodeMarker(a) || a.Key == \"is:inline\" {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif a.Key == \"slot\" {\n\t\t\t\t// Walk up the tree to find the nearest non-Expression ancestor\n\t\t\t\t// to determine if we're inside an Astro Component (slot should be stripped)\n\t\t\t\t// or a CustomElement/regular HTML (slot should be preserved)\n\t\t\t\tparent := n.Parent\n\t\t\t\tfor parent != nil && parent.Expression {\n\t\t\t\t\tparent = parent.Parent\n\t\t\t\t}\n\t\t\t\tif parent != nil && parent.Component {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\t// Note: if we encounter \"slot\" NOT inside a component, that's fine\n\t\t\t\t// These should be preserved in the output (e.g., for web components)\n\t\t\t\tp.printAttribute(a, n)\n\t\t\t} else if a.Key == \"data-astro-source-file\" {\n\t\t\t\tp.printAttribute(a, n)\n\t\t\t\tvar l []int\n\t\t\t\tif n.FirstChild != nil && len(n.FirstChild.Loc) > 0 {\n\t\t\t\t\tstart := n.FirstChild.Loc[0].Start\n\t\t\t\t\tif n.FirstChild.Type == TextNode {\n\t\t\t\t\t\tstart += len(n.Data) - len(strings.TrimLeftFunc(n.Data, unicode.IsSpace))\n\t\t\t\t\t}\n\t\t\t\t\tl = p.builder.GetLineAndColumnForLocation(loc.Loc{Start: start})\n\t\t\t\t} else if len(n.Loc) > 0 {\n\t\t\t\t\tl = p.builder.GetLineAndColumnForLocation(n.Loc[0])\n\t\t\t\t}\n\t\t\t\tif len(l) > 0 {\n\t\t\t\t\tp.printAttribute(Attribute{\n\t\t\t\t\t\tKey:  \"data-astro-source-loc\",\n\t\t\t\t\t\tType: QuotedAttribute,\n\t\t\t\t\t\tVal:  fmt.Sprintf(\"%d:%d\", l[0], l[1]),\n\t\t\t\t\t}, n)\n\t\t\t\t}\n\t\t\t\tp.addSourceMapping(n.Loc[0])\n\t\t\t} else {\n\t\t\t\tp.printAttribute(a, n)\n\t\t\t\tp.addSourceMapping(n.Loc[0])\n\t\t\t}\n\t\t}\n\t\tp.addSourceMapping(n.Loc[0])\n\t\tp.print(\">\")\n\t}\n\n\tif voidElements[n.Data] {\n\t\tif n.FirstChild != nil {\n\t\t\t// return fmt.Errorf(\"html: void element <%s> has child nodes\", n.Data)\n\t\t}\n\t\treturn\n\t}\n\n\t// Add initial newline where there is danger of a newline beging ignored.\n\tif c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, \"\\n\") {\n\t\tswitch n.Data {\n\t\tcase \"pre\", \"listing\", \"textarea\":\n\t\t\tp.print(\"\\n\")\n\t\t}\n\t}\n\n\tif n.DataAtom == atom.Script || n.DataAtom == atom.Style {\n\t\tp.printDefineVarsOpen(n)\n\t}\n\n\t// Render any child nodes.\n\tswitch n.Data {\n\tcase \"iframe\", \"noembed\", \"noframes\", \"noscript\", \"plaintext\", \"script\", \"style\", \"xmp\":\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif c.Type == TextNode {\n\t\t\t\tp.printTextWithSourcemap(escapeText(c.Data), c.Loc[0])\n\t\t\t} else {\n\t\t\t\trender1(p, c, RenderOptions{\n\t\t\t\t\tisRoot:           false,\n\t\t\t\t\tisExpression:     opts.isExpression,\n\t\t\t\t\tdepth:            depth + 1,\n\t\t\t\t\topts:             opts.opts,\n\t\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\t// if n.Data == \"plaintext\" {\n\t\t// \t// Don't render anything else. <plaintext> must be the\n\t\t// \t// last element in the file, with no closing tag.\n\t\t// \treturn\n\t\t// }\n\tdefault:\n\t\tisAllWhiteSpace := false\n\t\tif isComponent || isSlot {\n\t\t\tisAllWhiteSpace = true\n\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\tisAllWhiteSpace = c.Type == TextNode && strings.TrimSpace(c.Data) == \"\"\n\t\t\t\tif !isAllWhiteSpace {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif !isAllWhiteSpace {\n\t\t\tswitch true {\n\t\t\tcase n.CustomElement:\n\t\t\t\tp.print(`,{`)\n\t\t\t\tp.print(fmt.Sprintf(`\"%s\": () => `, \"default\"))\n\t\t\t\tp.printTemplateLiteralOpen()\n\t\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\t\trender1(p, c, RenderOptions{\n\t\t\t\t\t\tisRoot:           false,\n\t\t\t\t\t\tisExpression:     opts.isExpression,\n\t\t\t\t\t\tdepth:            depth + 1,\n\t\t\t\t\t\topts:             opts.opts,\n\t\t\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tp.printTemplateLiteralClose()\n\t\t\t\tp.print(`,}`)\n\t\t\tcase isComponent:\n\t\t\t\tp.print(`,`)\n\t\t\t\tslottedChildren := make(map[string][]*Node)\n\t\t\t\tconditionalSlottedChildren := make([][]*Node, 0)\n\t\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\t\tslotProp := `\"default\"`\n\t\t\t\t\tfor _, a := range c.Attr {\n\t\t\t\t\t\tif a.Key == \"slot\" {\n\t\t\t\t\t\t\tif a.Type == QuotedAttribute {\n\t\t\t\t\t\t\t\tslotProp = fmt.Sprintf(`\"%s\"`, escapeDoubleQuote(a.Val))\n\t\t\t\t\t\t\t} else if a.Type == ExpressionAttribute {\n\t\t\t\t\t\t\t\tslotProp = fmt.Sprintf(`[%s]`, a.Val)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tp.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\t\t\t\t\t\tCode:  loc.ERROR_UNSUPPORTED_SLOT_ATTRIBUTE,\n\t\t\t\t\t\t\t\t\tText:  \"slot[name] must be a static string\",\n\t\t\t\t\t\t\t\t\tRange: loc.Range{Loc: a.ValLoc, Len: len(a.Val)},\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif c.Expression {\n\t\t\t\t\t\tnestedSlots := make([]string, 0)\n\t\t\t\t\t\tfor c1 := c.FirstChild; c1 != nil; c1 = c1.NextSibling {\n\t\t\t\t\t\t\tfor _, a := range c1.Attr {\n\t\t\t\t\t\t\t\tif a.Key == \"slot\" {\n\t\t\t\t\t\t\t\t\tif a.Type == QuotedAttribute {\n\t\t\t\t\t\t\t\t\t\tnestedSlotProp := fmt.Sprintf(`\"%s\"`, escapeDoubleQuote(a.Val))\n\t\t\t\t\t\t\t\t\t\tnestedSlots = append(nestedSlots, nestedSlotProp)\n\t\t\t\t\t\t\t\t\t} else if a.Type == ExpressionAttribute {\n\t\t\t\t\t\t\t\t\t\tnestedSlotProp := fmt.Sprintf(`[%s]`, a.Val)\n\t\t\t\t\t\t\t\t\t\tnestedSlots = append(nestedSlots, nestedSlotProp)\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tpanic(`unknown slot attribute type`)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif len(nestedSlots) == 1 {\n\t\t\t\t\t\t\tslotProp = nestedSlots[0]\n\t\t\t\t\t\t\tslottedChildren[slotProp] = append(slottedChildren[slotProp], c)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t} else if len(nestedSlots) > 1 {\n\t\t\t\t\t\t\tconditionalChildren := make([]*Node, 0)\n\t\t\t\t\t\tchild_loop:\n\t\t\t\t\t\t\tfor c1 := c.FirstChild; c1 != nil; c1 = c1.NextSibling {\n\t\t\t\t\t\t\t\tfor _, a := range c1.Attr {\n\t\t\t\t\t\t\t\t\tif a.Key == \"slot\" {\n\t\t\t\t\t\t\t\t\t\tif a.Type == QuotedAttribute {\n\t\t\t\t\t\t\t\t\t\t\tnestedSlotProp := fmt.Sprintf(`\"%s\"`, escapeDoubleQuote(a.Val))\n\t\t\t\t\t\t\t\t\t\t\tnestedSlots = append(nestedSlots, nestedSlotProp)\n\t\t\t\t\t\t\t\t\t\t\tconditionalChildren = append(conditionalChildren, &Node{Type: TextNode, Data: fmt.Sprintf(\"{%s: () => \", nestedSlotProp), Loc: make([]loc.Loc, 1)})\n\t\t\t\t\t\t\t\t\t\t\tconditionalChildren = append(conditionalChildren, c1)\n\t\t\t\t\t\t\t\t\t\t\tconditionalChildren = append(conditionalChildren, &Node{Type: TextNode, Data: \"}\", Loc: make([]loc.Loc, 1)})\n\t\t\t\t\t\t\t\t\t\t\tcontinue child_loop\n\t\t\t\t\t\t\t\t\t\t} else if a.Type == ExpressionAttribute {\n\t\t\t\t\t\t\t\t\t\t\tnestedSlotProp := fmt.Sprintf(`[%s]`, a.Val)\n\t\t\t\t\t\t\t\t\t\t\tnestedSlots = append(nestedSlots, nestedSlotProp)\n\t\t\t\t\t\t\t\t\t\t\tconditionalChildren = append(conditionalChildren, &Node{Type: TextNode, Data: fmt.Sprintf(\"{%s: () => \", nestedSlotProp), Loc: make([]loc.Loc, 1)})\n\t\t\t\t\t\t\t\t\t\t\tconditionalChildren = append(conditionalChildren, c1)\n\t\t\t\t\t\t\t\t\t\t\tconditionalChildren = append(conditionalChildren, &Node{Type: TextNode, Data: \"}\", Loc: make([]loc.Loc, 1)})\n\t\t\t\t\t\t\t\t\t\t\tcontinue child_loop\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tpanic(`unknown slot attribute type`)\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tconditionalChildren = append(conditionalChildren, c1)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tconditionalSlottedChildren = append(conditionalSlottedChildren, conditionalChildren)\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only slot ElementNodes (except expressions containing only comments) or non-empty TextNodes!\n\t\t\t\t\t// CommentNode, JSX comments and others should not be slotted\n\t\t\t\t\tif expressionOnlyHasComment(c) {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif c.Type == ElementNode || c.Type == TextNode && !emptyTextNodeWithoutSiblings(c) {\n\t\t\t\t\t\tslottedChildren[slotProp] = append(slottedChildren[slotProp], c)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// fix: sort keys for stable output\n\t\t\t\tslottedKeys := make([]string, 0, len(slottedChildren))\n\t\t\t\tfor k := range slottedChildren {\n\t\t\t\t\tslottedKeys = append(slottedKeys, k)\n\t\t\t\t}\n\t\t\t\tsort.Strings(slottedKeys)\n\t\t\t\tif len(conditionalSlottedChildren) > 0 {\n\t\t\t\t\tp.print(`$$mergeSlots(`)\n\t\t\t\t}\n\t\t\t\tp.print(`{`)\n\t\t\t\tnumberOfSlots := len(slottedKeys)\n\t\t\t\tif numberOfSlots > 0 {\n\t\t\t\tchildrenLoop:\n\t\t\t\t\tfor _, slotProp := range slottedKeys {\n\t\t\t\t\t\tchildren := slottedChildren[slotProp]\n\n\t\t\t\t\t\t// If there are named slots, the default slot cannot be only whitespace\n\t\t\t\t\t\tif numberOfSlots > 1 && slotProp == \"\\\"default\\\"\" {\n\t\t\t\t\t\t\t// Loop over the children and verify that at least one non-whitespace node exists.\n\t\t\t\t\t\t\tfoundNonWhitespace := false\n\t\t\t\t\t\t\tfor _, child := range children {\n\t\t\t\t\t\t\t\tif child.Type != TextNode || strings.TrimSpace(child.Data) != \"\" {\n\t\t\t\t\t\t\t\t\tfoundNonWhitespace = true\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif !foundNonWhitespace {\n\t\t\t\t\t\t\t\tcontinue childrenLoop\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// If selected, pass through result object on the Astro side\n\t\t\t\t\t\tif opts.opts.ResultScopedSlot {\n\t\t\t\t\t\t\tp.print(fmt.Sprintf(`%s: %s($$result) => `, slotProp, p.getAsyncFuncPrefix()))\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tp.print(fmt.Sprintf(`%s: %s() => `, slotProp, p.getAsyncFuncPrefix()))\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tp.printTemplateLiteralOpen()\n\t\t\t\t\t\tfor _, child := range children {\n\t\t\t\t\t\t\trender1(p, child, RenderOptions{\n\t\t\t\t\t\t\t\tisRoot:           false,\n\t\t\t\t\t\t\t\tisExpression:     opts.isExpression,\n\t\t\t\t\t\t\t\tdepth:            depth + 1,\n\t\t\t\t\t\t\t\topts:             opts.opts,\n\t\t\t\t\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\t\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\t\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.printTemplateLiteralClose()\n\t\t\t\t\t\tp.print(`,`)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.print(`}`)\n\t\t\t\tif len(conditionalSlottedChildren) > 0 {\n\t\t\t\t\tfor _, children := range conditionalSlottedChildren {\n\t\t\t\t\t\tp.print(\",\")\n\t\t\t\t\t\tfor _, child := range children {\n\t\t\t\t\t\t\tif child.Type == ElementNode {\n\t\t\t\t\t\t\t\tp.printTemplateLiteralOpen()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\trender1(p, child, RenderOptions{\n\t\t\t\t\t\t\t\tisRoot:           false,\n\t\t\t\t\t\t\t\tisExpression:     opts.isExpression,\n\t\t\t\t\t\t\t\tdepth:            depth + 1,\n\t\t\t\t\t\t\t\topts:             opts.opts,\n\t\t\t\t\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\t\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\t\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\tif child.Type == ElementNode {\n\t\t\t\t\t\t\t\tp.printTemplateLiteralClose()\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tp.print(`)`)\n\t\t\t\t}\n\t\t\tcase isSlot:\n\t\t\t\tp.print(`,`)\n\t\t\t\tp.printTemplateLiteralOpen()\n\t\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\t\trender1(p, c, RenderOptions{\n\t\t\t\t\t\tisRoot:           false,\n\t\t\t\t\t\tisExpression:     opts.isExpression,\n\t\t\t\t\t\tdepth:            depth + 1,\n\t\t\t\t\t\topts:             opts.opts,\n\t\t\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tp.printTemplateLiteralClose()\n\t\t\tdefault:\n\t\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\t\trender1(p, c, RenderOptions{\n\t\t\t\t\t\tisRoot:           false,\n\t\t\t\t\t\tisExpression:     opts.isExpression,\n\t\t\t\t\t\tdepth:            depth + 1,\n\t\t\t\t\t\topts:             opts.opts,\n\t\t\t\t\t\tcssLen:           opts.cssLen,\n\t\t\t\t\t\tprintedMaybeHead: opts.printedMaybeHead,\n\t\t\t\t\t\tscriptCount:      opts.scriptCount,\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(n.Loc) == 2 {\n\t\tp.addSourceMapping(n.Loc[1])\n\t} else {\n\t\tp.addSourceMapping(n.Loc[0])\n\t}\n\tif n.DataAtom == atom.Script || n.DataAtom == atom.Style {\n\t\tp.printDefineVarsClose(n)\n\t}\n\tif isComponent || isSlot {\n\t\tp.print(\")}\")\n\t} else if !isImplicit {\n\t\tif n.DataAtom == atom.Head {\n\t\t\t*opts.printedMaybeHead = true\n\t\t\tp.printRenderHead()\n\t\t}\n\t\tstart := 2\n\t\tif len(n.Loc) > 0 {\n\t\t\tstart = n.Loc[0].Start\n\t\t}\n\t\tif len(n.Loc) >= 2 {\n\t\t\tstart = n.Loc[1].Start\n\t\t}\n\t\tstart -= 2\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.print(`</`)\n\t\tstart += 2\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.print(n.Data)\n\t\tstart += len(n.Data)\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.print(`>`)\n\t}\n}\n\n// Section 12.1.2, \"Elements\", gives this list of void elements. Void elements\n// are those that can't have any contents.\n// nolint\nvar voidElements = map[string]bool{\n\t\"area\":            true,\n\t\"base\":            true,\n\t\"br\":              true,\n\t\"col\":             true,\n\t\"embed\":           true,\n\t\"hr\":              true,\n\t\"img\":             true,\n\t\"input\":           true,\n\t\"keygen\":          true, // \"keygen\" has been removed from the spec, but are kept here for backwards compatibility.\n\t\"link\":            true,\n\t\"meta\":            true,\n\t\"param\":           true,\n\t\"selectedcontent\": true,\n\t\"source\":          true,\n\t\"track\":           true,\n\t\"wbr\":             true,\n}\n"
  },
  {
    "path": "internal/printer/print-to-json.go",
    "content": "package printer\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t. \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"github.com/withastro/compiler/internal/sourcemap\"\n\t\"github.com/withastro/compiler/internal/t\"\n\t\"github.com/withastro/compiler/internal/transform\"\n)\n\ntype ASTPosition struct {\n\tStart ASTPoint `json:\"start,omitempty\"`\n\tEnd   ASTPoint `json:\"end,omitempty\"`\n}\n\ntype ASTPoint struct {\n\tLine   int `json:\"line,omitempty\"`\n\tColumn int `json:\"column,omitempty\"`\n\tOffset int `json:\"offset,omitempty\"`\n}\n\ntype ASTNode struct {\n\tType       string      `json:\"type\"`\n\tName       string      `json:\"name\"`\n\tValue      string      `json:\"value,omitempty\"`\n\tAttributes []ASTNode   `json:\"attributes,omitempty\"`\n\tDirectives []ASTNode   `json:\"directives,omitempty\"`\n\tChildren   []ASTNode   `json:\"children,omitempty\"`\n\tPosition   ASTPosition `json:\"position,omitempty\"`\n\n\t// Attributes only\n\tKind string `json:\"kind,omitempty\"`\n\tRaw  string `json:\"raw,omitempty\"`\n}\n\nfunc escapeForJSON(value string) string {\n\tbackslash := regexp.MustCompile(`\\\\`)\n\tvalue = backslash.ReplaceAllString(value, `\\\\`)\n\tnewlines := regexp.MustCompile(`\\n`)\n\tvalue = newlines.ReplaceAllString(value, `\\n`)\n\tdoublequotes := regexp.MustCompile(`\"`)\n\tvalue = doublequotes.ReplaceAllString(value, `\\\"`)\n\tr := regexp.MustCompile(`\\r`)\n\tvalue = r.ReplaceAllString(value, `\\r`)\n\tt := regexp.MustCompile(`\\t`)\n\tvalue = t.ReplaceAllString(value, `\\t`)\n\tf := regexp.MustCompile(`\\f`)\n\tvalue = f.ReplaceAllString(value, `\\f`)\n\treturn value\n}\n\nfunc (n ASTNode) String() string {\n\tstr := fmt.Sprintf(`{\"type\":\"%s\"`, n.Type)\n\tif n.Kind != \"\" {\n\t\tstr += fmt.Sprintf(`,\"kind\":\"%s\"`, n.Kind)\n\t}\n\tif n.Name != \"\" {\n\t\tstr += fmt.Sprintf(`,\"name\":\"%s\"`, escapeForJSON(n.Name))\n\t} else if n.Type == \"fragment\" {\n\t\tstr += `,\"name\":\"\"`\n\t}\n\tif n.Value != \"\" || n.Type == \"attribute\" {\n\t\tstr += fmt.Sprintf(`,\"value\":\"%s\"`, escapeForJSON(n.Value))\n\t}\n\tif n.Raw != \"\" || n.Type == \"attribute\" {\n\t\tstr += fmt.Sprintf(`,\"raw\":\"%s\"`, escapeForJSON(n.Raw))\n\t}\n\tif len(n.Attributes) > 0 {\n\t\tstr += `,\"attributes\":[`\n\t\tfor i, attr := range n.Attributes {\n\t\t\tstr += attr.String()\n\t\t\tif i < len(n.Attributes)-1 {\n\t\t\t\tstr += \",\"\n\t\t\t}\n\t\t}\n\t\tstr += `]`\n\t} else if n.Type == \"element\" || n.Type == \"component\" || n.Type == \"custom-element\" || n.Type == \"fragment\" {\n\t\tstr += `,\"attributes\":[]`\n\t}\n\tif len(n.Children) > 0 {\n\t\tstr += `,\"children\":[`\n\t\tfor i, node := range n.Children {\n\t\t\tstr += node.String()\n\t\t\tif i < len(n.Children)-1 {\n\t\t\t\tstr += \",\"\n\t\t\t}\n\t\t}\n\t\tstr += `]`\n\t} else if n.Type == \"element\" || n.Type == \"component\" || n.Type == \"custom-element\" || n.Type == \"fragment\" {\n\t\tstr += `,\"children\":[]`\n\t}\n\tif n.Position.Start.Line != 0 {\n\t\tstr += `,\"position\":{`\n\t\tstr += fmt.Sprintf(`\"start\":{\"line\":%d,\"column\":%d,\"offset\":%d}`, n.Position.Start.Line, n.Position.Start.Column, n.Position.Start.Offset)\n\t\tif n.Position.End.Line != 0 {\n\t\t\tstr += fmt.Sprintf(`,\"end\":{\"line\":%d,\"column\":%d,\"offset\":%d}`, n.Position.End.Line, n.Position.End.Column, n.Position.End.Offset)\n\t\t}\n\t\tstr += \"}\"\n\t}\n\tstr += \"}\"\n\treturn str\n}\n\nfunc PrintToJSON(sourcetext string, n *Node, opts t.ParseOptions) PrintResult {\n\tp := &printer{\n\t\tbuilder:    sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(sourcetext, len(strings.Split(sourcetext, \"\\n\")))),\n\t\tsourcetext: sourcetext,\n\t}\n\troot := ASTNode{}\n\trenderNode(p, &root, n, opts)\n\tdoc := root.Children[0]\n\treturn PrintResult{\n\t\tOutput: []byte(doc.String()),\n\t}\n}\n\nfunc locToPoint(p *printer, loc loc.Loc) ASTPoint {\n\toffset := loc.Start\n\tinfo := p.builder.GetLineAndColumnForLocation(loc)\n\tline := info[0]\n\tcolumn := info[1]\n\n\treturn ASTPoint{\n\t\tLine:   line,\n\t\tColumn: column,\n\t\tOffset: offset,\n\t}\n}\n\nfunc positionAt(p *printer, n *Node, opts t.ParseOptions) ASTPosition {\n\tif !opts.Position {\n\t\treturn ASTPosition{}\n\t}\n\n\tif len(n.Loc) == 1 {\n\t\ts := n.Loc[0]\n\t\tstart := locToPoint(p, s)\n\n\t\treturn ASTPosition{\n\t\t\tStart: start,\n\t\t}\n\t}\n\n\tif len(n.Loc) == 2 {\n\t\ts := n.Loc[0]\n\t\te := n.Loc[1]\n\t\t// `s` and `e` mark the start location of the tag name\n\t\tif n.Type == ElementNode {\n\t\t\t// this adjusts `e` to be the last index of the end tag for self-closing tags\n\t\t\tif s.Start == e.Start {\n\t\t\t\te.Start = e.Start + len(n.Data) + 2\n\t\t\t} else {\n\t\t\t\t// this adjusts `e` to be the last index of the end tag for normally closed tags\n\t\t\t\te.Start = e.Start + len(n.Data) + 1\n\t\t\t}\n\n\t\t\tif s.Start != 0 {\n\t\t\t\t// this adjusts `s` to be the first index of the element tag\n\t\t\t\ts.Start = s.Start - 1\n\t\t\t}\n\t\t}\n\t\tstart := locToPoint(p, s)\n\t\tend := locToPoint(p, e)\n\n\t\treturn ASTPosition{\n\t\t\tStart: start,\n\t\t\tEnd:   end,\n\t\t}\n\t}\n\treturn ASTPosition{}\n}\n\nfunc attrPositionAt(p *printer, n *Attribute, opts t.ParseOptions) ASTPosition {\n\tif !opts.Position {\n\t\treturn ASTPosition{}\n\t}\n\n\tk := n.KeyLoc\n\tstart := locToPoint(p, k)\n\n\treturn ASTPosition{\n\t\tStart: start,\n\t}\n}\n\nfunc renderNode(p *printer, parent *ASTNode, n *Node, opts t.ParseOptions) {\n\tisImplicit := false\n\tfor _, a := range n.Attr {\n\t\tif transform.IsImplicitNodeMarker(a) {\n\t\t\tisImplicit = true\n\t\t\tbreak\n\t\t}\n\t}\n\thasChildren := n.FirstChild != nil\n\tif isImplicit {\n\t\tif hasChildren {\n\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\trenderNode(p, parent, c, opts)\n\t\t\t}\n\t\t}\n\t\treturn\n\t}\n\tvar node ASTNode\n\n\tnode.Position = positionAt(p, n, opts)\n\n\tif n.Type == ElementNode {\n\t\tif n.Expression {\n\t\t\tnode.Type = \"expression\"\n\t\t} else {\n\t\t\tnode.Name = n.Data\n\t\t\tif n.Component {\n\t\t\t\tnode.Type = \"component\"\n\t\t\t} else if n.CustomElement {\n\t\t\t\tnode.Type = \"custom-element\"\n\t\t\t} else if n.Fragment {\n\t\t\t\tnode.Type = \"fragment\"\n\t\t\t} else {\n\t\t\t\tnode.Type = \"element\"\n\t\t\t}\n\n\t\t\tfor _, attr := range n.Attr {\n\t\t\t\tname := attr.Key\n\t\t\t\tif attr.Namespace != \"\" {\n\t\t\t\t\tname = fmt.Sprintf(\"%s:%s\", attr.Namespace, attr.Key)\n\t\t\t\t}\n\t\t\t\tposition := attrPositionAt(p, &attr, opts)\n\t\t\t\traw := \"\"\n\t\t\t\tif attr.Type == QuotedAttribute || attr.Type == TemplateLiteralAttribute {\n\t\t\t\t\tstart := attr.ValLoc.Start - 1\n\t\t\t\t\tend := attr.ValLoc.Start + len(attr.Val)\n\n\t\t\t\t\tchar := p.sourcetext[start]\n\t\t\t\t\tif char == '=' {\n\t\t\t\t\t\tstart += 1\n\t\t\t\t\t} else {\n\t\t\t\t\t\tend += 1\n\t\t\t\t\t}\n\t\t\t\t\traw = strings.TrimSpace(p.sourcetext[start:end])\n\t\t\t\t}\n\t\t\t\tattrNode := ASTNode{\n\t\t\t\t\tType:     \"attribute\",\n\t\t\t\t\tKind:     attr.Type.String(),\n\t\t\t\t\tPosition: position,\n\t\t\t\t\tName:     name,\n\t\t\t\t\tValue:    attr.Val,\n\t\t\t\t\tRaw:      raw,\n\t\t\t\t}\n\t\t\t\tnode.Attributes = append(node.Attributes, attrNode)\n\t\t\t}\n\t\t}\n\t} else {\n\t\tnode.Type = n.Type.String()\n\t\tif n.Type == TextNode || n.Type == CommentNode || n.Type == DoctypeNode {\n\t\t\tnode.Value = n.Data\n\t\t}\n\t}\n\tif n.Type == FrontmatterNode && hasChildren {\n\t\tnode.Value = n.FirstChild.Data\n\t} else {\n\t\tif !isImplicit && hasChildren {\n\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\trenderNode(p, &node, c, opts)\n\t\t\t}\n\t\t}\n\t}\n\n\tparent.Children = append(parent.Children, node)\n}\n"
  },
  {
    "path": "internal/printer/print-to-tsx.go",
    "content": "package printer\n\nimport (\n\t\"fmt\"\n\t\"slices\"\n\t\"strings\"\n\t\"unicode\"\n\n\t. \"github.com/withastro/compiler/internal\"\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/helpers\"\n\t\"github.com/withastro/compiler/internal/js_scanner\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"github.com/withastro/compiler/internal/sourcemap\"\n\t\"github.com/withastro/compiler/internal/transform\"\n\t\"golang.org/x/net/html/atom\"\n)\n\nfunc getTSXPrefix() string {\n\treturn \"/* @jsxImportSource astro */\\n\\n\"\n}\n\ntype TSXOptions struct {\n\tIncludeScripts bool\n\tIncludeStyles  bool\n}\n\nfunc PrintToTSX(sourcetext string, n *Node, opts TSXOptions, transformOpts transform.TransformOptions, h *handler.Handler) PrintResult {\n\tp := &printer{\n\t\tsourcetext: sourcetext,\n\t\topts:       transformOpts,\n\t\tbuilder:    sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(sourcetext, len(strings.Split(sourcetext, \"\\n\")))),\n\t}\n\tp.print(getTSXPrefix())\n\trenderTsx(p, n, &opts)\n\n\treturn PrintResult{\n\t\tOutput:         p.output,\n\t\tSourceMapChunk: p.builder.GenerateChunk(p.output),\n\t\tTSXRanges:      finalizeRanges(string(p.output), p.ranges),\n\t}\n}\n\nfunc finalizeRanges(content string, ranges TSXRanges) TSXRanges {\n\tchunkBuilder := sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(content, len(strings.Split(content, \"\\n\"))))\n\n\treturn TSXRanges{\n\t\tFrontmatter: loc.TSXRange{\n\t\t\tStart: chunkBuilder.OffsetAt(loc.Loc{Start: ranges.Frontmatter.Start}),\n\t\t\tEnd:   chunkBuilder.OffsetAt(loc.Loc{Start: ranges.Frontmatter.End}),\n\t\t},\n\t\tBody: loc.TSXRange{\n\t\t\tStart: chunkBuilder.OffsetAt(loc.Loc{Start: ranges.Body.Start}),\n\t\t\tEnd:   chunkBuilder.OffsetAt(loc.Loc{Start: ranges.Body.End}),\n\t\t},\n\t\t// Scripts and styles are already using the proper positions\n\t\tScripts: ranges.Scripts,\n\t\tStyles:  ranges.Styles,\n\t}\n}\n\ntype TSXRanges struct {\n\tFrontmatter loc.TSXRange      `js:\"frontmatter\"`\n\tBody        loc.TSXRange      `js:\"body\"`\n\tScripts     []TSXExtractedTag `js:\"scripts\"`\n\tStyles      []TSXExtractedTag `js:\"styles\"`\n}\n\nvar htmlEvents = map[string]bool{\n\t\"onabort\":                   true,\n\t\"onafterprint\":              true,\n\t\"onauxclick\":                true,\n\t\"onbeforematch\":             true,\n\t\"onbeforeprint\":             true,\n\t\"onbeforeunload\":            true,\n\t\"onblur\":                    true,\n\t\"oncancel\":                  true,\n\t\"oncanplay\":                 true,\n\t\"oncanplaythrough\":          true,\n\t\"onchange\":                  true,\n\t\"onclick\":                   true,\n\t\"onclose\":                   true,\n\t\"oncontextlost\":             true,\n\t\"oncontextmenu\":             true,\n\t\"oncontextrestored\":         true,\n\t\"oncopy\":                    true,\n\t\"oncuechange\":               true,\n\t\"oncut\":                     true,\n\t\"ondblclick\":                true,\n\t\"ondrag\":                    true,\n\t\"ondragend\":                 true,\n\t\"ondragenter\":               true,\n\t\"ondragleave\":               true,\n\t\"ondragover\":                true,\n\t\"ondragstart\":               true,\n\t\"ondrop\":                    true,\n\t\"ondurationchange\":          true,\n\t\"onemptied\":                 true,\n\t\"onended\":                   true,\n\t\"onerror\":                   true,\n\t\"onfocus\":                   true,\n\t\"onformdata\":                true,\n\t\"onhashchange\":              true,\n\t\"oninput\":                   true,\n\t\"oninvalid\":                 true,\n\t\"onkeydown\":                 true,\n\t\"onkeypress\":                true,\n\t\"onkeyup\":                   true,\n\t\"onlanguagechange\":          true,\n\t\"onload\":                    true,\n\t\"onloadeddata\":              true,\n\t\"onloadedmetadata\":          true,\n\t\"onloadstart\":               true,\n\t\"onmessage\":                 true,\n\t\"onmessageerror\":            true,\n\t\"onmousedown\":               true,\n\t\"onmouseenter\":              true,\n\t\"onmouseleave\":              true,\n\t\"onmousemove\":               true,\n\t\"onmouseout\":                true,\n\t\"onmouseover\":               true,\n\t\"onmouseup\":                 true,\n\t\"onoffline\":                 true,\n\t\"ononline\":                  true,\n\t\"onpagehide\":                true,\n\t\"onpageshow\":                true,\n\t\"onpaste\":                   true,\n\t\"onpause\":                   true,\n\t\"onplay\":                    true,\n\t\"onplaying\":                 true,\n\t\"onpopstate\":                true,\n\t\"onprogress\":                true,\n\t\"onratechange\":              true,\n\t\"onrejectionhandled\":        true,\n\t\"onreset\":                   true,\n\t\"onresize\":                  true,\n\t\"onscroll\":                  true,\n\t\"onscrollend\":               true,\n\t\"onsecuritypolicyviolation\": true,\n\t\"onseeked\":                  true,\n\t\"onseeking\":                 true,\n\t\"onselect\":                  true,\n\t\"onslotchange\":              true,\n\t\"onstalled\":                 true,\n\t\"onstorage\":                 true,\n\t\"onsubmit\":                  true,\n\t\"onsuspend\":                 true,\n\t\"ontimeupdate\":              true,\n\t\"ontoggle\":                  true,\n\t\"onunhandledrejection\":      true,\n\t\"onunload\":                  true,\n\t\"onvolumechange\":            true,\n\t\"onwaiting\":                 true,\n\t\"onwheel\":                   true,\n}\n\nfunc getStyleLangFromAttrs(attrs []astro.Attribute) string {\n\tif len(attrs) == 0 {\n\t\treturn \"css\"\n\t}\n\n\tfor _, attr := range attrs {\n\t\tif attr.Key == \"lang\" {\n\t\t\tif attr.Type == astro.QuotedAttribute {\n\t\t\t\treturn strings.TrimSpace(strings.ToLower(attr.Val))\n\t\t\t} else {\n\t\t\t\t// If the lang attribute exists, but is not quoted, we can't tell what's inside of it\n\t\t\t\t// So we'll just return \"unknown\" and let the downstream client decide what to do with it\n\t\t\t\treturn \"unknown\"\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"css\"\n}\n\nfunc getScriptTypeFromAttrs(attrs []astro.Attribute) string {\n\tif len(attrs) == 0 {\n\t\treturn \"processed-module\"\n\t}\n\n\tfor _, attr := range attrs {\n\t\t// If the script tag has `is:raw`, we can't tell what's inside of it\n\t\t// so the downstream client will decide what to do with it (e.g. ignore it, treat as inline, try to guess the type, etc.)\n\t\tif attr.Key == \"is:raw\" {\n\t\t\treturn \"raw\"\n\t\t}\n\n\t\tif attr.Key == \"type\" {\n\t\t\tif attr.Type == astro.QuotedAttribute {\n\t\t\t\tnormalizedType := strings.TrimSpace(strings.ToLower(attr.Val))\n\t\t\t\t// If the script tag has `type=\"module\"`, it's not processed, but it's still a module\n\t\t\t\tif normalizedType == \"module\" {\n\t\t\t\t\treturn \"module\"\n\t\t\t\t}\n\n\t\t\t\tif ScriptJSONMimeTypes[normalizedType] {\n\t\t\t\t\treturn \"json\"\n\t\t\t\t}\n\n\t\t\t\tif ScriptMimeTypes[normalizedType] {\n\t\t\t\t\treturn \"inline\"\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the type is not recognized, leave it as unknown\n\t\t\treturn \"unknown\"\n\t\t}\n\n\t}\n\n\t// Otherwise, it's an inline script\n\treturn \"inline\"\n}\n\ntype TSXExtractedTag struct {\n\tLoc     loc.TSXRange `js:\"position\"`\n\tType    string       `js:\"type\"`\n\tContent string       `js:\"content\"`\n\tLang    string       `js:\"lang\"`\n}\n\nfunc isScript(p *astro.Node) bool {\n\treturn p.DataAtom == atom.Script\n}\n\nfunc isStyle(p *astro.Node) bool {\n\treturn p.DataAtom == atom.Style\n}\n\n// Has is:raw attribute\nfunc isRawText(p *astro.Node) bool {\n\tfor _, a := range p.Attr {\n\t\tif a.Key == \"is:raw\" {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nvar ScriptMimeTypes map[string]bool = map[string]bool{\n\t\"module\":                 true,\n\t\"text/typescript\":        true,\n\t\"application/javascript\": true,\n\t\"text/partytown\":         true,\n\t\"application/node\":       true,\n}\n\nvar ScriptJSONMimeTypes map[string]bool = map[string]bool{\n\t\"application/json\":    true,\n\t\"application/ld+json\": true,\n\t\"importmap\":           true,\n\t\"speculationrules\":    true,\n}\n\n// This is not perfect (as in, you wouldn't use this to make a spec compliant parser), but it's good enough\n// for the real world. Thankfully, JSX is also a bit more lax than JavaScript, so we can spare some work.\nfunc isValidTSXAttribute(a Attribute) bool {\n\tif a.Type == SpreadAttribute {\n\t\treturn true\n\t}\n\n\tfor i, ch := range a.Key {\n\t\tif i == 0 && !isValidFirstRune(ch) {\n\t\t\treturn false\n\t\t}\n\n\t\t// See https://tc39.es/ecma262/#prod-IdentifierName\n\t\tif i != 0 && !(isValidFirstRune(ch) ||\n\t\t\tunicode.In(ch, unicode.Mn, unicode.Mc, unicode.Nd, unicode.Pc)) &&\n\t\t\t// : is allowed inside TSX attributes, for namespaces purpose\n\t\t\t// See https://facebook.github.io/jsx/#prod-JSXNamespacedName\n\t\t\t// - is allowed inside TSX attributes, for custom attributes\n\t\t\t// See https://facebook.github.io/jsx/#prod-JSXIdentifier\n\t\t\tch != ':' && ch != '-' {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n\n// See https://tc39.es/ecma262/#prod-IdentifierStartChar\nfunc isValidFirstRune(r rune) bool {\n\treturn r == '$' || r == '_' || unicode.In(r,\n\t\tunicode.Lu,\n\t\tunicode.Ll,\n\t\tunicode.Lt,\n\t\tunicode.Lm,\n\t\tunicode.Lo,\n\t\tunicode.Nl,\n\t)\n}\n\ntype TextType uint32\n\nconst (\n\tRawText TextType = iota\n\tText\n\tScriptText\n\tJsonScriptText\n\tUnknownScriptText\n\tStyleText\n)\n\nfunc getTextType(n *astro.Node) TextType {\n\tif script := n.Closest(isScript); script != nil {\n\t\tattr := astro.GetAttribute(script, \"type\")\n\t\tif attr == nil || ScriptMimeTypes[strings.ToLower(attr.Val)] {\n\t\t\treturn ScriptText\n\t\t}\n\n\t\t// There's no difference between JSON and unknown script types in the result JSX at this time\n\t\t// however, we might want to add some special handling in the future, so we keep them separate\n\t\tif ScriptJSONMimeTypes[strings.ToLower(attr.Val)] {\n\t\t\treturn JsonScriptText\n\t\t}\n\n\t\treturn UnknownScriptText\n\t}\n\tif style := n.Closest(isStyle); style != nil {\n\t\treturn StyleText\n\t}\n\n\tif n.Closest(isRawText) != nil {\n\t\treturn RawText\n\t}\n\n\treturn Text\n}\n\nfunc renderTsx(p *printer, n *Node, o *TSXOptions) {\n\t// Root of the document, print all children\n\tif n.Type == DocumentNode {\n\t\tsource := []byte(p.sourcetext)\n\t\tprops := js_scanner.GetPropsType(source)\n\t\thasGetStaticPaths := js_scanner.HasGetStaticPaths(source)\n\t\thasChildren := false\n\t\tstartLen := len(p.output)\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t// This checks for the first node that comes *after* the frontmatter\n\t\t\t// to ensure that the statement is properly closed with a `;`.\n\t\t\t// Without this, TypeScript can get tripped up by the body of our file.\n\t\t\tif c.PrevSibling != nil && c.PrevSibling.Type == FrontmatterNode {\n\t\t\t\tbuf := strings.TrimSpace(string(p.output))\n\t\t\t\tif len(buf)-len(getTSXPrefix()) > 1 {\n\t\t\t\t\tchar := rune(buf[len(buf)-1:][0])\n\t\t\t\t\t// If the existing buffer ends with any character other than ;, we need to add a `;`\n\t\t\t\t\tif char != ';' {\n\t\t\t\t\t\tp.addNilSourceMapping()\n\t\t\t\t\t\tp.print(\"{};\")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// We always need to start the body with `<Fragment>`\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.print(\"<Fragment>\\n\")\n\n\t\t\t\t// Update the start location of the body to the start of the first child\n\t\t\t\tstartLen = len(p.output)\n\n\t\t\t\thasChildren = true\n\t\t\t}\n\t\t\tif c.PrevSibling == nil && c.Type != FrontmatterNode {\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.print(\"<Fragment>\\n\")\n\n\t\t\t\tstartLen = len(p.output)\n\n\t\t\t\thasChildren = true\n\t\t\t}\n\t\t\trenderTsx(p, c, o)\n\t\t}\n\t\tp.addSourceMapping(loc.Loc{Start: len(p.sourcetext)})\n\t\tp.print(\"\\n\")\n\n\t\tp.addNilSourceMapping()\n\t\tp.setTSXBodyRange(loc.TSXRange{\n\t\t\tStart: startLen,\n\t\t\tEnd:   len(p.output),\n\t\t})\n\n\t\t// Only close the body with `</Fragment>` if we printed a body\n\t\tif hasChildren {\n\t\t\tp.print(\"</Fragment>\\n\")\n\t\t}\n\t\tcomponentName := getTSXComponentName(p.opts.Filename)\n\t\tpropsIdent := props.Ident\n\t\tparamsIdent := \"\"\n\t\tif hasGetStaticPaths {\n\t\t\tparamsIdent = \"ASTRO__Get<ASTRO__InferredGetStaticPath, 'params'>\"\n\t\t\tif propsIdent == \"Record<string, any>\" {\n\t\t\t\tpropsIdent = \"ASTRO__MergeUnion<ASTRO__Get<ASTRO__InferredGetStaticPath, 'props'>>\"\n\t\t\t}\n\t\t}\n\n\t\tp.print(fmt.Sprintf(\"export default function %s%s(_props: %s%s): any {}\\n\", componentName, props.Statement, propsIdent, props.Generics))\n\t\tif hasGetStaticPaths {\n\t\t\tp.printf(`type ASTRO__ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;\ntype ASTRO__Flattened<T> = T extends Array<infer U> ? ASTRO__Flattened<U> : T;\ntype ASTRO__InferredGetStaticPath = ASTRO__Flattened<ASTRO__ArrayElement<Awaited<ReturnType<typeof getStaticPaths>>>>;\ntype ASTRO__MergeUnion<T, K extends PropertyKey = T extends unknown ? keyof T : never> = T extends unknown ? T & { [P in Exclude<K, keyof T>]?: never } extends infer O ? { [P in keyof O]: O[P] } : never : never;\ntype ASTRO__Get<T, K> = T extends undefined ? undefined : K extends keyof T ? T[K] : never;%s`, \"\\n\")\n\t\t}\n\n\t\tif propsIdent != \"Record<string, any>\" {\n\t\t\tp.printf(`/**\n * Astro global available in all contexts in .astro files\n *\n * [Astro documentation](https://docs.astro.build/reference/api-reference/#astro-global)\n*/\ndeclare const Astro: Readonly<import('astro').AstroGlobal<%s, typeof %s`, propsIdent, componentName)\n\t\t\tif paramsIdent != \"\" {\n\t\t\t\tp.printf(\", %s\", paramsIdent)\n\t\t\t}\n\t\t\tp.print(\">>\")\n\t\t}\n\t\treturn\n\t}\n\n\tif n.Type == FrontmatterNode {\n\t\tp.addSourceMapping(loc.Loc{Start: 0})\n\t\tfrontmatterStart := len(p.output)\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif c.Type == TextNode {\n\t\t\t\tif len(c.Loc) > 0 {\n\t\t\t\t\tp.addSourceMapping(c.Loc[0])\n\t\t\t\t}\n\t\t\t\t// Find top-level returns and transform them to throws\n\t\t\t\t// This is needed because top-level returns are valid in Astro frontmatter\n\t\t\t\t// but cause TypeScript parsing errors in the generated TSX\n\t\t\t\ttopLevelReturns := js_scanner.FindTopLevelReturns([]byte(c.Data))\n\t\t\t\tif len(topLevelReturns) > 0 {\n\t\t\t\t\t// Build a new string with top-level returns replaced by throws\n\t\t\t\t\t// Note: We use \"throw \" (with extra space) to preserve the same character\n\t\t\t\t\t// count as \"return\" so sourcemaps remain accurate for the rest of the code\n\t\t\t\t\tnewString := make([]byte, 0, len(c.Data))\n\t\t\t\t\ti := 0\n\t\t\t\t\tfor i < len(c.Data) {\n\t\t\t\t\t\tif slices.Contains(topLevelReturns, i) {\n\t\t\t\t\t\t\tnewString = append(newString, []byte(\"throw \")...)\n\t\t\t\t\t\t\ti += len(\"return\")\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tnewString = append(newString, c.Data[i])\n\t\t\t\t\t\t\ti++\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tp.printTextWithSourcemap(string(newString), c.Loc[0])\n\t\t\t\t} else {\n\t\t\t\t\tp.printTextWithSourcemap(c.Data, c.Loc[0])\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\trenderTsx(p, c, o)\n\t\t\t}\n\t\t}\n\t\tif n.FirstChild != nil {\n\t\t\tp.addSourceMapping(loc.Loc{Start: n.FirstChild.Loc[0].Start + len(n.FirstChild.Data)})\n\t\t\tp.print(\"\")\n\t\t\tp.addSourceMapping(loc.Loc{Start: n.FirstChild.Loc[0].Start + len(n.FirstChild.Data) + 3})\n\t\t\tp.println(\"\")\n\t\t}\n\t\tp.setTSXFrontmatterRange(loc.TSXRange{\n\t\t\tStart: frontmatterStart,\n\t\t\tEnd:   len(p.output),\n\t\t})\n\t\treturn\n\t}\n\n\tswitch n.Type {\n\tcase TextNode:\n\t\ttextType := getTextType(n)\n\t\tif textType == ScriptText {\n\t\t\tp.addNilSourceMapping()\n\t\t\tif o.IncludeScripts {\n\t\t\t\tp.print(\"\\n{() => {\")\n\t\t\t\tp.printTextWithSourcemap(n.Data, n.Loc[0])\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.print(\"}}\\n\")\n\t\t\t}\n\t\t\tp.addSourceMapping(loc.Loc{Start: n.Loc[0].Start + len(n.Data)})\n\t\t} else if textType == StyleText || textType == JsonScriptText || textType == RawText || textType == UnknownScriptText {\n\t\t\tp.addNilSourceMapping()\n\t\t\tif (textType == StyleText && o.IncludeStyles) || ((textType == JsonScriptText || textType == UnknownScriptText) && o.IncludeScripts) || textType == RawText {\n\t\t\t\tp.print(\"{`\")\n\t\t\t\tp.printTextWithSourcemap(escapeText(n.Data), n.Loc[0])\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.print(\"`}\")\n\t\t\t}\n\t\t\tp.addSourceMapping(loc.Loc{Start: n.Loc[0].Start + len(n.Data)})\n\t\t} else {\n\t\t\tp.printEscapedJSXTextWithSourcemap(n.Data, n.Loc[0])\n\t\t}\n\t\treturn\n\tcase ElementNode:\n\t\t// No-op.\n\tcase CommentNode:\n\t\t// p.addSourceMapping(n.Loc[0])\n\t\tp.addNilSourceMapping()\n\t\tp.print(\"{/**\")\n\t\tif !unicode.IsSpace(rune(n.Data[0])) {\n\t\t\t// always add a space after the opening comment\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.addSourceMapping(n.Loc[0])\n\t\tp.printTextWithSourcemap(escapeBraces(n.Data), n.Loc[0])\n\t\tp.addNilSourceMapping()\n\t\tp.print(\"*/}\")\n\t\treturn\n\tdefault:\n\t\treturn\n\t}\n\n\tif n.Expression {\n\t\tp.addSourceMapping(n.Loc[0])\n\t\tif n.FirstChild == nil {\n\t\t\tp.print(\"{(void 0)\")\n\t\t} else {\n\t\t\tp.print(\"{\")\n\t\t}\n\t\tstart := n.Loc[0].Start + 1\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tif c.Type == TextNode {\n\t\t\t\tif c == n.FirstChild {\n\t\t\t\t\tp.printTextWithSourcemap(c.Data, loc.Loc{Start: start})\n\t\t\t\t} else {\n\t\t\t\t\tp.printTextWithSourcemap(c.Data, c.Loc[0])\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif c.PrevSibling == nil || c.PrevSibling.Type == TextNode {\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.print(`<Fragment>`)\n\t\t\t}\n\t\t\trenderTsx(p, c, o)\n\t\t\tif c.NextSibling == nil || c.NextSibling.Type == TextNode {\n\t\t\t\tp.addNilSourceMapping()\n\t\t\t\tp.print(`</Fragment>`)\n\t\t\t}\n\t\t}\n\t\tif len(n.Loc) > 1 {\n\t\t\tp.addSourceMapping(n.Loc[1])\n\t\t} else {\n\t\t\tp.addSourceMapping(n.Loc[0])\n\t\t}\n\t\tp.print(\"}\")\n\t\treturn\n\t}\n\n\tisImplicit := false\n\tfor _, a := range n.Attr {\n\t\tif transform.IsImplicitNodeMarker(a) {\n\t\t\tisImplicit = true\n\t\t\tbreak\n\t\t}\n\t}\n\n\tif isImplicit {\n\t\t// Render any child nodes\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\trenderTsx(p, c, o)\n\t\t}\n\t\treturn\n\t}\n\n\tp.addSourceMapping(loc.Loc{Start: n.Loc[0].Start - 1})\n\tp.print(\"<\")\n\tp.addSourceMapping(loc.Loc{Start: n.Loc[0].Start})\n\tp.print(n.Data)\n\tp.addSourceMapping(loc.Loc{Start: n.Loc[0].Start + len(n.Data)})\n\n\tinvalidTSXAttributes := make([]Attribute, 0)\n\tendLoc := n.Loc[0].Start + len(n.Data)\n\tfor _, a := range n.Attr {\n\t\tif !isValidTSXAttribute(a) {\n\t\t\tinvalidTSXAttributes = append(invalidTSXAttributes, a)\n\t\t\tcontinue\n\t\t}\n\t\toffset := 1\n\t\tif a.Type != astro.ShorthandAttribute && a.Type != astro.SpreadAttribute {\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start - offset})\n\t\t}\n\t\tp.print(\" \")\n\t\teqStart := a.KeyLoc.Start + strings.IndexRune(p.sourcetext[a.KeyLoc.Start:], '=')\n\t\tif a.Type != astro.ShorthandAttribute && a.Type != astro.SpreadAttribute {\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t}\n\t\tif a.Namespace != \"\" {\n\t\t\tp.print(a.Namespace)\n\t\t\tp.print(\":\")\n\t\t}\n\t\tswitch a.Type {\n\t\tcase astro.QuotedAttribute:\n\t\t\tp.print(a.Key)\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart})\n\t\t\tp.print(\"=\")\n\t\t\tif len(a.Val) > 0 {\n\t\t\t\tp.addSourceMapping(loc.Loc{Start: a.ValLoc.Start - 1})\n\t\t\t\tp.print(`\"`)\n\t\t\t\tp.printTextWithSourcemap(encodeDoubleQuote(a.Val), loc.Loc{Start: a.ValLoc.Start})\n\t\t\t\tp.addSourceMapping(loc.Loc{Start: a.ValLoc.Start + len(a.Val)})\n\t\t\t\tp.print(`\"`)\n\t\t\t\tendLoc = a.ValLoc.Start + len(a.Val) + 1\n\t\t\t} else {\n\t\t\t\tp.addSourceMapping(loc.Loc{Start: a.ValLoc.Start - 1})\n\t\t\t\tp.print(`\"`)\n\t\t\t\tp.addSourceMapping(loc.Loc{Start: a.ValLoc.Start})\n\t\t\t\tp.print(`\"`)\n\t\t\t\tendLoc = a.ValLoc.Start\n\t\t\t}\n\n\t\t\tif _, ok := htmlEvents[a.Key]; ok {\n\t\t\t\tp.addTSXScript(p.builder.OffsetAt(a.ValLoc), p.builder.OffsetAt(loc.Loc{Start: endLoc}), a.Val, \"event-attribute\")\n\t\t\t}\n\t\t\tif a.Key == \"style\" {\n\t\t\t\tp.addTSXStyle(p.builder.OffsetAt(a.ValLoc), p.builder.OffsetAt(loc.Loc{Start: endLoc}), a.Val, \"style-attribute\", \"css\")\n\t\t\t}\n\t\tcase astro.EmptyAttribute:\n\t\t\tp.print(a.Key)\n\t\t\tendLoc = a.KeyLoc.Start + len(a.Key)\n\t\tcase astro.ExpressionAttribute:\n\t\t\tp.print(a.Key)\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start + len(a.Key)})\n\t\t\tp.print(`=`)\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart + 1})\n\t\t\tp.print(`{`)\n\t\t\tp.printTextWithSourcemap(a.Val, loc.Loc{Start: eqStart + 2})\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart + 2 + len(a.Val)})\n\t\t\tp.print(`}`)\n\t\t\tendLoc = eqStart + len(a.Val) + 2\n\t\tcase astro.SpreadAttribute:\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start - 4})\n\t\t\tp.print(\"{\")\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start - 3})\n\t\t\tp.print(\"...\")\n\t\t\tp.printTextWithSourcemap(a.Key, a.KeyLoc)\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start + len(a.Key)})\n\t\t\tp.print(\"}\")\n\t\t\tendLoc = a.KeyLoc.Start + len(a.Key) + 1\n\t\tcase astro.ShorthandAttribute:\n\t\t\twithoutComments := helpers.RemoveComments(a.Key)\n\t\t\tif len(withoutComments) == 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.printf(a.Key)\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start - 1})\n\t\t\tp.printf(\"={\")\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start})\n\t\t\tp.print(a.Key)\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start + len(a.Key)})\n\t\t\tp.print(\"}\")\n\t\t\tendLoc = a.KeyLoc.Start + len(a.Key) + 1\n\t\tcase astro.TemplateLiteralAttribute:\n\t\t\tp.print(a.Key)\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart})\n\t\t\tp.print(`=`)\n\t\t\tp.addNilSourceMapping()\n\t\t\tp.print(`{`)\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.ValLoc.Start - 1})\n\t\t\tp.print(\"`\")\n\t\t\tp.printTextWithSourcemap(a.Val, a.ValLoc)\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.ValLoc.Start + len(a.Val)})\n\t\t\tp.print(\"`\")\n\t\t\tp.addNilSourceMapping()\n\t\t\tp.print(`}`)\n\t\t\tendLoc = a.ValLoc.Start + len(a.Val) + 1\n\t\t}\n\t\tp.addSourceMapping(loc.Loc{Start: endLoc})\n\t}\n\tfor i, a := range invalidTSXAttributes {\n\t\tif i == 0 {\n\t\t\tp.print(\" {...{\")\n\t\t} else {\n\t\t\tp.print(\",\")\n\t\t}\n\t\teqStart := a.KeyLoc.Start + strings.IndexRune(p.sourcetext[a.KeyLoc.Start:], '=')\n\t\tp.addSourceMapping(a.KeyLoc)\n\t\tp.print(`\"`)\n\t\tif a.Namespace != \"\" {\n\t\t\tp.print(a.Namespace)\n\t\t\tp.print(\":\")\n\t\t}\n\t\tswitch a.Type {\n\t\tcase astro.QuotedAttribute:\n\t\t\tp.print(a.Key)\n\t\t\tp.print(`\"`)\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart})\n\t\t\tp.print(`:`)\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart + 1})\n\t\t\tp.print(`\"` + encodeDoubleQuote(a.Val) + `\"`)\n\t\tcase astro.EmptyAttribute:\n\t\t\tp.print(a.Key)\n\t\t\tp.print(`\"`)\n\t\t\tp.addNilSourceMapping()\n\t\t\tp.print(`:`)\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.print(`true`)\n\t\tcase astro.ExpressionAttribute:\n\t\t\tp.print(a.Key)\n\t\t\tp.print(`\"`)\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart})\n\t\t\tp.print(`:`)\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart + 1})\n\t\t\tp.print(`(`)\n\t\t\tp.printTextWithSourcemap(a.Val, loc.Loc{Start: eqStart + 2})\n\t\t\tp.addSourceMapping(loc.Loc{Start: eqStart + 2 + len(a.Val)})\n\t\t\tp.print(`)`)\n\t\tcase astro.SpreadAttribute:\n\t\t\t// noop\n\t\tcase astro.ShorthandAttribute:\n\t\t\twithoutComments := helpers.RemoveComments(a.Key)\n\t\t\tif len(withoutComments) == 0 {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.print(a.Key)\n\t\tcase astro.TemplateLiteralAttribute:\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.print(a.Key)\n\t\t\tp.print(`\":`)\n\t\t\tp.addSourceMapping(a.ValLoc)\n\t\t\tp.print(fmt.Sprintf(\"`%s`\", a.Val))\n\t\t}\n\t\tif i == len(invalidTSXAttributes)-1 {\n\t\t\tp.addNilSourceMapping()\n\t\t\tp.print(\"}}\")\n\t\t}\n\t}\n\tif len(n.Attr) == 0 {\n\t\tendLoc = n.Loc[0].Start + len(n.Data)\n\t}\n\tisSelfClosing := false\n\thasLeadingSpace := false\n\ttmpLoc := endLoc\n\tleadingSpaceLoc := endLoc\n\tif len(p.sourcetext) > tmpLoc {\n\t\tfor i := 0; i < len(p.sourcetext[tmpLoc:]); i++ {\n\t\t\tc := p.sourcetext[endLoc : endLoc+1][0]\n\t\t\tif c == '/' && len(p.sourcetext) > endLoc+1 && p.sourcetext[endLoc+1:][0] == '>' {\n\t\t\t\tisSelfClosing = true\n\t\t\t\tbreak\n\t\t\t} else if c == '>' {\n\t\t\t\tp.addSourceMapping(loc.Loc{Start: endLoc})\n\t\t\t\tendLoc++\n\t\t\t\tbreak\n\t\t\t} else if unicode.IsSpace(rune(c)) || (c == '\\\\' && p.sourcetext[endLoc+1:][0] == 'n') {\n\t\t\t\thasLeadingSpace = true\n\t\t\t\tleadingSpaceLoc = endLoc\n\t\t\t\tendLoc++\n\t\t\t} else {\n\t\t\t\tendLoc++\n\t\t\t}\n\t\t}\n\t} else {\n\t\tendLoc++\n\t}\n\n\tif hasLeadingSpace {\n\t\tp.addSourceMapping(loc.Loc{Start: leadingSpaceLoc})\n\t\tp.print(\" \")\n\t\tp.addSourceMapping(loc.Loc{Start: leadingSpaceLoc + 1})\n\t}\n\n\tif voidElements[n.Data] && n.FirstChild == nil {\n\t\tp.print(\"/>\")\n\t\treturn\n\t}\n\tif isSelfClosing && n.FirstChild == nil {\n\t\tp.addSourceMapping(loc.Loc{Start: endLoc})\n\t\tp.print(\"/>\")\n\t\treturn\n\t}\n\tp.print(\">\")\n\n\tstartTagEndLoc := loc.Loc{Start: endLoc}\n\n\t// Render any child nodes\n\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\trenderTsx(p, c, o)\n\t\tif len(c.Loc) > 1 {\n\t\t\tendLoc = c.Loc[1].Start + len(c.Data) + 1\n\t\t} else if len(c.Loc) == 1 {\n\t\t\tendLoc = c.Loc[0].Start + len(c.Data)\n\t\t}\n\t}\n\n\tif len(n.Loc) > 1 {\n\t\tendLoc = n.Loc[1].Start - 2\n\t} else if n.LastChild != nil && n.LastChild.Expression {\n\t\tif len(n.LastChild.Loc) > 1 {\n\t\t\tendLoc = n.LastChild.Loc[1].Start + 1\n\t\t}\n\t}\n\n\tif n.FirstChild != nil && (n.DataAtom == atom.Script || n.DataAtom == atom.Style) {\n\t\ttagContentEndLoc := loc.Loc{Start: endLoc}\n\t\tif endLoc > len(p.sourcetext) { // Sometimes, when tags are not closed properly, endLoc can be greater than the length of the source text, wonky stuff\n\t\t\ttagContentEndLoc.Start = len(p.sourcetext)\n\t\t}\n\t\tif n.DataAtom == atom.Script {\n\t\t\tp.addTSXScript(p.builder.OffsetAt(startTagEndLoc), p.builder.OffsetAt(tagContentEndLoc), n.FirstChild.Data, getScriptTypeFromAttrs(n.Attr))\n\t\t}\n\t\tif n.DataAtom == atom.Style {\n\t\t\tp.addTSXStyle(p.builder.OffsetAt(startTagEndLoc), p.builder.OffsetAt(tagContentEndLoc), n.FirstChild.Data, \"tag\", getStyleLangFromAttrs(n.Attr))\n\t\t}\n\t}\n\n\t// Special case because of trailing expression close in scripts\n\tif n.DataAtom == atom.Script {\n\t\tp.printf(\"</%s>\", n.Data)\n\t\treturn\n\t}\n\n\tp.addSourceMapping(loc.Loc{Start: endLoc})\n\tp.print(\"</\")\n\tif !isSelfClosing {\n\t\tendLoc += 2\n\t\tp.addSourceMapping(loc.Loc{Start: endLoc})\n\t}\n\tp.print(n.Data)\n\tif !isSelfClosing {\n\t\tendLoc += len(n.Data)\n\t\tp.addSourceMapping(loc.Loc{Start: endLoc})\n\t}\n\tp.print(\">\")\n\tp.addSourceMapping(loc.Loc{Start: endLoc + 1})\n}\n"
  },
  {
    "path": "internal/printer/print-to-tsx_test.go",
    "content": "package printer\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\thandler \"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/transform\"\n)\n\n// One of the more performance-sensitive parts of the compiler is the handling of multibytes characters, this benchmark is an extreme case of that.\nfunc BenchmarkPrintToTSX(b *testing.B) {\n\tsource := `🌘🔅🔘🍮🔭🔁💝🐄👋 🍘👽💽🌉🌒🔝 📇🍨💿🎷🎯💅📱🎭👞🎫💝🍢🕡 augue tincidunt 👠💋🌵💌🍌🏄🕂🍹📣🍟 🐞🍲👷🗻🏢🐫👣🐹🔷🎢👭🍗👃 🐴🐈📐💄 et, 👽👽🔙🐒🔙🍀 🐞🍐🎵💕🍂🍭🎬🎅 ac 🏃👳📑🐶👝🔷 🔕👄🐾👡🍢💗 🌓🔙🌔🏈🔒🔄🎹🎐 🎾🐝🌁📃💞📔🔕🐕 vel 🌟🏁💴🎾🔷📪💼👣📚 👟💻🗾🎋💁🏬🐮💑 🍈🌸🍓🍥💦 et vivamus 🍑🍫🔉🔹💽🍙 rhoncus eu 📰💫💀🌺 🔋💾🔱🔷🐟 convallis facilisi vitae mollis 📨🔚💮🔃🎀🍶 🌠📑🎹🌑📫🗽🐊💁🔼🕓 ac 🌂🌳🌺🎭🍧🐑 🔭🔉💉🍗👠🍦 🔄👔🎭🍇 🏤🍂🌝👜🔺 ornare 🔽🌰🎃💝👩 🐬🌻🍩👺🎆📣 risus 🌼👧🌒🍄💄🌆🐖👐📠 🕙🍈👞🏢👅🎽🏫👃🌾🍘🕑🎼💆🎳 🐻📵🔂🍩🕦👕🐶 💚🏮📟📈🌄👱🔚 sem 🔵💱💭💫 libero bibendum 🌿🍮🎧🍴💉 🐵🔷🍒🍜 sed metus, aliquam 🐷🐬📇👔🎴🔻🏊📴🍂🎽 🏀💡🍺🌾 💣🍇🐼🌀🐟🍂🐰 sed luctus 👾🍠👻💬📋🐈👀🌕💥🐹 consectetur commodo at 📓🐣🔮🐍🔺🍐🗻🍃🍠🔬 🏁🎬🐔🌙 🎿🎊🍳💓👹🐏 👦🐩👶💻 🔉💏📧🔲🍈📹💫🎧 🌟🍯🔭🎿 🎹🗻💳🔄🕁💂 🐩👠🌗🍹 facilisis 👍🍑💤🐕🐞🐻🏩 posuere 🎑🍢🍑🏨📗👣 ultrices. Vestibulum 🌠👰💼📐🍺💫 👘🐖🔕🔤🐖💶🐢📵👍🍪 🔸🎿🔤🍡💡🌄📁👉🎎🎆🎢🔒 📴👉🌱🐍🌓🎆🏩🐀👓💹🎴 🔴🌒🔘👡🕜 🌝🐉🐑🏮🎸🐳💉🎄 🍳🐲🔭📆🐎🔼🎐🐩💾🍈🎶💅🐜🍀. 🍭🍄🌳🍏💍👈🌆 🔦🏦👵🌹🏊🎐📳🌃📘🌷💎📓🎼 🎳🔁🔂🗽 💅🏰🐊👂🌴 💍🕗🐘🔼🔰🏀 🎂📻🕛🍔🎄 vitae 📎🐆🍚🌲🐰 ipsum 👘👎📅🎈🌆💮🔁🎤 💺💉💉👐🔛🐛🐺🍸📭 💠👞🍨💖 integer 🐌📀🍂🍍🐼 volutpat, condimentum elit 🎌🌕🏊👼 🌛🕜🌚🕤🍎 🏢💨👓👤 duis amet 📹🕚🔏🏧🌷🍄👦 🔠🐬👬🍩📫🏧🎷🔢💆🎭🔳👈 🔇👿💈👧🐍🍱🔉 in 🌐🎲🌠🌟🐀👛🌞🎧 sed. Tristique malesuada id 🏆🍕🕚🎯🌶 📺🐘🏀🐮🔶🏀🍥👬💞🎃🌙🎥🔦🍗 👘👣🐂🎪🔂🎾 👎👮💈🗻🌿💰📩🔋💭💃 🍍🕑🔋👠🍆🍈👰🌅 orci nam 🔀🕠🏄🍣👘🐲💘🐥 🏥🎊🎯👾📅 👛🌽🏫🔃👋🐀👶💥🔳 🕥👪👑👯 🐓💡🔠💼🔳💲 👬🔁🍜💘🔌🌎🏃🌶🍏🍯🎺 🔟📨🔜🎱💓🔛 accumsan 🎢🐭🍉🍳🕜🏆🔗📝👿 🍗👑📜🎁🍇🍕🌛 🎓🌰👣📆🌋 👌🍱💏🔇🐆🌞📝💻🌺 dictumst 📡🍝🌐💤🐅🔔🐟📥🌓🌒🍅📨🏡👺🍬🐟 🔹💳🍨💡🎋💕🕜🏦👟🕒🕣💅💗 🏤🔈📀📜📙🍌 📫🕘👍💾📱 purus 🕒🐕👵🏄💗🐤🕝 pharetra adipiscing elit, non 🏬👸🍉👑 🎠🌇👰💄 🌕🗼🏮💇🐗 📌🏤🌲👹📌 🎐🕓📎🏤💾 tellus 💆🍨👂🕟💚🎋🌠🐳 🍘🍫🎵📚📟🔛🐑🏭🔄👌📏👚🏄🐞 💏🍊👾🍘👰📄💯🔑 proin 🐡🔝🐳🎻🐶🍜 🍕🌵📯🔖💅🕔💘🏁🌾💨🔲🔼🍜🍘🕂 in suscipit 🍎🎄🎬🔙👪💣🍣💯🕧 lectus 🌾🍚🍺🐆💉🎡👷 📖🔅👼🕞 🌄🌃📦🔲💘🌶💁🍯💿 senectus 👻💈🗽🍈 📜🍉🍒🍐🔖👙🔀🐅👙 🐬📷🎨👹🎬 🐷🌐🔽💨🎿🌌🌒 🎎🍊🔕🍁. 🍈🌄📧🏊📛👗🕟 🍋💌🔁🐛💫🔰👃🕑 ridiculus mattis 🕓🍌👘🌹 👅💏🍨🔯🍂🕃🌝👠🏁🔔 pellentesque elit eu, 💝🍧💯🔄📈📛🐻📆🔱📴🔸🍻🐘🎀 viverra 🌆🍉🍉🌆 📪🍕🏊🌜📺🔆🐢🎃 mi sed tellus luctus 🍜🍃🔶🗽 laoreet dui tristique 🔆🌸🐛🔣🏤📘🕜🍃🐋 pretium ultrices 🔳🏇🍏🎭🍀 🍱🐠👬📮🌗🌆💺🔆👨🌱 et 👸📁📩🔌👯👏👫👳💸 🐎💉🔱💦👴 🏪🍶🐸🔤 💔🏤👺👻🏤🎥🐽🔦👌🔡📚💡🔁🎻 🎵👡🕀🎩 🍸🐒🍭🕠🔢🎧🍚💪 🌸🍰💏🏁🎥🐕🔬💶 💃🌽💕🐭 💯🍁📭🐚📛📓🌏🔯📦 🕝👾📒📳💵 🏠💺🕔🕁📃 adipiscing nulla congue 🔖💲🕚🎰🔋👬 sem 👽👵👜👇 vehicula 📑🌎🍁💈 consectetur nulla ullamcorper enim, 🏫🍃🐢🔄🍝🕢👖💨👺💰👎💳🏠🏤 vel fermentum porttitor lacus 📱💧🔜🔰👱🎰🐉🔓🕧🍌🕙 🎴🍫🐱🐟🌖🕞🏥🍝📜🔃🏈🔡🐁🔗 💊🍐📝👭🎢🐳🐯📷🐀🔃. 🐦🍚🔵🕜🏩 id 🌔🔤💿🌻🍹 🌎🎈📢🔬🐖💢👸🎭 🍤🔵🔓🕕📪💢🔁👽💴 🐛👶🔢🎹🏄👜📌🍭🔼🎫🍯🎦💎🐦 🐨💧🍴🌊🔁 consequat pretium 👍🏬🏰👖🍥📺👛🌕 🏄🔱🔩🐏🌞🌺🐌👑 🏰🕢💱👖🐶🐥📯🎶💧🍭🔀🎾🏩🍑 massa, est 👶🍭💅🕔🍳💗🍞💚🍩🐷🍘🌄🐇 🐼👀👀🎅 📄🎁🐞💼 placerat erat 💧🌉💻🔣🐥📠🍪📻🐃🔻👠🕘🍞🍈🍔📴 dolor 📁💹🎐🍂🍉 neque, 👗🍁🍪🌵🕛🍄 🕝👔🔼🎡🔺📬 sed 💨💧🏢🐼👘🌳🎼👹🐉🕕 enim 🔏🏁👊💀🔓 🏫🐈💀🌳🔒👵🔘🎺💴🍑 👭🔲🍰💿🔪🌊 🌅🕔🎑📛🔶🔘🎑🍯 🐲📺👬📊🍒 elit, 🌽🎱💇🎥 ultricies 📡💲🐦🌁🍚🌵🍵 🎮📧🔟🍴👕🔏🌴🔊👳🗼💒🌴👍📞🔳👜🔥🐝🐾🐧🍊 🌰🗾🌂🐄 🔛🐀🍏🍞🔔📖💉📼🐥🍱 🐜🎺🍵💿👂🌋🌸 🔞🐤🔟🍀📙🏩👑 porta id 🎄💺🍙👶👪🔪👪🐭💚📗🎅🍐👡🎭 🐦🎌🐆💫 quis nulla dictumst non 📫🍵🔫🕠 🔯🔃🐷📖💙👓💍 🎬🕃🐥🏫🍛🌆🐗👅📷 📚🍭🌞🌎🕐👜👳 🏧💬💴🎆🐄🔠📄🐰📝🌈 🎩🌇🌟📙 suspendisse 🔡👫🍐🏩🌉🕚📘🐮 👐🏁👮🎭🏣 👰📤🍙🏈👓🐰🍦 lacinia diam eu vestibulum donec faucibus 🔝🎴🌷💩🍡🍜💙 🎐🔉🌛📠🏢📄🍆🎆.\n\n<script>console.log(\"That's a lot of emojis.\");</script>\n\n🔲🍀🏨👆👎🏩🏦🎹 nibh 🕞🍃🔻📨 nec pulvinar 📏🐜💻🐸🐾🐾💖 risus 🍫🕜🐑🌳📇🍋🐪🎣 neque 👝🐝🌹🍫🌌👅 👹🏈🗽🐣 💉📊🐘🔉🏆💡🌸👰🔛📼 🍺🌿🐪🔜💄🎒👟 amet vitae, morbi elit rhoncus 🐙🏫🍪🎡👕💵 🌕💁💯🐷🌾📼🐀🍬🌛🕤🐊👔🔩🍂📚💵 💖🐐👹🔼🏠🍢🎼🐧 👛📩🍯💊 📞🌒📞💽 purus 🔐📼📬🌞🍁💸 morbi 🍁🎾🎡🌋 📨🌈🔈🌆🔨📕💛🏡🏯 💅🎣👽🕦 🌴🍋🔐🔑 ut congue 🔊🐧🌻🕑 gravida 🐉👅👦👢🎉🔎💪🔄🎈 👳🏡🕥🎂 🔵🐘🔠🍑👉🔀📊🏡 🌄🍯💽📁📚🐆👆🌂🎡📖🎱👮🌽🐄 orci 📚🍣🐀🎦📪💶🌓 etiam 🌑🐁💇👬🍓📅💸👟🌕🐊🎁🏪 vehicula sed 📒📭📣🌌🐁🎲🌴🏠🔏👯📥💽🌗💲🍡🔫 🎈🏥🍇🔺💍💐🌳👎🎤🍮📭📊 🍓👠🕞🕘🍂🏣🐺🍬🐖 eget lectus 🍄🍍📉📥🌾🎴🏣 🐾🕤🍼🌃🔩🐂🕣🐉💧📊🎧🎧🌂🎠 🐵🌺📰📑🏰 👣🍸💚🐗🔜🕕🐠🕙🏇📲🌙 👫💛💽🐑💸 🔐🔝🔘🎪💻🔂 nunc, 🍹🕗🏡📤🎷 sem vitae adipiscing tempor, 🕡🍚🐈🌟👎💢🔦 🌴💿💔🎳📍🌽🎒🔭🔨 lectus 🌰🌓🗽💀🍈 est 📬💑🕁🍺 📀🏮🔫🔜🎭🌷🏀💑🍂🔵 vulputate leo eget 🍗🌴🎃🔣👲📙 📺🍈🍏💦🌅💔💌 phasellus 👨💡🔯🐃🍜🐒🔵💆🍩🐦🍬🍅🍧 🎲🍰💊🏣📁💎 🔮🎉🎱👿🐟💪🕤 🍡🐜🕚🌏. Turpis vulputate 🌗🔫📙🎽🎽🎿📓 pretium congue in arcu tincidunt. Nisi 📺💍👃🕃🐫 🐝📨🍁🕕💯💭 📬🏧🔧🌟 🏩👛🏭🌽🎮🌁 magnis porttitor 🔈🎄🌓👶🏮. 👢🌵🏬🌏🍩 rutrum egestas 💙🔠🎧🐜🎣 nisi lectus feugiat 🍀🕚🕢🌀🎰💅 💝📮🌝📃🔈 🎓📝🏮🍄📢📛🍺🔊💐 sagittis 🐖🌂🎓👒👎🔼👊📣📭👿🐦🔖🍵💺🐳 🕗🔭🐭📐👍💯 massa erat 🏧🐁🎤👔💑🍣🐢 🍐🗾🔙🍊🎭🔣👐 💊💖🌳💌💿🏯🔴🎪. Id 🐅🐦💝📱💐👓🎡 ut 🏬🔔🌟🌑 🎦💮🎩🔬 👰📵🍘🎴 👪🐩👳💆🍧 purus 💮🐦🐼🎷🔦 🎺🔇🍴📈 cras pretium volutpat, etiam risus 🐇🕔🐪🔽 👠🔮🔈🎃🎧🌄👜 vel sapien 💯👻👜🎼📜 🎽💀🏊🌉📴🍻📐💉📺🐺 vivamus lorem 📃📉🔞🕦 📣🍨🌉🔩🐺🔎👙 molestie tellus 👹💃🕕📗🔵🕢 vel 📎🐍🔅📁🔁🍚🌀💏🐦 🎱🐮🕣👋📳🎑 🕙🏡🕒📖📪👩 condimentum 🐤💐💷🕞💬💝🎨💰 amet nisl fringilla bibendum 🐘🏃🎃🐉🏰🏦🐎🎱🍅🎥🔳🎵🍠🏧🍖🔭💇 🕞🎱📂🐈👇 🍯👐🎹👘💯📗👷 💂🕘👦💘💆🌗🕃🏀🔚 🔜💃🌒🍧🔝🐹🔑💂👜🐭 🎤👌👐🏩📞🕦🔜🍙 morbi 👑🐸🌄🐹🐃🐢🍳💸 malesuada quam amet, 💰🔗👗🐰🍆🕑📮 🍋🌘🐞🍧 🔻🎺🍘👐🍬🔷 pulvinar 🔭🏬👦💆 vivamus tempus 🏧👉🕢📭🔠🌔🕧💧📊🔼 👬🐑🌘🍮🎎🐝🕃👗🔴🐽🐘🌈📺👙🕝.\n\n<div onload=\"console.log('It really is.')\"></div>\n\nFaucibus 🎈🐋🔄📇🐡💐 🎾🎩🔹🔣🎍🐸🌳 vestibulum, 🐢🌘🕜👂💬🎑🍪 📫📊🎅🌷📝🔰🏣💭👧👽🎒📕💓👯 🎎🍁🕥🕑💗🐌📩📧🍸🌙 🕝🐵🐀🐫🎫🔰👲🍛🔵🍪 🍳🏆🎷🐐 quam 💠🎈🕓🌴🌱🍨💢🍮🕡🔡💎🐍 imperdiet placerat 🔱🐑📔🔧🌍 nisl 📢🗻🐹🔏🕕🐐💦 📈🔵📴🍳📬💕📧📓🍚 📈🌸🔱💜💎🌐🍻📘🏠💵🏡🔌📦🐑🍩🔇👅📎🐆 🐌💞📺🐫🍷🌍💒🌸🔎🌇📠🔂🌼💎🍟 ut vel et 🎩👖💾👢🎵💂 🌂📱💳🐨🍲 🍔🔵🏃🎦🕐🌟🌐🔑 tristique vel 🌃💋👉🔰. Tortor sit 🌓👑🔓🐀🌹 tempus 🍸🍹📔🎂🍺🏀 consequat ornare 👽👽🍃📗🌘🍍 🔯🌲📝📥🍐🏣🐸 🍔📝📞🍣 💩🔥💨👋🔹 🌕💊🏪🕡 🏇🏉🐵👢🎳🕛🍸 🐈🏇🏭🕁🍬 rhoncus 📛🍁🔨💶 bibendum 🎋👲🏤📰🍐 🌸📙🍏🌠 🎿🎀👡💲📋💦🐵🔑🕡🕞🍥🍍👧🔘💡 arcu 💣👍🌶👬🌹🔒🌁📠🕖🎓📌🎩📫💬 👋🌚🌶💶🍊💫🔁📲🎺🐮💙🍟 🕦🌁🐡🍵🍒 🍁🍜🍪🔳📞💝💻🎶📦🔵📯🏦🐎 lobortis malesuada 💇💸🏰💅. 🌐🐕🐂📇 🎒💨🔙🐉🎹🔥🔗📴👥🎈📒🔸💍🔇🌙🕁🐊🏣💆💗🔽 tortor 🔵🐚🍓🌱🌆🐀🐻 🔓👦🍌🌔🍯👐🕣 🌅👇📝💰💝 condimentum 🍋💉🐞📆🍲👢🐬💌🎤 🎢👷👑👆 💱🎒🏬🎫 🗾💝👎👄 💊🔅🔙🐮🍗🐥 nulla adipiscing 🎦👿🐞🔋📜👵 🏄🐷🎵👾 🎿🍒🌲💄📚🌔📭👄👿🍱📷💮🔀🍄 velit.`\n\tfor i := 0; i < b.N; i++ {\n\t\th := handler.NewHandler(source, \"AstroBenchmark\")\n\t\tvar doc *astro.Node\n\t\tdoc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true))\n\t\tif err != nil {\n\t\t\th.AppendError(err)\n\t\t}\n\n\t\tPrintToTSX(source, doc, TSXOptions{\n\t\t\tIncludeScripts: false,\n\t\t\tIncludeStyles:  false,\n\t\t}, transform.TransformOptions{\n\t\t\tFilename: \"AstroBenchmark\",\n\t\t}, h)\n\t}\n}\n"
  },
  {
    "path": "internal/printer/printer.go",
    "content": "package printer\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/helpers\"\n\t\"github.com/withastro/compiler/internal/js_scanner\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"github.com/withastro/compiler/internal/sourcemap\"\n\t\"github.com/withastro/compiler/internal/transform\"\n\t\"golang.org/x/net/html/atom\"\n)\n\ntype PrintResult struct {\n\tOutput         []byte\n\tSourceMapChunk sourcemap.Chunk\n\t// Optional, used only for TSX output\n\tTSXRanges TSXRanges\n}\n\ntype printer struct {\n\tsourcetext         string\n\topts               transform.TransformOptions\n\toutput             []byte\n\tbuilder            sourcemap.ChunkBuilder\n\thandler            *handler.Handler\n\thasFuncPrelude     bool\n\thasInternalImports bool\n\thasCSSImports      bool\n\tneedsTransitionCSS bool\n\n\t// Optional, used only for TSX output\n\tranges TSXRanges\n}\n\nvar TEMPLATE_TAG = \"$$render\"\nvar CREATE_ASTRO = \"$$createAstro\"\nvar CREATE_COMPONENT = \"$$createComponent\"\nvar RENDER_COMPONENT = \"$$renderComponent\"\nvar RENDER_HEAD = \"$$renderHead\"\nvar MAYBE_RENDER_HEAD = \"$$maybeRenderHead\"\nvar UNESCAPE_HTML = \"$$unescapeHTML\"\nvar RENDER_SLOT = \"$$renderSlot\"\nvar MERGE_SLOTS = \"$$mergeSlots\"\nvar ADD_ATTRIBUTE = \"$$addAttribute\"\nvar RENDER_TRANSITION = \"$$renderTransition\"\nvar CREATE_TRANSITION_SCOPE = \"$$createTransitionScope\"\nvar SPREAD_ATTRIBUTES = \"$$spreadAttributes\"\nvar DEFINE_STYLE_VARS = \"$$defineStyleVars\"\nvar DEFINE_SCRIPT_VARS = \"$$defineScriptVars\"\nvar CREATE_METADATA = \"$$createMetadata\"\nvar RENDER_SCRIPT = \"$$renderScript\"\nvar METADATA = \"$$metadata\"\nvar RESULT = \"$$result\"\nvar SLOTS = \"$$slots\"\nvar FRAGMENT = \"Fragment\"\nvar BACKTICK = \"`\"\nvar styleModuleSpecExp = regexp.MustCompile(`(\\.css|\\.pcss|\\.postcss|\\.sass|\\.scss|\\.styl|\\.stylus|\\.less)$`)\n\nfunc (p *printer) print(text string) {\n\tp.output = append(p.output, []byte(text)...)\n}\n\nfunc (p *printer) printf(format string, a ...interface{}) {\n\tp.print(fmt.Sprintf(format, a...))\n}\n\nfunc (p *printer) println(text string) {\n\tp.print(text + \"\\n\")\n}\n\nfunc (p *printer) setTSXFrontmatterRange(frontmatterRange loc.TSXRange) {\n\tp.ranges.Frontmatter = frontmatterRange\n}\n\nfunc (p *printer) setTSXBodyRange(componentRange loc.TSXRange) {\n\tp.ranges.Body = componentRange\n}\n\nfunc (p *printer) addTSXScript(start int, end int, content string, scriptType string) {\n\tp.ranges.Scripts = append(p.ranges.Scripts, TSXExtractedTag{\n\t\tLoc: loc.TSXRange{\n\t\t\tStart: start,\n\t\t\tEnd:   end,\n\t\t},\n\t\tContent: content,\n\t\tType:    scriptType,\n\t})\n}\n\nfunc (p *printer) addTSXStyle(start int, end int, content string, styleType string, styleLang string) {\n\tp.ranges.Styles = append(p.ranges.Styles, TSXExtractedTag{\n\t\tLoc: loc.TSXRange{\n\t\t\tStart: start,\n\t\t\tEnd:   end,\n\t\t},\n\t\tContent: content,\n\t\tType:    styleType,\n\t\tLang:    styleLang,\n\t})\n}\n\nfunc (p *printer) getAsyncFuncPrefix() string {\n\t// Decide whether to print `async` if top-level await is used. Use a loose check for now.\n\tfuncPrefix := \"\"\n\tif strings.Contains(p.sourcetext, \"await\") {\n\t\tfuncPrefix = \"async \"\n\t}\n\treturn funcPrefix\n}\n\nfunc (p *printer) printTextWithSourcemap(text string, l loc.Loc) {\n\tstart := l.Start\n\tskipNext := false\n\tfor pos, c := range text {\n\t\tif skipNext {\n\t\t\tskipNext = false\n\t\t\tcontinue\n\t\t}\n\n\t\t// If we encounter a CRLF, map both characters to the same location\n\t\tif c == '\\r' && len(text[pos:]) > 1 && text[pos+1] == '\\n' {\n\t\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\t\tp.print(\"\\r\\n\")\n\t\t\tstart += 2\n\t\t\tskipNext = true\n\t\t\tcontinue\n\t\t}\n\n\t\t_, nextCharByteSize := utf8.DecodeRuneInString(text[pos:])\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.print(string(c))\n\t\tstart += nextCharByteSize\n\t}\n}\n\nfunc (p *printer) printEscapedJSXTextWithSourcemap(text string, l loc.Loc) {\n\tstart := l.Start\n\tskipNext := false\n\tfor pos, c := range text {\n\t\tif skipNext {\n\t\t\tskipNext = false\n\t\t\tcontinue\n\t\t}\n\n\t\t// If we encounter a CRLF, map both characters to the same location\n\t\tif c == '\\r' && len(text[pos:]) > 1 && text[pos+1] == '\\n' {\n\t\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\t\tp.print(\"\\r\\n\")\n\t\t\tstart += 2\n\t\t\tskipNext = true\n\t\t\tcontinue\n\t\t}\n\n\t\t// If we encounter characters invalid in JSX, escape them by putting them in a JS expression\n\t\t// No need to map, since it's just text. We also don't need to handle tags, since this is only for text nodes.\n\t\tif c == '>' || c == '}' {\n\t\t\tp.print(\"{`\")\n\t\t\tp.print(string(c))\n\t\t\tp.print(\"`}\")\n\t\t\tstart++\n\t\t\tcontinue\n\t\t}\n\n\t\t_, nextCharByteSize := utf8.DecodeRuneInString(text[pos:])\n\t\tp.addSourceMapping(loc.Loc{Start: start})\n\t\tp.print(string(c))\n\t\tstart += nextCharByteSize\n\t}\n}\n\nfunc (p *printer) printInternalImports(importSpecifier string, opts *RenderOptions) {\n\tif p.hasInternalImports {\n\t\treturn\n\t}\n\tp.addNilSourceMapping()\n\tp.print(\"\")\n\tp.print(\"import {\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(FRAGMENT + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"render as \" + TEMPLATE_TAG + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"createAstro as \" + CREATE_ASTRO + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"createComponent as \" + CREATE_COMPONENT + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"renderComponent as \" + RENDER_COMPONENT + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"renderHead as \" + RENDER_HEAD + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"maybeRenderHead as \" + MAYBE_RENDER_HEAD + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"unescapeHTML as \" + UNESCAPE_HTML + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"renderSlot as \" + RENDER_SLOT + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"mergeSlots as \" + MERGE_SLOTS + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"addAttribute as \" + ADD_ATTRIBUTE + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"spreadAttributes as \" + SPREAD_ATTRIBUTES + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"defineStyleVars as \" + DEFINE_STYLE_VARS + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"defineScriptVars as \" + DEFINE_SCRIPT_VARS + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"renderTransition as \" + RENDER_TRANSITION + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"createTransitionScope as \" + CREATE_TRANSITION_SCOPE + \",\\n  \")\n\tp.addNilSourceMapping()\n\tp.print(\"renderScript as \" + RENDER_SCRIPT + \",\\n  \")\n\n\t// Only needed if using fallback `resolvePath` as it calls `$$metadata.resolvePath`\n\tif opts.opts.ResolvePath == nil {\n\t\tp.addNilSourceMapping()\n\t\tp.print(\"createMetadata as \" + CREATE_METADATA)\n\t}\n\tp.addNilSourceMapping()\n\tp.print(\"\\n} from \\\"\")\n\tp.print(importSpecifier)\n\tp.print(\"\\\";\\n\")\n\tp.addNilSourceMapping()\n\tp.hasInternalImports = true\n}\n\nfunc (p *printer) printCSSImports(cssLen int) {\n\tif p.hasCSSImports {\n\t\treturn\n\t}\n\ti := 0\n\tfor i < cssLen {\n\t\tp.addNilSourceMapping()\n\t\t// import '/src/pages/index.astro?astro&type=style&index=0&lang.css';\n\t\tp.print(fmt.Sprintf(\"import \\\"%s?astro&type=style&index=%v&lang.css\\\";\", p.opts.Filename, i))\n\t\ti++\n\t}\n\tif p.needsTransitionCSS {\n\t\tp.addNilSourceMapping()\n\t\tp.print(fmt.Sprintf(`import \"%s\";`, p.opts.TransitionsAnimationURL))\n\t}\n\tp.print(\"\\n\")\n\tp.hasCSSImports = true\n}\n\nfunc (p *printer) printRenderHead() {\n\tp.addNilSourceMapping()\n\tp.print(fmt.Sprintf(\"${%s(%s)}\", RENDER_HEAD, RESULT))\n}\n\nfunc (p *printer) printMaybeRenderHead() {\n\tp.addNilSourceMapping()\n\tp.print(fmt.Sprintf(\"${%s(%s)}\", MAYBE_RENDER_HEAD, RESULT))\n}\n\nfunc (p *printer) printReturnOpen() {\n\tp.addNilSourceMapping()\n\tp.print(\"return \")\n\tp.printTemplateLiteralOpen()\n}\n\nfunc (p *printer) printReturnClose() {\n\tp.addNilSourceMapping()\n\tp.printTemplateLiteralClose()\n\tp.println(\";\")\n}\n\nfunc (p *printer) printTemplateLiteralOpen() {\n\tp.addNilSourceMapping()\n\tp.print(fmt.Sprintf(\"%s%s\", TEMPLATE_TAG, BACKTICK))\n}\n\nfunc (p *printer) printTemplateLiteralClose() {\n\tp.addNilSourceMapping()\n\tp.print(BACKTICK)\n}\n\nfunc isTypeModuleScript(n *astro.Node) bool {\n\tt := astro.GetAttribute(n, \"type\")\n\tif t != nil && t.Val == \"module\" {\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (p *printer) printDefineVarsOpen(n *astro.Node) {\n\t// Only handle <script> or <style>\n\tif !(n.DataAtom == atom.Script || n.DataAtom == atom.Style) {\n\t\treturn\n\t}\n\tif !transform.HasAttr(n, \"define:vars\") {\n\t\treturn\n\t}\n\tif n.DataAtom == atom.Script {\n\t\tif !isTypeModuleScript(n) {\n\t\t\tp.print(\"(function(){\")\n\t\t}\n\t}\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == \"define:vars\" {\n\t\t\tvar value string\n\t\t\tvar defineCall string\n\n\t\t\tif n.DataAtom == atom.Script {\n\t\t\t\tdefineCall = DEFINE_SCRIPT_VARS\n\t\t\t} else if n.DataAtom == atom.Style {\n\t\t\t\tdefineCall = DEFINE_STYLE_VARS\n\t\t\t}\n\t\t\tswitch attr.Type {\n\t\t\tcase astro.ExpressionAttribute:\n\t\t\t\tvalue = strings.TrimSpace(attr.Val)\n\t\t\t}\n\t\t\tp.addNilSourceMapping()\n\t\t\tp.print(fmt.Sprintf(\"${%s(\", defineCall))\n\t\t\tp.addSourceMapping(attr.ValLoc)\n\t\t\tp.printf(value)\n\t\t\tp.addNilSourceMapping()\n\t\t\tp.print(\")}\")\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (p *printer) printDefineVarsClose(n *astro.Node) {\n\t// Only handle <script>\n\tif !(n.DataAtom == atom.Script) {\n\t\treturn\n\t}\n\tif !transform.HasAttr(n, \"define:vars\") {\n\t\treturn\n\t}\n\tif !isTypeModuleScript(n) {\n\t\tp.print(\"})();\")\n\t}\n}\n\nfunc (p *printer) printFuncPrelude(opts transform.TransformOptions, printAstroGlobal bool) {\n\tif p.hasFuncPrelude {\n\t\treturn\n\t}\n\tcomponentName := getComponentName(opts.Filename)\n\n\tp.addNilSourceMapping()\n\tp.println(fmt.Sprintf(\"const %s = %s(%s(%s, $$props, %s) => {\", componentName, CREATE_COMPONENT, p.getAsyncFuncPrefix(), RESULT, SLOTS))\n\tif printAstroGlobal {\n\t\tp.addNilSourceMapping()\n\t\tp.println(fmt.Sprintf(\"const Astro = %s.createAstro($$props, %s);\", RESULT, SLOTS))\n\t\tp.addNilSourceMapping()\n\t\tp.println(fmt.Sprintf(\"Astro.self = %s;\", componentName))\n\t}\n\tp.hasFuncPrelude = true\n}\n\nfunc (p *printer) printFuncSuffix(opts transform.TransformOptions, n *astro.Node) {\n\tcomponentName := getComponentName(opts.Filename)\n\tp.addNilSourceMapping()\n\tfilenameArg := \"undefined\"\n\tpropagationArg := \"undefined\"\n\tif len(opts.Filename) > 0 {\n\t\tescapedFilename := strings.ReplaceAll(opts.Filename, \"'\", \"\\\\'\")\n\t\tfilenameArg = fmt.Sprintf(\"'%s'\", escapedFilename)\n\t}\n\tif n.Transition {\n\t\tpropagationArg = \"'self'\"\n\t}\n\tp.println(fmt.Sprintf(\"}, %s, %s);\", filenameArg, propagationArg))\n\tp.println(fmt.Sprintf(\"export default %s;\", componentName))\n}\n\nvar skippedAttributes = map[string]bool{\n\t\"define:vars\":        true,\n\t\"set:text\":           true,\n\t\"set:html\":           true,\n\t\"is:raw\":             true,\n\t\"transition:animate\": true,\n\t\"transition:name\":    true,\n\t\"transition:persist\": true,\n}\n\nvar skippedAttributesToObject = map[string]bool{\n\t\"set:text\":           true,\n\t\"set:html\":           true,\n\t\"is:raw\":             true,\n\t\"transition:animate\": true,\n\t\"transition:name\":    true,\n\t\"transition:persist\": true,\n}\n\nfunc (p *printer) printAttributesToObject(n *astro.Node) {\n\tlastAttributeSkipped := false\n\tp.print(\"{\")\n\tfor i, a := range n.Attr {\n\t\tif i != 0 && !lastAttributeSkipped {\n\t\t\tp.print(\",\")\n\t\t}\n\t\tif _, ok := skippedAttributesToObject[a.Key]; ok {\n\t\t\tlastAttributeSkipped = true\n\t\t\tcontinue\n\t\t}\n\t\tif a.Namespace != \"\" {\n\t\t\ta.Key = fmt.Sprintf(`%s:%s`, a.Namespace, a.Key)\n\t\t}\n\t\tlastAttributeSkipped = false\n\t\tswitch a.Type {\n\t\tcase astro.QuotedAttribute:\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.printf(`\"%s\"`, a.Key)\n\t\t\tp.print(\":\")\n\t\t\tp.addSourceMapping(a.ValLoc)\n\t\t\tp.print(`\"` + escapeDoubleQuote(escapeNewlines(a.Val)) + `\"`)\n\t\tcase astro.EmptyAttribute:\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.printf(`\"%s\"`, a.Key)\n\t\t\tp.print(\":\")\n\t\t\tp.print(\"true\")\n\t\tcase astro.ExpressionAttribute:\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.printf(`\"%s\"`, a.Key)\n\t\t\tp.print(\":\")\n\t\t\tp.addSourceMapping(a.ValLoc)\n\t\t\tif a.Val == \"\" {\n\t\t\t\tp.print(`(void 0)`)\n\t\t\t} else {\n\t\t\t\tp.print(`(` + a.Val + `)`)\n\t\t\t}\n\t\tcase astro.SpreadAttribute:\n\t\t\tp.addSourceMapping(loc.Loc{Start: a.KeyLoc.Start - 3})\n\t\t\tp.print(`...(` + strings.TrimSpace(a.Key) + `)`)\n\t\tcase astro.ShorthandAttribute:\n\t\t\twithoutComments := helpers.RemoveComments(a.Key)\n\t\t\tif len(withoutComments) == 0 {\n\t\t\t\tlastAttributeSkipped = true\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.print(`\"` + withoutComments + `\"`)\n\t\t\tp.print(\":\")\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.print(`(` + strings.TrimSpace(a.Key) + `)`)\n\t\tcase astro.TemplateLiteralAttribute:\n\t\t\tp.addSourceMapping(a.KeyLoc)\n\t\t\tp.printf(`\"%s\"`, strings.TrimSpace(a.Key))\n\t\t\tp.print(\":\")\n\t\t\tp.print(\"`\" + strings.TrimSpace(a.Val) + \"`\")\n\t\t}\n\t}\n\tp.print(\"}\")\n}\n\nfunc (p *printer) printAttribute(attr astro.Attribute, n *astro.Node) {\n\tif _, ok := skippedAttributes[attr.Key]; ok {\n\t\treturn\n\t}\n\n\tif attr.Namespace != \"\" || attr.Type == astro.QuotedAttribute || attr.Type == astro.EmptyAttribute {\n\t\tp.print(\" \")\n\t}\n\n\tif attr.Namespace != \"\" {\n\t\tattr.Key = fmt.Sprintf(\"%s:%s\", attr.Namespace, attr.Key)\n\t}\n\n\tswitch attr.Type {\n\tcase astro.QuotedAttribute:\n\t\tp.addSourceMapping(attr.KeyLoc)\n\t\tp.print(attr.Key)\n\t\tp.addNilSourceMapping()\n\t\tp.print(`=\"`)\n\t\tp.printTextWithSourcemap(encodeDoubleQuote(escapeInterpolation(escapeBackticks(attr.Val))), attr.ValLoc)\n\t\tp.addNilSourceMapping()\n\t\tp.print(`\"`)\n\tcase astro.EmptyAttribute:\n\t\tp.addSourceMapping(attr.KeyLoc)\n\t\tp.print(attr.Key)\n\tcase astro.ExpressionAttribute:\n\t\tp.addNilSourceMapping()\n\t\tp.print(fmt.Sprintf(\"${%s(\", ADD_ATTRIBUTE))\n\t\tif strings.TrimSpace(attr.Val) == \"\" {\n\t\t\tp.addNilSourceMapping()\n\t\t\tp.print(\"(void 0)\")\n\t\t} else {\n\t\t\tp.printTextWithSourcemap(attr.Val, attr.ValLoc)\n\t\t}\n\t\tp.addNilSourceMapping()\n\t\tp.print(`, \"`)\n\t\tp.addSourceMapping(attr.KeyLoc)\n\t\tp.print(attr.Key)\n\t\tp.addNilSourceMapping()\n\t\tp.print(`\")}`)\n\tcase astro.SpreadAttribute:\n\t\tinjectClass := false\n\t\tfor p := n.Parent; p != nil; p = p.Parent {\n\t\t\tif p.Parent == nil && len(p.Styles) != 0 {\n\t\t\t\tinjectClass = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif injectClass {\n\t\t\tfor _, a := range n.Attr {\n\t\t\t\tif a.Key == \"class\" || a.Key == \"class:list\" {\n\t\t\t\t\tinjectClass = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tp.print(fmt.Sprintf(\"${%s(\", SPREAD_ATTRIBUTES))\n\t\tp.addSourceMapping(loc.Loc{Start: attr.KeyLoc.Start - 3})\n\t\tp.print(strings.TrimSpace(attr.Key))\n\t\tif !injectClass {\n\t\t\tp.print(`)}`)\n\t\t} else {\n\t\t\tp.printf(`,undefined,{\"class\":\"astro-%s\"})}`, p.opts.Scope)\n\t\t}\n\tcase astro.ShorthandAttribute:\n\t\twithoutComments := helpers.RemoveComments(attr.Key)\n\t\tif len(withoutComments) == 0 {\n\t\t\treturn\n\t\t}\n\t\tp.print(fmt.Sprintf(\"${%s(\", ADD_ATTRIBUTE))\n\t\tp.addSourceMapping(attr.KeyLoc)\n\t\tp.print(strings.TrimSpace(attr.Key))\n\t\tp.addSourceMapping(attr.KeyLoc)\n\t\tp.print(`, \"` + withoutComments + `\")}`)\n\tcase astro.TemplateLiteralAttribute:\n\t\tp.print(fmt.Sprintf(\"${%s(`\", ADD_ATTRIBUTE))\n\t\tp.addSourceMapping(attr.ValLoc)\n\t\tp.print(strings.TrimSpace(attr.Val))\n\t\tp.addSourceMapping(attr.KeyLoc)\n\t\tp.print(\"`\" + `, \"` + strings.TrimSpace(attr.Key) + `\")}`)\n\t}\n}\n\nfunc (p *printer) addSourceMapping(location loc.Loc) {\n\tif location.Start < 0 {\n\t\tp.builder.AddSourceMapping(loc.Loc{Start: 0}, p.output)\n\t} else {\n\t\tp.builder.AddSourceMapping(location, p.output)\n\t}\n}\n\n// Reset sourcemap by pointing to last possible index\nfunc (p *printer) addNilSourceMapping() {\n\tp.builder.AddSourceMapping(loc.Loc{Start: -1}, p.output)\n}\n\nfunc (p *printer) printTopLevelAstro(opts transform.TransformOptions) {\n\tp.println(fmt.Sprintf(\"const $$Astro = %s(%s);\\nconst Astro = $$Astro;\", CREATE_ASTRO, opts.AstroGlobalArgs))\n}\n\nfunc remove(slice []*astro.Node, node *astro.Node) []*astro.Node {\n\tvar s int\n\tfor i, n := range slice {\n\t\tif n == node {\n\t\t\ts = i\n\t\t}\n\t}\n\treturn append(slice[:s], slice[s+1:]...)\n}\n\nfunc maybeConvertTransition(n *astro.Node) {\n\tif transform.HasAttr(n, transform.TRANSITION_ANIMATE) || transform.HasAttr(n, transform.TRANSITION_NAME) {\n\t\tanimationExpr := convertAttributeValue(n, transform.TRANSITION_ANIMATE)\n\t\ttransitionExpr := convertAttributeValue(n, transform.TRANSITION_NAME)\n\n\t\tn.Attr = append(n.Attr, astro.Attribute{\n\t\t\tKey:  \"data-astro-transition-scope\",\n\t\t\tVal:  fmt.Sprintf(`%s(%s, \"%s\", %s, %s)`, RENDER_TRANSITION, RESULT, n.TransitionScope, animationExpr, transitionExpr),\n\t\t\tType: astro.ExpressionAttribute,\n\t\t})\n\t}\n\tif transform.HasAttr(n, transform.TRANSITION_PERSIST) {\n\t\ttransitionPersistIndex := transform.AttrIndex(n, transform.TRANSITION_PERSIST)\n\t\t// If there no value, create a transition scope for this element\n\t\tif n.Attr[transitionPersistIndex].Val != \"\" {\n\t\t\t// Just rename the attribute\n\t\t\tn.Attr[transitionPersistIndex].Key = \"data-astro-transition-persist\"\n\n\t\t} else if transform.HasAttr(n, transform.TRANSITION_NAME) {\n\t\t\ttransitionNameAttr := transform.GetAttr(n, transform.TRANSITION_NAME)\n\t\t\tn.Attr[transitionPersistIndex].Key = \"data-astro-transition-persist\"\n\t\t\tn.Attr[transitionPersistIndex].Val = transitionNameAttr.Val\n\t\t\tn.Attr[transitionPersistIndex].Type = transitionNameAttr.Type\n\t\t} else {\n\t\t\tn.Attr = append(n.Attr, astro.Attribute{\n\t\t\t\tKey:  \"data-astro-transition-persist\",\n\t\t\t\tVal:  fmt.Sprintf(`%s(%s, \"%s\")`, CREATE_TRANSITION_SCOPE, RESULT, n.TransitionScope),\n\t\t\t\tType: astro.ExpressionAttribute,\n\t\t\t})\n\t\t}\n\n\t\t// Do a simple rename for `transition:persist-props`\n\t\ttransitionPersistPropsIndex := transform.AttrIndex(n, transform.TRANSITION_PERSIST_PROPS)\n\t\tif transitionPersistPropsIndex != -1 {\n\t\t\tn.Attr[transitionPersistPropsIndex].Key = \"data-astro-transition-persist-props\"\n\t\t}\n\t}\n}\n\nfunc (p *printer) printComponentMetadata(doc *astro.Node, opts transform.TransformOptions, source []byte) {\n\tvar specs []string\n\tvar asrts []string\n\tvar conlyspecs []string\n\tunfoundconly := make([]*astro.Node, len(doc.ClientOnlyComponentNodes))\n\tcopy(unfoundconly, doc.ClientOnlyComponentNodes)\n\n\tmodCount := 1\n\tl, statement := js_scanner.NextImportStatement(source, 0)\n\tfor l != -1 {\n\t\tisClientOnlyImport := false\n\tcomponent_loop:\n\t\tfor _, n := range doc.ClientOnlyComponentNodes {\n\t\t\tfor _, imported := range statement.Imports {\n\t\t\t\texportName, isUsed := js_scanner.ExtractComponentExportName(n.Data, imported)\n\t\t\t\tif isUsed {\n\t\t\t\t\tattrTemplate := `\"%s\"`\n\t\t\t\t\tif opts.ResolvePath == nil {\n\t\t\t\t\t\tattrTemplate = `$$metadata.resolvePath(\"%s\")`\n\t\t\t\t\t}\n\t\t\t\t\t// Inject metadata attributes to `client:only` Component\n\t\t\t\t\tpathAttr := astro.Attribute{\n\t\t\t\t\t\tKey:  \"client:component-path\",\n\t\t\t\t\t\tVal:  fmt.Sprintf(attrTemplate, transform.ResolveIdForMatch(statement.Specifier, &opts)),\n\t\t\t\t\t\tType: astro.ExpressionAttribute,\n\t\t\t\t\t}\n\t\t\t\t\tn.Attr = append(n.Attr, pathAttr)\n\t\t\t\t\tconlyspecs = append(conlyspecs, statement.Specifier)\n\n\t\t\t\t\texportAttr := astro.Attribute{\n\t\t\t\t\t\tKey:  \"client:component-export\",\n\t\t\t\t\t\tVal:  exportName,\n\t\t\t\t\t\tType: astro.QuotedAttribute,\n\t\t\t\t\t}\n\t\t\t\t\tn.Attr = append(n.Attr, exportAttr)\n\t\t\t\t\tunfoundconly = remove(unfoundconly, n)\n\n\t\t\t\t\tisClientOnlyImport = true\n\t\t\t\t\tcontinue component_loop\n\t\t\t\t}\n\t\t\t}\n\t\t\tif isClientOnlyImport {\n\t\t\t\tcontinue component_loop\n\t\t\t}\n\t\t}\n\t\tif !isClientOnlyImport && opts.ResolvePath == nil {\n\t\t\tassertions := \"\"\n\t\t\tif statement.Assertions != \"\" {\n\t\t\t\tassertions += \" assert \"\n\t\t\t\tassertions += statement.Assertions\n\t\t\t}\n\n\t\t\tisCSSImport := false\n\t\t\tif len(statement.Imports) == 0 && styleModuleSpecExp.MatchString(statement.Specifier) {\n\t\t\t\tisCSSImport = true\n\t\t\t}\n\n\t\t\tif !isCSSImport && !statement.IsType {\n\t\t\t\tp.print(fmt.Sprintf(\"\\nimport * as $$module%v from '%s'%s;\", modCount, statement.Specifier, assertions))\n\t\t\t\tspecs = append(specs, statement.Specifier)\n\t\t\t\tasrts = append(asrts, statement.Assertions)\n\t\t\t\tmodCount++\n\t\t\t}\n\t\t}\n\t\tl, statement = js_scanner.NextImportStatement(source, l)\n\t}\n\tif len(unfoundconly) > 0 {\n\t\tfor _, n := range unfoundconly {\n\t\t\tp.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\tCode:  loc.ERROR_FRAGMENT_SHORTHAND_ATTRS,\n\t\t\t\tText:  \"Unable to find matching import statement for client:only component\",\n\t\t\t\tHint:  \"A client:only component must match an import statement, either the default export or a named exported, and can't be derived from a variable in the frontmatter.\",\n\t\t\t\tRange: loc.Range{Loc: n.Loc[0], Len: len(n.Data)},\n\t\t\t})\n\t\t}\n\t}\n\t// If we added imports, add a line break.\n\tif modCount > 1 {\n\t\tp.print(\"\\n\")\n\t}\n\n\t// Only needed if using fallback `resolvePath` as it calls `$$metadata.resolvePath`\n\tif opts.ResolvePath != nil {\n\t\treturn\n\t}\n\n\t// Call createMetadata\n\tpatharg := opts.Filename\n\tif patharg == \"\" {\n\t\tpatharg = \"import.meta.url\"\n\t} else {\n\t\tescapedPatharg := strings.ReplaceAll(patharg, \"'\", \"\\\\'\")\n\t\tpatharg = fmt.Sprintf(\"\\\"%s\\\"\", escapedPatharg)\n\t}\n\tp.print(fmt.Sprintf(\"\\nexport const $$metadata = %s(%s, { \", CREATE_METADATA, patharg))\n\n\t// Add modules\n\tp.print(\"modules: [\")\n\tfor i := 1; i < modCount; i++ {\n\t\tif i > 1 {\n\t\t\tp.print(\", \")\n\t\t}\n\t\tasrt := \"{}\"\n\t\tif asrts[i-1] != \"\" {\n\t\t\tasrt = asrts[i-1]\n\t\t}\n\t\tp.print(fmt.Sprintf(\"{ module: $$module%v, specifier: '%s', assert: %s }\", i, specs[i-1], asrt))\n\t}\n\tp.print(\"]\")\n\n\t// Hydrated Components\n\tp.print(\", hydratedComponents: [\")\n\tfor i, node := range doc.HydratedComponentNodes {\n\t\tif i > 0 {\n\t\t\tp.print(\", \")\n\t\t}\n\n\t\tif node.CustomElement {\n\t\t\tp.print(fmt.Sprintf(\"'%s'\", node.Data))\n\t\t} else {\n\t\t\tp.print(node.Data)\n\t\t}\n\t}\n\t// Client-Only Components\n\tp.print(\"], clientOnlyComponents: [\")\n\tuniquespecs := make([]string, 0)\n\ti := 0\nconly_loop:\n\tfor _, spec := range conlyspecs {\n\t\tfor _, uniq := range uniquespecs {\n\t\t\tif uniq == spec {\n\t\t\t\tcontinue conly_loop\n\t\t\t}\n\t\t}\n\t\tif i > 0 {\n\t\t\tp.print(\", \")\n\t\t}\n\t\tp.print(fmt.Sprintf(\"'%s'\", spec))\n\t\ti++\n\t\tuniquespecs = append(uniquespecs, spec)\n\t}\n\tp.print(\"], hydrationDirectives: new Set([\")\n\tj := 0\n\tfor directive := range doc.HydrationDirectives {\n\t\tif j > 0 {\n\t\t\tp.print(\", \")\n\t\t}\n\t\tp.print(fmt.Sprintf(\"'%s'\", directive))\n\t\tj++\n\t}\n\t// Hoisted scripts\n\tp.print(\"]), hoisted: [\")\n\tfor i, node := range doc.Scripts {\n\t\tif i > 0 {\n\t\t\tp.print(\", \")\n\t\t}\n\n\t\tdefineVars := astro.GetAttribute(node, \"define:vars\")\n\t\tsrc := astro.GetAttribute(node, \"src\")\n\n\t\tswitch {\n\t\tcase defineVars != nil:\n\t\t\tkeys := js_scanner.GetObjectKeys([]byte(defineVars.Val))\n\t\t\tparams := make([]byte, 0)\n\t\t\tfor i, key := range keys {\n\t\t\t\tparams = append(params, key...)\n\t\t\t\tif i < len(keys)-1 {\n\t\t\t\t\tparams = append(params, ',')\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.print(fmt.Sprintf(\"{ type: 'define:vars', value: `%s`, keys: '%s' }\", escapeInterpolation(escapeBackticks(node.FirstChild.Data)), escapeSingleQuote(string(params))))\n\t\tcase src != nil:\n\t\t\tp.print(fmt.Sprintf(\"{ type: 'external', src: '%s' }\", escapeSingleQuote(src.Val)))\n\t\tcase node.FirstChild != nil:\n\t\t\tp.print(fmt.Sprintf(\"{ type: 'inline', value: `%s` }\", escapeInterpolation(escapeBackticks(node.FirstChild.Data))))\n\t\t}\n\t}\n\n\tp.print(\"] });\\n\\n\")\n}\n"
  },
  {
    "path": "internal/printer/printer_css_test.go",
    "content": "package printer\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/test_utils\"\n\t\"github.com/withastro/compiler/internal/transform\"\n)\n\ntype testcase_css struct {\n\tname                string\n\tsource              string\n\tscopedStyleStrategy string\n}\n\nfunc TestPrinterCSS(t *testing.T) {\n\ttests := []testcase_css{\n\t\t{\n\t\t\tname: \"styles (no frontmatter)\",\n\t\t\tsource: `<style>\n\t\t  .title {\n\t\t    font-family: fantasy;\n\t\t    font-size: 28px;\n\t\t  }\n\n\t\t  .body {\n\t\t    font-size: 1em;\n\t\t  }\n\t\t</style>\n\n\t\t<h1 class=\"title\">Page Title</h1>\n\t\t<p class=\"body\">I’m a page</p>`,\n\t\t},\n\t\t{\n\t\t\tname: \"scopedStyleStrategy: 'class'\",\n\t\t\tsource: `<style>\n\t\t  .title {\n\t\t    font-family: fantasy;\n\t\t    font-size: 28px;\n\t\t  }\n\n\t\t  .body {\n\t\t    font-size: 1em;\n\t\t  }\n\t\t</style>\n\n\t\t<h1 class=\"title\">Page Title</h1>\n\t\t<p class=\"body\">I’m a page</p>`,\n\t\t\tscopedStyleStrategy: \"class\",\n\t\t},\n\t\t{\n\t\t\tname: \"scopedStyleStrategy: 'attribute'\",\n\t\t\tsource: `<style>\n\t\t  .title {\n\t\t    font-family: fantasy;\n\t\t    font-size: 28px;\n\t\t  }\n\n\t\t  .body {\n\t\t    font-size: 1em;\n\t\t  }\n\t\t</style>\n\n\t\t<h1 class=\"title\">Page Title</h1>\n\t\t<p class=\"body\">I’m a page</p>`,\n\t\t\tscopedStyleStrategy: \"attribute\",\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// transform output from source\n\t\t\tcode := test_utils.Dedent(tt.source)\n\n\t\t\tdoc, err := astro.Parse(strings.NewReader(code))\n\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\n\t\t\tscopedStyleStrategy := \"where\"\n\t\t\tif tt.scopedStyleStrategy == \"class\" || tt.scopedStyleStrategy == \"attribute\" {\n\t\t\t\tscopedStyleStrategy = tt.scopedStyleStrategy\n\t\t\t}\n\n\t\t\thash := astro.HashString(code)\n\t\t\topts := transform.TransformOptions{Scope: hash, ScopedStyleStrategy: scopedStyleStrategy}\n\t\t\ttransform.ExtractStyles(doc, &opts)\n\t\t\ttransform.Transform(doc, opts, handler.NewHandler(code, \"/test.astro\")) // note: we want to test Transform in context here, but more advanced cases could be tested separately\n\t\t\tresult := PrintCSS(code, doc, transform.TransformOptions{\n\t\t\t\tScope:       \"astro-XXXX\",\n\t\t\t\tInternalURL: \"http://localhost:3000/\",\n\t\t\t})\n\t\t\toutput := \"\"\n\t\t\tfor _, bytes := range result.Output {\n\t\t\t\toutput += string(bytes)\n\t\t\t}\n\n\t\t\ttest_utils.MakeSnapshot(\n\t\t\t\t&test_utils.SnapshotOptions{\n\t\t\t\t\tTesting:      t,\n\t\t\t\t\tTestCaseName: tt.name,\n\t\t\t\t\tInput:        code,\n\t\t\t\t\tOutput:       output,\n\t\t\t\t\tKind:         test_utils.CssOutput,\n\t\t\t\t\tFolderName:   \"__printer_css__\",\n\t\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/printer/printer_test.go",
    "content": "package printer\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\ttypes \"github.com/withastro/compiler/internal/t\"\n\t\"github.com/withastro/compiler/internal/test_utils\"\n\t\"github.com/withastro/compiler/internal/transform\"\n)\n\nvar INTERNAL_IMPORTS = fmt.Sprintf(\"import {\\n  %s\\n} from \\\"%s\\\";\\n\", strings.Join([]string{\n\tFRAGMENT,\n\t\"render as \" + TEMPLATE_TAG,\n\t\"createAstro as \" + CREATE_ASTRO,\n\t\"createComponent as \" + CREATE_COMPONENT,\n\t\"renderComponent as \" + RENDER_COMPONENT,\n\t\"renderHead as \" + RENDER_HEAD,\n\t\"maybeRenderHead as \" + MAYBE_RENDER_HEAD,\n\t\"unescapeHTML as \" + UNESCAPE_HTML,\n\t\"renderSlot as \" + RENDER_SLOT,\n\t\"mergeSlots as \" + MERGE_SLOTS,\n\t\"addAttribute as \" + ADD_ATTRIBUTE,\n\t\"spreadAttributes as \" + SPREAD_ATTRIBUTES,\n\t\"defineStyleVars as \" + DEFINE_STYLE_VARS,\n\t\"defineScriptVars as \" + DEFINE_SCRIPT_VARS,\n\t\"renderTransition as \" + RENDER_TRANSITION,\n\t\"createTransitionScope as \" + CREATE_TRANSITION_SCOPE,\n\t\"renderScript as \" + RENDER_SCRIPT,\n\t\"createMetadata as \" + CREATE_METADATA,\n}, \",\\n  \"), \"http://localhost:3000/\")\nvar PRELUDE = fmt.Sprintf(`const $$Component = %s(($$result, $$props, %s) => {`, CREATE_COMPONENT, SLOTS)\nvar PRELUDE_WITH_ASYNC = fmt.Sprintf(`const $$Component = %s(async ($$result, $$props, %s) => {`, CREATE_COMPONENT, SLOTS)\nvar PRELUDE_ASTRO_GLOBAL = fmt.Sprintf(`const Astro = $$result.createAstro($$props, %s);\nAstro.self = $$Component;`, SLOTS)\nvar RETURN = fmt.Sprintf(\"return %s%s\", TEMPLATE_TAG, BACKTICK)\nvar SUFFIX = fmt.Sprintf(\"%s;\", BACKTICK) + `\n}, undefined, undefined);\nexport default $$Component;`\nvar SUFFIX_EXP_TRANSITIONS = fmt.Sprintf(\"%s;\", BACKTICK) + `\n}, undefined, 'self');\nexport default $$Component;`\nvar CREATE_ASTRO_CALL = \"const $$Astro = $$createAstro('https://astro.build');\\nconst Astro = $$Astro;\"\nvar RENDER_HEAD_RESULT = \"${$$renderHead($$result)}\"\n\ntype testcase struct {\n\tname             string\n\tsource           string\n\tonly             bool\n\ttransitions      bool\n\tfilename         string\n}\n\ntype jsonTestcase struct {\n\tname   string\n\tsource string\n\tonly   bool\n}\n\nfunc TestPrinter(t *testing.T) {\n\tlongRandomString := \"\"\n\tfor i := 0; i < 40; i++ {\n\t\tlongRandomString += \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[];:'\\\",.?\"\n\t}\n\n\ttests := []testcase{\n\t\t{\n\t\t\tname:   \"text only\",\n\t\t\tsource: `Foo`,\n\t\t},\n\t\t{\n\t\t\tname:   \"unusual line terminator I\",\n\t\t\tsource: `Pre-set & Time-limited \\u2028holiday campaigns`,\n\t\t},\n\t\t{\n\t\t\tname:   \"unusual line terminator II\",\n\t\t\tsource: `Pre-set & Time-limited  holiday campaigns`,\n\t\t},\n\t\t{\n\t\t\tname:   \"basic (no frontmatter)\",\n\t\t\tsource: `<button>Click</button>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"basic renderHead\",\n\t\t\tsource: `<html><head><title>Ah</title></head></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"head inside slot\",\n\t\t\tsource: `<html><slot><head></head></slot></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"head slot\",\n\t\t\tsource: `<html><head><slot /></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"head slot II\",\n\t\t\tsource: `<html><head><slot /></head><body class=\"a\"></body></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"head slot III\",\n\t\t\tsource: `<html><head><slot name=\"baseHeadExtension\"><meta property=\"test2\" content=\"test2\"/></slot></head>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"ternary component\",\n\t\t\tsource: `{special ? <ChildDiv><p>Special</p></ChildDiv> : <p>Not special</p>}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"ternary layout\",\n\t\t\tsource: `{toggleError ? <BaseLayout><h1>SITE: {Astro.site}</h1></BaseLayout> : <><h1>SITE: {Astro.site}</h1></>}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"orphan slot\",\n\t\t\tsource: `<slot />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"conditional slot\",\n\t\t\tsource: `<Component>{value && <div slot=\"test\">foo</div>}</Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"ternary slot\",\n\t\t\tsource: `<Component>{Math.random() > 0.5 ? <div slot=\"a\">A</div> : <div slot=\"b\">B</div>}</Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"function expression slots I\",\n\t\t\tsource: \"<Component>\\n{() => { switch (value) {\\ncase 'a': return <div slot=\\\"a\\\">A</div>\\ncase 'b': return <div slot=\\\"b\\\">B</div>\\ncase 'c': return <div slot=\\\"c\\\">C</div>\\n}\\n}}\\n</Component>\",\n\t\t},\n\t\t{\n\t\t\tname: \"function expression slots II (#959)\",\n\t\t\tsource: `<Layout title=\"Welcome to Astro.\">\n\t<main>\n\t\t<Layout title=\"switch bug\">\n\t\t\t{components.map((component, i) => {\n\t\t\t\tswitch(component) {\n\t\t\t\t\tcase \"Hero\":\n\t\t\t\t\t\treturn <div>Hero</div>\n\t\t\t\t\tcase \"Component2\":\n\t\t\t\t\t\treturn <div>Component2</div>\n\t\t\t\t}\n\t\t\t})}\n\t\t</Layout>\n\t</main>\n</Layout>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"expression slot\",\n\t\t\tsource: `<Component>{true && <div slot=\"a\">A</div>}{false && <div slot=\"b\">B</div>}</Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"preserve is:inline slot\",\n\t\t\tsource: `<slot is:inline />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"preserve is:inline slot II\",\n\t\t\tsource: `<slot name=\"test\" is:inline />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"slot with fallback\",\n\t\t\tsource: `<body><slot><p>Hello world!</p></slot><body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"slot with fallback II\",\n\t\t\tsource: `<slot name=\"test\"><p>Hello world!</p></slot>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"slot with fallback III\",\n\t\t\tsource: `<div><slot name=\"test\"><p>Fallback</p></slot></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"Preserve slot whitespace\",\n\t\t\tsource: `<Component>\n  <p>Paragraph 1</p>\n  <p>Paragraph 2</p>\n</Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"text only\",\n\t\t\tsource: \"Hello!\",\n\t\t},\n\t\t{\n\t\t\tname:   \"custom-element\",\n\t\t\tsource: \"{show && <client-only-element></client-only-element>}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"attribute with template literal\",\n\t\t\tsource: \"<a :href=\\\"`/home`\\\">Home</a>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"attribute with template literal interpolation\",\n\t\t\tsource: \"<a :href=\\\"`/${url}`\\\">Home</a>\",\n\t\t},\n\t\t{\n\t\t\tname: \"basic (frontmatter)\",\n\t\t\tsource: `---\nconst href = '/about';\n---\n<a href={href}>About</a>`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths (basic)\",\n\t\t\tsource: `---\nexport const getStaticPaths = async () => {\n\treturn { paths: [] }\n}\n---\n<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths (hoisted)\",\n\t\t\tsource: `---\nconst a = 0;\nexport const getStaticPaths = async () => {\n\treturn { paths: [] }\n}\n---\n<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"getStaticPaths (hoisted II)\",\n\t\t\tsource: `---\nconst a = 0;\nexport async function getStaticPaths() {\n\treturn { paths: [] }\n}\nconst b = 0;\n---\n<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"export member does not panic\",\n\t\t\tsource: `---\nmod.export();\n---\n<div />`,\n\t\t},\n\t\t{\n\t\t\tname: \"export comments I\",\n\t\t\tsource: `---\n// hmm\nexport const foo = 0\n/*\n*/\n---`,\n\t\t},\n\t\t{\n\t\t\tname: \"export comments II\",\n\t\t\tsource: `---\n// hmm\nexport const foo = 0;\n/*\n*/\n---`,\n\t\t},\n\t\t{\n\t\t\tname: \"import assertions\",\n\t\t\tsource: `---\nimport data from \"test\" assert { type: 'json' };\n---\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"import to identifier named assert\",\n\n\t\t\tsource: `---\nimport assert from 'test';\n---`,\n\t\t},\n\t\t{\n\t\t\tname:   \"no expressions in math\",\n\t\t\tsource: `<p>Hello, world! This is a <em>buggy</em> formula: <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>f</mi><mspace></mspace><mspace width=\"0.1111em\"></mspace><mo lspace=\"0em\" rspace=\"0.17em\"></mo><mtext> ⁣</mtext><mo lspace=\"0em\" rspace=\"0em\">:</mo><mspace width=\"0.3333em\"></mspace><mi>X</mi><mo>→</mo><msup><mi mathvariant=\"double-struck\">R</mi><mrow><mn>2</mn><mi>x</mi></mrow></msup></mrow><annotation encoding=\"application/x-tex\">f\\colon X \\to \\mathbb R^{2x}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.8889em;vertical-align:-0.1944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace nobreak\"></span><span class=\"mspace\" style=\"margin-right:0.1111em;\"></span><span class=\"mpunct\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mrel\">:</span></span><span class=\"mspace\" style=\"margin-right:0.3333em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.07847em;\">X</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">→</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.8141em;\"></span><span class=\"mord\"><span class=\"mord mathbb\">R</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span><span class=\"mord mathnormal mtight\">x</span></span></span></span></span></span></span></span></span></span></span></span></span></p>`,\n\t\t},\n\t\t{\n\t\t\tname: \"import order\",\n\t\t\tsource: `---\nlet testWord = \"Test\"\n// comment\nimport data from \"test\";\n---\n\n<div>{data}</div>\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"type import\",\n\t\t\tsource: `---\nimport type data from \"test\"\n---\n\n<div>{data}</div>\n`,\n\t\t},\n\t\t{\n\t\t\tname:   \"no expressions in math\",\n\t\t\tsource: `<p>Hello, world! This is a <em>buggy</em> formula: <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>f</mi><mspace></mspace><mspace width=\"0.1111em\"></mspace><mo lspace=\"0em\" rspace=\"0.17em\"></mo><mtext> ⁣</mtext><mo lspace=\"0em\" rspace=\"0em\">:</mo><mspace width=\"0.3333em\"></mspace><mi>X</mi><mo>→</mo><msup><mi mathvariant=\"double-struck\">R</mi><mrow><mn>2</mn><mi>x</mi></mrow></msup></mrow><annotation encoding=\"application/x-tex\">f\\colon X \\to \\mathbb R^{2x}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.8889em;vertical-align:-0.1944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace nobreak\"></span><span class=\"mspace\" style=\"margin-right:0.1111em;\"></span><span class=\"mpunct\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mrel\">:</span></span><span class=\"mspace\" style=\"margin-right:0.3333em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.07847em;\">X</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">→</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.8141em;\"></span><span class=\"mord\"><span class=\"mord mathbb\">R</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">2</span><span class=\"mord mathnormal mtight\">x</span></span></span></span></span></span></span></span></span></span></span></span></span></p>`,\n\t\t},\n\n\t\t{\n\t\t\tname: \"css imports are not included in module metadata\",\n\t\t\tsource: `---\n\t\t\timport './styles.css';\n\t\t\t---\n\t\t\t`,\n\t\t},\n\t\t{\n\t\t\tname:   \"solidus in template literal expression\",\n\t\t\tsource: \"<div value={`${attr ? `a/b` : \\\"c\\\"} awesome`} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nested template literal expression\",\n\t\t\tsource: \"<div value={`${attr ? `a/b ${`c`}` : \\\"d\\\"} awesome`} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"component in expression with its child expression before its child element\",\n\t\t\tsource: \"{list.map(() => (<Component>{name}<link rel=\\\"stylesheet\\\" /></Component>))}\",\n\t\t},\n\t\t{\n\t\t\tname: \"expression returning multiple elements\",\n\t\t\tsource: `<Layout title=\"Welcome to Astro.\">\n\t<main>\n\t\t<h1>Welcome to <span class=\"text-gradient\">Astro</span></h1>\n\t\t{\n\t\t\tObject.entries(DUMMY_DATA).map(([dummyKey, dummyValue]) => {\n\t\t\t\treturn (\n\t\t\t\t\t<p>\n\t\t\t\t\t\tonlyp {dummyKey}\n\t\t\t\t\t</p>\n\t\t\t\t\t<h2>\n\t\t\t\t\t\tonlyh2 {dummyKey}\n\t\t\t\t\t</h2>\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<h2>div+h2 {dummyKey}</h2>\n\t\t\t\t\t</div>\n\t\t\t\t\t<p>\n\t\t\t\t\t\t<h2>p+h2 {dummyKey}</h2>\n\t\t\t\t\t</p>\n\t\t\t\t);\n\t\t\t})\n\t\t}\n\t</main>\n</Layout>`,\n\t\t},\n\t\t{\n\t\t\tname: \"nested template literal expression\",\n\t\t\tsource: `<html lang=\"en\">\n<body>\n{Object.keys(importedAuthors).map(author => <p><div>hello</div></p>)}\n{Object.keys(importedAuthors).map(author => <p><div>{author}</div></p>)}\n</body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"complex nested template literal expression\",\n\t\t\tsource: \"<div value={`${attr ? `a/b ${`c ${`d ${cool}`}`}` : \\\"d\\\"} ahhhh`} />\",\n\t\t},\n\t\t{\n\t\t\tname: \"component\",\n\t\t\tsource: `---\nimport VueComponent from '../components/Vue.vue';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <VueComponent />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"dot component\",\n\t\t\tsource: `---\nimport * as ns from '../components';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <ns.Component />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"component with quoted attributes\",\n\t\t\tsource: `<Component is='\"cool\"' />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"slot with quoted attributes\",\n\t\t\tsource: `<Component><div slot='\"name\"' /></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"#955 ternary slot with text\",\n\t\t\tsource: `<Component>Hello{isLeaf ? <p>Leaf</p> : <p>Branch</p>}world</Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"#955 ternary slot with elements\",\n\t\t\tsource: `<Component><div>{isLeaf ? <p>Leaf</p> : <p>Branch</p>}</div></Component>`,\n\t\t},\n\t\t{\n\t\t\tname: \"noscript component\",\n\t\t\tsource: `\n<html>\n  <head></head>\n  <body>\n\t<noscript>\n\t\t<Component />\n\t</noscript>\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"noscript styles\",\n\t\t\tsource: `<noscript><style>div { color: red; }</style></noscript>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"noscript deep styles\",\n\t\t\tsource: `<body><noscript><div><div><div><style>div { color: red; }</style></div></div></div></noscript></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"noscript only\",\n\t\t\tsource: `<noscript><h1>Hello world</h1></noscript>`,\n\t\t},\n\t\t{\n\t\t\tname: \"client:only component (default)\",\n\t\t\tsource: `---\nimport Component from '../components';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <Component client:only />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"client:only component (named)\",\n\t\t\tsource: `---\nimport { Component } from '../components';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <Component client:only />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"client:only component (namespace)\",\n\t\t\tsource: `---\nimport * as components from '../components';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <components.A client:only />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"client:only component (namespaced default)\",\n\t\t\tsource: `---\nimport defaultImport from '../components/ui-1';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n\t<defaultImport.Counter1 client:only />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"client:only component (namespaced named)\",\n\t\t\tsource: `---\nimport { namedImport } from '../components/ui-2';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n\t<namedImport.Counter2 client:only />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"client:only component (multiple)\",\n\t\t\tsource: `---\nimport Component from '../components';\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <Component test=\"a\" client:only />\n\t<Component test=\"b\" client:only />\n\t<Component test=\"c\" client:only />\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"iframe\",\n\t\t\tsource: `<iframe src=\"something\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"conditional render\",\n\t\t\tsource: `<body>{false ? <div>#f</div> : <div>#t</div>}</body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"conditional noscript\",\n\t\t\tsource: `{mode === \"production\" && <noscript>Hello</noscript>}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"conditional iframe\",\n\t\t\tsource: `{bool && <iframe src=\"something\">content</iframe>}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"simple ternary\",\n\t\t\tsource: `<body>{link ? <a href=\"/\">{link}</a> : <div>no link</div>}</body>`,\n\t\t},\n\t\t{\n\t\t\tname: \"map basic\",\n\t\t\tsource: `---\nconst items = [0, 1, 2];\n---\n<ul>\n\t{items.map(item => {\n\t\treturn <li>{item}</li>;\n\t})}\n</ul>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"map without component\",\n\t\t\tsource: `<header><nav>{menu.map((item) => <a href={item.href}>{item.title}</a>)}</nav></header>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"map with component\",\n\t\t\tsource: `<header><nav>{menu.map((item) => <a href={item.href}>{item.title}</a>)}</nav><Hello/></header>`,\n\t\t},\n\t\t{\n\t\t\tname: \"map nested\",\n\t\t\tsource: `---\nconst groups = [[0, 1, 2], [3, 4, 5]];\n---\n<div>\n\t{groups.map(items => {\n\t\treturn <ul>{\n\t\t\titems.map(item => {\n\t\t\t\treturn <li>{item}</li>;\n\t\t\t})\n\t\t}</ul>\n\t})}\n</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"backtick in HTML comment\",\n\t\t\tsource: \"<body><!-- `npm install astro` --></body>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"HTML comment in component inside expression I\",\n\t\t\tsource: \"{(() => <Component><!--Hi--></Component>)}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"HTML comment in component inside expression II\",\n\t\t\tsource: \"{list.map(() => <Component><!--Hi--></Component>)}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions\",\n\t\t\tsource: `<article>{(previous || next) && <aside>{previous && <div>Previous Article: <a rel=\"prev\" href={new URL(previous.link, Astro.site).pathname}>{previous.text}</a></div>}{next && <div>Next Article: <a rel=\"next\" href={new URL(next.link, Astro.site).pathname}>{next.text}</a></div>}</aside>}</article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions II\",\n\t\t\tsource: `<article>{(previous || next) && <aside>{previous && <div>Previous Article: <a rel=\"prev\" href={new URL(previous.link, Astro.site).pathname}>{previous.text}</a></div>} {next && <div>Next Article: <a rel=\"next\" href={new URL(next.link, Astro.site).pathname}>{next.text}</a></div>}</aside>}</article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions III\",\n\t\t\tsource: `<div>{x.map((x) => x ? <div>{true ? <span>{x}</span> : null}</div> : <div>{false ? null : <span>{x}</span>}</div>)}</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions IV\",\n\t\t\tsource: `<div>{() => { if (value > 0.25) { return <span>Default</span> } else if (value > 0.5) { return <span>Another</span> } else if (value > 0.75) { return <span>Other</span> } return <span>Yet Other</span> }}</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions V\",\n\t\t\tsource: `<div><h1>title</h1>{list.map(group => <Fragment><h2>{group.label}</h2>{group.items.map(item => <span>{item}</span>)}</Fragment>)}</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions VI\",\n\t\t\tsource: `<div>{()=>{ if (true) { return <hr />;} if (true) { return <img />;}}}</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions VII\",\n\t\t\tsource: `<div>{() => { if (value > 0.25) { return <br />;} else if (value > 0.5) { return <hr />;} else if (value > 0.75) { return <div />;} return <div>Yaaay</div>;}</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nested expressions VIII\",\n\t\t\tsource: `<div>{ items.map(({ type, ...data }) => { switch (type) { case 'card': { return ( <Card {...data} /> ); } case 'paragraph': { return ( <p>{data.body}</p>);}}})}</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"expressions with JS comments\",\n\t\t\tsource: `---\nconst items = ['red', 'yellow', 'blue'];\n---\n<div>\n  {items.map((item) => (\n    // foo < > < }\n    <div id={color}>color</div>\n  ))}\n  {items.map((item) => (\n    /* foo < > < } */ <div id={color}>color</div>\n  ))}\n</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"expressions with multiple curly braces\",\n\t\t\tsource: `\n<div>\n{\n\t() => {\n\t\tlet generate = (input) => {\n\t\t\tlet a = () => { return; };\n\t\t\tlet b = () => { return; };\n\t\t\tlet c = () => { return; };\n\t\t};\n\t}\n}\n</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"slots (basic)\",\n\t\t\tsource: `---\nimport Component from \"test\";\n---\n<Component>\n\t<div>Default</div>\n\t<div slot=\"named\">Named</div>\n</Component>`,\n\t\t},\n\t\t{\n\t\t\tname: \"slots (no comments)\",\n\t\t\tsource: `---\nimport Component from 'test';\n---\n<Component>\n\t<div>Default</div>\n\t<!-- A comment! -->\n\t<div slot=\"named\">Named</div>\n</Component>`,\n\t\t},\n\t\t{\n\t\t\tname: \"slots (expression)\",\n\t\t\tsource: `\n<Component {data}>\n\t{items.map(item => <div>{item}</div>)}\n</Component>`,\n\t\t},\n\t\t{\n\t\t\tname: \"head expression\",\n\t\t\tsource: `---\nconst name = \"world\";\n---\n<html>\n  <head>\n    <title>Hello {name}</title>\n  </head>\n  <body>\n    <div></div>\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"head expression and conditional rendering of fragment\",\n\t\t\tsource: `---\nconst testBool = true;\n---\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<title>{testBool ? \"Hey\" : \"Bye\"}</title>\n\t\t{testBool && (<><meta name=\"description\" content=\"test\" /></>)}\n\t</head>\n\t<body>\n\t  <div></div>\n\t</body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"conditional rendering of title containing expression\",\n\t\t\tsource: `{\n  props.title && (\n    <>\n      <title>{props.title}</title>\n      <meta property=\"og:title\" content={props.title} />\n      <meta name=\"twitter:title\" content={props.title} />\n    </>\n  )\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"styles (no frontmatter)\",\n\t\t\tsource: `<style>\n\t\t  .title {\n\t\t    font-family: fantasy;\n\t\t    font-size: 28px;\n\t\t  }\n\n\t\t  .body {\n\t\t    font-size: 1em;\n\t\t  }\n\t\t</style>\n\n\t\t<h1 class=\"title\">Page Title</h1>\n\t\t<p class=\"body\">I’m a page</p>`,\n\t\t},\n\t\t{\n\t\t\tname: \"html5 boilerplate\",\n\t\t\tsource: `<!doctype html>\n\n<html lang=\"en\">\n<head>\n  <meta charset=\"utf-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\n  <title>A Basic HTML5 Template</title>\n  <meta name=\"description\" content=\"A simple HTML5 Template for new projects.\">\n  <meta name=\"author\" content=\"SitePoint\">\n\n  <meta property=\"og:title\" content=\"A Basic HTML5 Template\">\n  <meta property=\"og:type\" content=\"website\">\n  <meta property=\"og:url\" content=\"https://www.sitepoint.com/a-basic-html5-template/\">\n  <meta property=\"og:description\" content=\"A simple HTML5 Template for new projects.\">\n  <meta property=\"og:image\" content=\"image.png\">\n\n  <link rel=\"icon\" href=\"/favicon.ico\">\n  <link rel=\"icon\" href=\"/favicon.svg\" type=\"image/svg+xml\">\n  <link rel=\"apple-touch-icon\" href=\"/apple-touch-icon.png\">\n\n  <link rel=\"stylesheet\" href=\"css/styles.css?v=1.0\">\n\n</head>\n\n<body>\n  <!-- your content here... -->\n  <script is:inline src=\"js/scripts.js\"></script>\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"React framework example\",\n\t\t\tsource: `---\n// Component Imports\nimport Counter from '../components/Counter.jsx'\nconst someProps = {\n  count: 0,\n}\n\n// Full Astro Component Syntax:\n// https://docs.astro.build/core-concepts/astro-components/\n---\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta\n      name=\"viewport\"\n      content=\"width=device-width\"\n    />\n    <link rel=\"icon\" type=\"image/x-icon\" href=\"/favicon.ico\" />\n    <style>\n      :global(:root) {\n        font-family: system-ui;\n        padding: 2em 0;\n      }\n      :global(.counter) {\n        display: grid;\n        grid-template-columns: repeat(3, minmax(0, 1fr));\n        place-items: center;\n        font-size: 2em;\n        margin-top: 2em;\n      }\n      :global(.children) {\n        display: grid;\n        place-items: center;\n        margin-bottom: 2em;\n      }\n    </style>\n  </head>\n  <body>\n    <main>\n      <Counter {...someProps} client:visible>\n        <h1>Hello React!</h1>\n      </Counter>\n    </main>\n  </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"script in <head>\",\n\t\t\tsource: `---\nimport Widget from '../components/Widget.astro';\nimport Widget2 from '../components/Widget2.astro';\n---\n<html lang=\"en\">\n  <head>\n    <script type=\"module\" src=\"/regular_script.js\"></script>\n  </head>`,\n\t\t},\n\t\t{\n\t\t\tname: \"script hoist with frontmatter\",\n\t\t\tsource: `---\n---\n<script type=\"module\" hoist>console.log(\"Hello\");</script>`,\n\t\t},\n\t\t{\n\t\t\tname: \"script hoist without frontmatter\",\n\t\t\tsource: `\n\t\t\t\t\t\t\t<main>\n\t\t\t\t\t\t\t\t<script type=\"module\" hoist>console.log(\"Hello\");</script>\n\t\t\t\t\t\t\t`,\n\t\t},\n\t\t{\n\t\t\tname:   \"scriptinline\",\n\t\t\tsource: `<main><script is:inline type=\"module\">console.log(\"Hello\");</script>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"script define:vars I\",\n\t\t\tsource: `<script define:vars={{ value: 0 }}>console.log(value);</script>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"script define:vars II\",\n\t\t\tsource: `<script define:vars={{ \"dash-case\": true }}>console.log(dashCase);</script>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"script before elements\",\n\t\t\tsource: `<script>Here</script><div></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"script\",\n\t\t\tsource: `<main><script>console.log(\"Hello\");</script>`,\n\t\t\tfilename: \"/src/pages/index.astro\",\n\t\t},\n\t\t{\n\t\t\tname:   \"script multiple\",\n\t\t\tsource: `<main><script>console.log(\"Hello\");</script><script>console.log(\"World\");</script>`,\n\t\t\tfilename: \"/src/pages/index.astro\",\n\t\t},\n\t\t{\n\t\t\tname:   \"script external\",\n\t\t\tsource: `<main><script src=\"./hello.js\"></script>`,\n\t\t\tfilename: \"/src/pages/index.astro\",\n\t\t},\n\t\t{\n\t\t\tname:   \"script external in expression\",\n\t\t\tsource: `<main>{<script src=\"./hello.js\"></script>}`,\n\t\t\tfilename: \"/src/pages/index.astro\",\n\t\t},\n\t\t{\n\t\t\tname:   \"script in expression\",\n\t\t\tsource: `<main>{true && <script>console.log(\"hello\")</script>}`,\n\t\t\tfilename: \"/src/pages/index.astro\",\n\t\t},\n\t\t{\n\t\t\tname:   \"script inline\",\n\t\t\tsource: `<main><script is:inline type=\"module\">console.log(\"Hello\");</script>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"script mixed handled and inline\",\n\t\t\tsource: `<main><script>console.log(\"Hello\");</script><script is:inline>console.log(\"World\");</script>`,\n\t\t\tfilename: \"/src/pages/index.astro\",\n\t\t},\n\t\t{\n\t\t\tname:   \"text after title expression\",\n\t\t\tsource: `<title>a {expr} b</title>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"text after title expressions\",\n\t\t\tsource: `<title>a {expr} b {expr} c</title>`,\n\t\t},\n\t\t{\n\t\t\tname: \"slots (dynamic name)\",\n\t\t\tsource: `---\nimport Component from 'test';\nconst name = 'named';\n\t\t---\n\t\t<Component>\n\t\t\t<div slot={name}>Named</div>\n\t\t</Component>`,\n\t\t},\n\t\t{\n\t\t\tname: \"slots (named only)\",\n\t\t\tsource: `<Slotted>\n      <span slot=\"a\">A</span>\n      <span slot=\"b\">B</span>\n      <span slot=\"c\">C</span>\n    </Slotted>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"condition expressions at the top-level\",\n\t\t\tsource: `{cond && <span></span>}{cond && <strong></strong>}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"condition expressions at the top-level with head content\",\n\t\t\tsource: `{cond && <meta charset=utf8>}{cond && <title>My title</title>}`,\n\t\t},\n\t\t{\n\t\t\tname: \"custom elements\",\n\t\t\tsource: `---\nimport 'test';\n---\n<my-element></my-element>`,\n\t\t},\n\t\t{\n\t\t\tname: \"gets all potential hydrated components\",\n\t\t\tsource: `---\nimport One from 'one';\nimport Two from 'two';\nimport 'custom-element';\nconst name = 'world';\n---\n<One client:load />\n<Two client:load />\n<my-element client:load />\n`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Component siblings are siblings\",\n\t\t\tsource: `<BaseHead></BaseHead><link href=\"test\">`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Self-closing components siblings are siblings\",\n\t\t\tsource: `<BaseHead /><link href=\"test\">`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Self-closing script in head works\",\n\t\t\tsource: `<html><head><script is:inline /></head><html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Self-closing title\",\n\t\t\tsource: `<title />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Self-closing title II\",\n\t\t\tsource: `<html><head><title /></head><body></body></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Self-closing components in head can have siblings\",\n\t\t\tsource: `<html><head><BaseHead /><link href=\"test\"></head><html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Self-closing formatting elements\",\n\t\t\tsource: `<div id=\"1\"><div id=\"2\"><div id=\"3\"><i/><i/><i/></div></div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"Self-closing formatting elements 2\",\n\t\t\tsource: `<body>\n  <div id=\"1\"><div id=\"2\"><div id=\"3\"><i id=\"a\" /></div></div></div>\n  <div id=\"4\"><div id=\"5\"><div id=\"6\"><i id=\"b\" /></div></div></div>\n  <div id=\"7\"><div id=\"8\"><div id=\"9\"><i id=\"c\" /></div></div></div>\n</body>`,\n\t\t},\n\t\t{\n\t\t\tname: \"Nested HTML in expressions, wrapped in parens\",\n\t\t\tsource: `---\nconst image = './penguin.png';\nconst canonicalURL = new URL('http://example.com');\n---\n{image && (<meta property=\"og:image\" content={new URL(image, canonicalURL)}>)}`,\n\t\t},\n\t\t{\n\t\t\tname: \"Use of interfaces within frontmatter\",\n\t\t\tsource: `---\ninterface MarkdownFrontmatter {\n\tdate: number;\n\timage: string;\n\tauthor: string;\n}\nlet allPosts = Astro.fetchContent<MarkdownFrontmatter>('./post/*.md');\n---\n<div>testing</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"dynamic import\",\n\t\t\tsource: `---\nconst markdownDocs = await Astro.glob('../markdown/*.md')\nconst article2 = await import('../markdown/article2.md')\n---\n<div />\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"Component names A-Z\",\n\t\t\tsource: `---\nimport AComponent from '../components/AComponent.jsx';\nimport ZComponent from '../components/ZComponent.jsx';\n---\n\n<body>\n  <AComponent />\n  <ZComponent />\n</body>`,\n\t\t},\n\t\t{\n\t\t\tname: \"Parser can handle files > 4096 chars\",\n\t\t\tsource: `<html><body>` + longRandomString + `<img\n  width=\"1600\"\n  height=\"1131\"\n  class=\"img\"\n  src=\"https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75\"\n  srcSet=\"https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 800w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1200&q=75 1200w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=1600&q=75 1600w,https://images.unsplash.com/photo-1469854523086-cc02fe5d8800?w=2400&q=75 2400w\"\n  sizes=\"(max-width: 800px) 800px, (max-width: 1200px) 1200px, (max-width: 1600px) 1600px, (max-width: 2400px) 2400px, 1200px\"\n>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"SVG styles\",\n\t\t\tsource: `<svg><style>path { fill: red; }</style></svg>`,\n\t\t},\n\t\t{\n\t\t\tname: \"svg expressions\",\n\t\t\tsource: `---\nconst title = 'icon';\n---\n<svg>{title ?? null}</svg>`,\n\t\t},\n\t\t{\n\t\t\tname: \"advanced svg expression\",\n\t\t\tsource: `---\nconst title = 'icon';\n---\n<svg>{title ? <title>{title}</title> : null}</svg>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Empty script\",\n\t\t\tsource: `<script hoist></script>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Empty style\",\n\t\t\tsource: `<style define:vars={{ color: \"Gainsboro\" }}></style>`,\n\t\t},\n\t\t{\n\t\t\tname: \"No extra script tag\",\n\t\t\tsource: `<!-- Global Metadata -->\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width\">\n\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n<link rel=\"alternate icon\" type=\"image/x-icon\" href=\"/favicon.ico\" />\n\n<link rel=\"sitemap\" href=\"/sitemap.xml\"/>\n\n<!-- Global CSS -->\n<link rel=\"stylesheet\" href=\"/theme.css\" />\n<link rel=\"stylesheet\" href=\"/code.css\" />\n<link rel=\"stylesheet\" href=\"/index.css\" />\n\n<!-- Preload Fonts -->\n<link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n<link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n<link href=\"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital@0;1&display=swap\" rel=\"stylesheet\">\n\n<!-- Scrollable a11y code helper -->\n<script type=\"module\" src=\"/make-scrollable-code-focusable.js\" />\n\n<!-- This is intentionally inlined to avoid FOUC -->\n<script is:inline>\n  const root = document.documentElement;\n  const theme = localStorage.getItem('theme');\n  if (theme === 'dark' || (!theme) && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n    root.classList.add('theme-dark');\n  } else {\n    root.classList.remove('theme-dark');\n  }\n</script>\n\n<!-- Global site tag (gtag.js) - Google Analytics -->\n<!-- <script async src=\"https://www.googletagmanager.com/gtag/js?id=G-TEL60V1WM9\"></script>\n<script>\n  window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n  gtag('config', 'G-TEL60V1WM9');\n</script> -->`,\n\t\t},\n\t\t{\n\t\t\tname: \"All components\",\n\t\t\tsource: `\n---\nimport { Container, Col, Row } from 'react-bootstrap';\n---\n<Container>\n    <Row>\n        <Col>\n            <h1>Hi!</h1>\n        </Col>\n    </Row>\n</Container>\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"Mixed style siblings\",\n\t\t\tsource: `<head>\n\t<style is:global>div { color: red }</style>\n\t<style is:scoped>div { color: green }</style>\n\t<style>div { color: blue }</style>\n</head>\n<div />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"spread with double quotation marks\",\n\t\t\tsource: `<div {...propsFn(\"string\")}/>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"class with spread\",\n\t\t\tsource: `<div class=\"something\" {...Astro.props} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"class:list with spread\",\n\t\t\tsource: `<div class:list=\"something\" {...Astro.props} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"class list\",\n\t\t\tsource: `<div class:list={['one', 'variable']} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"class and class list simple array\",\n\t\t\tsource: `<div class=\"two\" class:list={['one', 'variable']} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"class and class list object\",\n\t\t\tsource: `<div class=\"two three\" class:list={['hello goodbye', { hello: true, world: true }]} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"class and class list set\",\n\t\t\tsource: `<div class=\"two three\" class:list={[ new Set([{hello: true, world: true}]) ]} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"spread without style or class\",\n\t\t\tsource: `<div {...Astro.props} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"spread with style but no explicit class\",\n\t\t\tsource: `<style>div { color: red; }</style><div {...Astro.props} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment\",\n\t\t\tsource: `<body><Fragment><div>Default</div><div>Named</div></Fragment></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment shorthand\",\n\t\t\tsource: `<body><><div>Default</div><div>Named</div></></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment shorthand only\",\n\t\t\tsource: `<>Hello</>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment literal only\",\n\t\t\tsource: `<Fragment>world</Fragment>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment slotted\",\n\t\t\tsource: `<body><Component><><div>Default</div><div>Named</div></></Component></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment slotted with name\",\n\t\t\tsource: `<body><Component><Fragment slot=named><div>Default</div><div>Named</div></Fragment></Component></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment with await\",\n\t\t\tsource: `<body><Fragment> { await Promise.resolve(\"Awaited\") } </Fragment></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment shorthand with await\",\n\t\t\tsource: `<body><> { await Promise.resolve(\"Awaited\") } </></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment wrapping link with awaited href\",\n\t\t\tsource: `<head><Fragment><link rel=\"preload\" href={(await import('../fonts/some-font.woff2')).default} as=\"font\" crossorigin /></Fragment></head>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Component with await\",\n\t\t\tsource: `<body><Component> { await Promise.resolve(\"Awaited\") } </Component></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve slots inside custom-element\",\n\t\t\tsource: `<body><my-element><div slot=name>Name</div><div>Default</div></my-element></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve slot attribute in expression for custom element\",\n\t\t\tsource: `<body><my-element>{!href ? <button slot={slotName}>Button</button> : <a href={href} slot={slotName}>Link</a>}</my-element></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve slot attribute in conditional expression for custom element\",\n\t\t\tsource: `<body><my-element>{show && <div slot=\"content\">Content</div>}</my-element></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve slot attribute at root level in expression\",\n\t\t\tsource: `{!href ? <button slot={slotName}>Button</button> : <a href={href} slot={slotName}>Link</a>}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve namespaces\",\n\t\t\tsource: `<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect xlink:href=\"#id\"></svg>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve namespaces in expressions\",\n\t\t\tsource: `<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect xlink:href={` + BACKTICK + `#${iconId}` + BACKTICK + `}></svg>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve namespaces for components\",\n\t\t\tsource: `<Component some:thing=\"foobar\">`,\n\t\t},\n\t\t{\n\t\t\tname: \"import.meta.env\",\n\t\t\tsource: fmt.Sprintf(`---\nimport Header from '../../components/Header.jsx'\nimport Footer from '../../components/Footer.astro'\nimport ProductPageContent from '../../components/ProductPageContent.jsx';\n\nexport async function getStaticPaths() {\n  let products = await fetch(%s${import.meta.env.PUBLIC_NETLIFY_URL}/.netlify/functions/get-product-list%s)\n    .then(res => res.json()).then((response) => {\n      console.log('--- built product pages ---')\n      return response.products.edges\n    });\n\n  return products.map((p, i) => {\n    return {\n      params: {pid: p.node.handle},\n      props: {product: p},\n    };\n  });\n}\n\nconst { product } = Astro.props;\n---\n\n<!doctype html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  <title>Shoperoni | Buy {product.node.title}</title>\n\n  <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\">\n  <link rel=\"stylesheet\" href=\"/style/global.css\">\n</head>\n<body>\n  <Header />\n  <div class=\"product-page\">\n    <article>\n      <ProductPageContent client:visible product={product.node} />\n    </article>\n  </div>\n  <Footer />\n</body>\n</html>`, BACKTICK, BACKTICK),\n\t\t},\n\t\t{\n\t\t\tname: \"import.meta\",\n\t\t\tsource: `---\nconst components = import.meta.glob(\"../components/*.astro\", {\n  import: 'default'\n});\n---`,\n\t\t},\n\t\t{\n\t\t\tname:   \"doctype\",\n\t\t\tsource: `<!DOCTYPE html><div/>`,\n\t\t},\n\t\t{\n\t\t\tname: \"select option expression\",\n\t\t\tsource: `---\nconst value = 'test';\n---\n<select><option>{value}</option></select>`,\n\t\t},\n\t\t{\n\t\t\tname: \"select nested option\",\n\t\t\tsource: `---\nconst value = 'test';\n---\n<select>{value && <option>{value}</option>}</select>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"select map expression\",\n\t\t\tsource: `<select>{[1, 2, 3].map(num => <option>{num}</option>)}</select><div>Hello world!</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"textarea\",\n\t\t\tsource: `---\nconst value = 'test';\n---\n<textarea>{value}</textarea>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"textarea inside expression\",\n\t\t\tsource: `{bool && <textarea>{value}</textarea>} {!bool && <input>}`,\n\t\t},\n\t\t{\n\t\t\tname: \"table simple case\",\n\t\t\tsource: `---\nconst content = \"lol\";\n---\n\n<html>\n  <body>\n    <table>\n      <tr>\n        <td>{content}</td>\n      </tr>\n      {\n        (\n          <tr>\n            <td>1</td>\n          </tr>\n        )\n      }\n    </table>Hello\n  </body>\n</html>\n`,\n\t\t},\n\t\t{\n\t\t\tname: \"complex table\",\n\t\t\tsource: `<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\" />\n        <meta name=\"viewport\" content=\"width=device-width\" />\n        <title>Astro Multi Table</title>\n    </head>\n    <body>\n        <main>\n            <section>\n                {Array(3).fill(false).map((item, idx) => <div>\n                    <div class=\"row\">\n                        {'a'}\n                        <table>\n                            <thead>\n                                <tr>\n                                    <>{Array(7).fill(false).map((entry, index) => <th>A</th>)}</>\n                                </tr>\n                            </thead>\n                            <tbody>\n                                <tr><td></td></tr>\n                            </tbody>\n                        </table>\n                    </div>\n                </div>)}\n            </section>\n            <section>\n                <div class=\"row\">\n                    <table>\n                        <thead>\n                            <tr>\n                                <th>B</th>\n                                <th>B</th>\n                                <th>B</th>\n                            </tr>\n                        </thead>\n                        <tbody>\n                            <tr><td></td></tr>\n                        </tbody>\n                    </table>\n                </div>\n            </section>\n        </main>\n    </body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"table with expression in 'th'\",\n\t\t\tsource: `---\nconst { title, footnotes, tables } = Astro.props;\n\ninterface Table {\n\ttitle: string;\n\tdata: any[];\n\tshowTitle: boolean;\n\tfootnotes: string;\n}\nconsole.log(tables);\n---\n\n<div>\n\t<div>\n\t<h2>\n\t\t{title}\n\t</h2>\n\t{\n\t\ttables.map((table: Table) => (\n\t\t<>\n\t\t\t<div>\n\t\t\t<h3 class=\"text-3xl sm:text-5xl font-bold\">{table.title}</h3>\n\t\t\t<table>\n\t\t\t\t<thead>\n\t\t\t\t{Object.keys(table.data[0]).map((thead) => (\n\t\t\t\t\t<th>{thead}</th>\n\t\t\t\t))}\n\t\t\t\t</thead>\n\t\t\t\t<tbody>\n\t\t\t\t{table.data.map((trow) => (\n\t\t\t\t\t<tr>\n\t\t\t\t\t{Object.values(trow).map((cell, index) => (\n\t\t\t\t\t\t<td>\n\t\t\t\t\t\t{cell}\n\t\t\t\t\t\t</td>\n\t\t\t\t\t))}\n\t\t\t\t\t</tr>\n\t\t\t\t))}\n\t\t\t\t</tbody>\n\t\t\t</table>\n\t\t\t</div>\n\t\t</>\n\t\t))\n\t}\n\t</div>\n</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"table expressions (no implicit tbody)\",\n\t\t\tsource: `---\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n---\n<table>{items.map(item => (<tr><td>{item}</td></tr>))}</table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"table caption expression\",\n\t\t\tsource: `<table><caption>{title}</caption><tr><td>Hello</td></tr></table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"table expression with trailing div\",\n\t\t\tsource: `<table><tr><td>{title}</td></tr></table><div>Div</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"tbody expressions\",\n\t\t\tsource: `---\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n---\n<table><tr><td>Name</td></tr>{items.map(item => (<tr><td>{item}</td></tr>))}</table>`,\n\t\t},\n\t\t{\n\t\t\tname: \"tbody expressions 2\",\n\t\t\tsource: `---\nconst items = [\"Dog\", \"Cat\", \"Platipus\"];\n---\n<table><tr><td>Name</td></tr>{items.map(item => (<tr><td>{item}</td><td>{item + 's'}</td></tr>))}</table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"tbody expressions 3\",\n\t\t\tsource: `<table><tbody>{rows.map(row => (<tr><td><strong>{row}</strong></td></tr>))}</tbody></table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"td expressions\",\n\t\t\tsource: `<table><tr><td><h2>Row 1</h2></td><td>{title}</td></tr></table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"td expressions II\",\n\t\t\tsource: `<table>{data.map(row => <tr>{row.map(cell => <td>{cell}</td>)}</tr>)}</table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"self-closing td\",\n\t\t\tsource: `<table>{data.map(row => <tr>{row.map(cell => <td set:html={cell} />)}</tr>)}</table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"th expressions\",\n\t\t\tsource: `<table><thead><tr><th>{title}</th></tr></thead></table>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"tr only\",\n\t\t\tsource: `<tr><td>col 1</td><td>col 2</td><td>{foo}</td></tr>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"caption only\",\n\t\t\tsource: `<caption>Hello world!</caption>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"anchor expressions\",\n\t\t\tsource: `<a>{expr}</a>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"anchor inside expression\",\n\t\t\tsource: `{true && <a>expr</a>}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"anchor content\",\n\t\t\tsource: `<a><div><h3></h3><ul><li>{expr}</li></ul></div></a>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"small expression\",\n\t\t\tsource: `<div><small>{a}</small>{data.map(a => <Component value={a} />)}</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"division inside expression\",\n\t\t\tsource: `<div>{16 / 4}</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"escaped entity\",\n\t\t\tsource: `<img alt=\"A person saying &#x22;hello&#x22;\">`,\n\t\t},\n\t\t{\n\t\t\tname:   \"textarea in form\",\n\t\t\tsource: `<html><Component><form><textarea></textarea></form></Component></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"select in form\",\n\t\t\tsource: `<form><select>{options.map((option) => (<option value={option.id}>{option.title}</option>))}</select><div><label>Title 3</label><input type=\"text\" /></div><button type=\"submit\">Submit</button></form>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"selectedcontent element in customizable select\",\n\t\t\tsource: `<select><button><selectedcontent></selectedcontent></button><option>Option 1</option><option>Option 2</option></select>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"selectedcontent self-closing element\",\n\t\t\tsource: `<select><button><selectedcontent /></button><option>Option 1</option><option>Option 2</option></select>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Expression in form followed by other sibling forms\",\n\t\t\tsource: \"<form><p>No expression here. So the next form will render.</p></form><form><h3>{data.formLabelA}</h3></form><form><h3>{data.formLabelB}</h3></form><form><p>No expression here, but the last form before me had an expression, so my form didn't render.</p></form><form><h3>{data.formLabelC}</h3></form><div><p>Here is some in-between content</p></div><form><h3>{data.formLabelD}</h3></form>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"slot inside of Base\",\n\t\t\tsource: `<Base title=\"Home\"><div>Hello</div></Base>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"user-defined `implicit` is printed\",\n\t\t\tsource: `<html implicit></html>`,\n\t\t},\n\t\t{\n\t\t\tname: \"css comment doesn’t produce semicolon\",\n\t\t\tsource: `<style>/* comment */.container {\n    padding: 2rem;\n\t}\n</style><div class=\"container\">My Text</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"sibling expressions\",\n\t\t\tsource: `<html><body>\n  <table>\n  {true ? (<tr><td>Row 1</td></tr>) : null}\n  {true ? (<tr><td>Row 2</td></tr>) : null}\n  {true ? (<tr><td>Row 3</td></tr>) : null}\n  </table>\n</body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"table\",\n\t\t\tsource: \"<table><tr>{[0,1,2].map(x => (<td>{x}</td>))}</tr></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table II\",\n\t\t\tsource: \"<table><thead><tr>{['Hey','Ho'].map((item)=> <th scope=\\\"col\\\">{item}</th>)}</tr></thead></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table III\",\n\t\t\tsource: \"<table><tbody><tr><td>Cell</td><Cell /><Cell /><Cell /></tr></tbody></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table IV\",\n\t\t\tsource: \"<body><div><tr><td>hello world</td></tr></div></body>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table slot I\",\n\t\t\tsource: \"<table><slot /></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table slot II\",\n\t\t\tsource: \"<table><tr><slot /></tr></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table slot III\",\n\t\t\tsource: \"<table><td><slot /></td></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table slot IV\",\n\t\t\tsource: \"<table><thead><slot /></thead></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"table slot V\",\n\t\t\tsource: \"<table><tbody><slot /></tbody></table>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"XElement\",\n\t\t\tsource: `<XElement {...attrs}></XElement>{onLoadString ? <script data-something></script> : null }`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Empty expression\",\n\t\t\tsource: \"<body>({})</body>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"Empty expression with whitespace\",\n\t\t\tsource: \"<body>({   })</body>\",\n\t\t},\n\t\t{\n\t\t\tname: \"expression with leading whitespace\",\n\t\t\tsource: `<section>\n<ul class=\"font-mono text-sm flex flex-col gap-0.5\">\n\t{\n\t\t<li>Build: { new Date().toISOString() }</li>\n\t\t<li>NODE_VERSION: { process.env.NODE_VERSION }</li>\n\t}\n</ul>\n</section>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Empty attribute expression\",\n\t\t\tsource: \"<body attr={}></body>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"is:raw\",\n\t\t\tsource: \"<article is:raw><% awesome %></article>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"Component is:raw\",\n\t\t\tsource: \"<Component is:raw>{<% awesome %>}</Component>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html\",\n\t\t\tsource: \"<article set:html={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html with quoted attribute\",\n\t\t\tsource: `<article set:html=\"content\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html with template literal attribute without variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `content` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html with template literal attribute with variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text\",\n\t\t\tsource: \"<article set:text={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text with quoted attribute\",\n\t\t\tsource: `<article set:text=\"content\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text with template literal attribute without variable\",\n\t\t\tsource: `<article set:text=` + BACKTICK + `content` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text with template literal attribute with variable\",\n\t\t\tsource: `<article set:text=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Component\",\n\t\t\tsource: `<Component set:html={content} />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Component with quoted attribute\",\n\t\t\tsource: `<Component set:html=\"content\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Component with template literal attribute without variable\",\n\t\t\tsource: `<Component set:html=` + BACKTICK + `content` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Component with template literal attribute with variable\",\n\t\t\tsource: `<Component set:html=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on Component\",\n\t\t\tsource: \"<Component set:text={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on Component with quoted attribute\",\n\t\t\tsource: `<Component set:text=\"content\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on Component with template literal attribute without variable\",\n\t\t\tsource: `<Component set:text=` + BACKTICK + `content` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on Component with template literal attribute with variable\",\n\t\t\tsource: `<Component set:text=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on custom-element\",\n\t\t\tsource: \"<custom-element set:html={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on custom-element with quoted attribute\",\n\t\t\tsource: `<custom-element set:html=\"content\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on custom-element with template literal attribute without variable\",\n\t\t\tsource: `<custom-element set:html=` + BACKTICK + `content` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on custom-element with template literal attribute with variable\",\n\t\t\tsource: `<custom-element set:html=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on custom-element\",\n\t\t\tsource: \"<custom-element set:text={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on custom-element with quoted attribute\",\n\t\t\tsource: `<custom-element set:text=\"content\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on custom-element with template literal attribute without variable\",\n\t\t\tsource: `<custom-element set:text=` + BACKTICK + `content` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:text on custom-element with template literal attribute with variable\",\n\t\t\tsource: `<custom-element set:text=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on self-closing tag\",\n\t\t\tsource: \"<article set:html={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on self-closing tag with quoted attribute\",\n\t\t\tsource: `<article set:html=\"content\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on self-closing tag with template literal attribute without variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `content` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on self-closing tag with template literal attribute with variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html with other attributes\",\n\t\t\tsource: \"<article set:html={content} cool=\\\"true\\\" />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html with quoted attribute and other attributes\",\n\t\t\tsource: `<article set:html=\"content\" cool=\"true\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html with template literal attribute without variable and other attributes\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `content` + BACKTICK + ` cool=\"true\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html with template literal attribute with variable and other attributes\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `${content}` + BACKTICK + ` cool=\"true\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on empty tag\",\n\t\t\tsource: \"<article set:html={content}></article>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on empty tag with quoted attribute\",\n\t\t\tsource: `<article set:html=\"content\"></article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on empty tag with template literal attribute without variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `content` + BACKTICK + `></article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on empty tag with template literal attribute with variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `${content}` + BACKTICK + `></article>`,\n\t\t},\n\t\t{\n\t\t\t// If both \"set:*\" directives are passed, we only respect the first one\n\t\t\tname:   \"set:html and set:text\",\n\t\t\tsource: \"<article set:html={content} set:text={content} />\",\n\t\t},\n\t\t//\n\t\t{\n\t\t\tname:   \"set:html on tag with children\",\n\t\t\tsource: \"<article set:html={content}>!!!</article>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on tag with children and quoted attribute\",\n\t\t\tsource: `<article set:html=\"content\">!!!</article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on tag with children and template literal attribute without variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `content` + BACKTICK + `>!!!</article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on tag with children and template literal attribute with variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `${content}` + BACKTICK + `>!!!</article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on tag with empty whitespace\",\n\t\t\tsource: \"<article set:html={content}>   </article>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on tag with empty whitespace and quoted attribute\",\n\t\t\tsource: `<article set:html=\"content\">   </article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on tag with empty whitespace and template literal attribute without variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `content` + BACKTICK + `>   </article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on tag with empty whitespace and template literal attribute with variable\",\n\t\t\tsource: `<article set:html=` + BACKTICK + `${content}` + BACKTICK + `>   </article>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on script\",\n\t\t\tsource: \"<script set:html={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on script with quoted attribute\",\n\t\t\tsource: `<script set:html=\"alert(1)\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on script with template literal attribute without variable\",\n\t\t\tsource: `<script set:html=` + BACKTICK + `alert(1)` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on script with template literal attribute with variable\",\n\t\t\tsource: `<script set:html=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on style\",\n\t\t\tsource: \"<style set:html={content} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on style with quoted attribute\",\n\t\t\tsource: `<style set:html=\"h1{color:green;}\" />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on style with template literal attribute without variable\",\n\t\t\tsource: `<style set:html=` + BACKTICK + `h1{color:green;}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on style with template literal attribute with variable\",\n\t\t\tsource: `<style set:html=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Fragment\",\n\t\t\tsource: \"<Fragment set:html={\\\"<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>\\\"} />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Fragment with quoted attribute\",\n\t\t\tsource: \"<Fragment set:html=\\\"<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>\\\" />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Fragment with template literal attribute without variable\",\n\t\t\tsource: \"<Fragment set:html=`<p>&#x3C;i>This should NOT be italic&#x3C;/i></p>` />\",\n\t\t},\n\t\t{\n\t\t\tname:   \"set:html on Fragment with template literal attribute with variable\",\n\t\t\tsource: `<Fragment set:html=` + BACKTICK + `${content}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"template literal attribute on component\",\n\t\t\tsource: `<Component class=` + BACKTICK + `red` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"template literal attribute with variable on component\",\n\t\t\tsource: `<Component class=` + BACKTICK + `${color}` + BACKTICK + ` />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"define:vars on style\",\n\t\t\tsource: \"<style>h1{color:green;}</style><style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1>testing</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"define:vars on style tag with style shorthand attribute on element\",\n\t\t\tsource: \"<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 {style}>testing</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"define:vars on style tag with style expression attribute on element\",\n\t\t\tsource: \"<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style={myStyles}>testing</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"define:vars on style tag with style empty attribute on element\",\n\t\t\tsource: \"<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style>testing</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"define:vars on style tag with style quoted attribute on element\",\n\t\t\tsource: \"<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style='color: yellow;'>testing</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"define:vars on style tag with style template literal attribute on element\",\n\t\t\tsource: \"<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><h1 style=`color: ${color};`>testing</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"multiple define:vars on style\",\n\t\t\tsource: \"<style define:vars={{color:'green'}}>h1{color:var(--color)}</style><style define:vars={{color:'red'}}>h2{color:var(--color)}</style><h1>foo</h1><h2>bar</h2>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"define:vars on non-root elements\",\n\t\t\tsource: \"<style define:vars={{color:'green'}}>h1{color:var(--color)}</style>{true ? <h1>foo</h1> : <h1>bar</h1>}\",\n\t\t},\n\t\t{\n\t\t\tname: \"define:vars on script with StaticExpression turned on\",\n\t\t\t// 1. An inline script with is:inline - right\n\t\t\t// 2. A hoisted script - wrong, shown up in scripts.add\n\t\t\t// 3. A define:vars hoisted script\n\t\t\t// 4. A define:vars inline script\n\t\t\tsource: `<script is:inline>var one = 'one';</script><script>var two = 'two';</script><script define:vars={{foo:'bar'}}>var three = foo;</script><script is:inline define:vars={{foo:'bar'}}>var four = foo;</script>`,\n\t\t},\n\t\t{\n\t\t\tname: \"define:vars on a module script with imports\",\n\t\t\t// Should not wrap with { } scope.\n\t\t\tsource: `<script type=\"module\" define:vars={{foo:'bar'}}>import 'foo';\\nvar three = foo;</script>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"comments removed from attribute list\",\n\t\t\tsource: `<div><h1 {/* comment 1 */} value=\"1\" {/* comment 2 */}>Hello</h1><Component {/* comment 1 */} value=\"1\" {/* comment 2 */} /></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"includes comments for shorthand attribute\",\n\t\t\tsource: `<div><h1 {/* comment 1 */ id /* comment 2 */}>Hello</h1><Component {/* comment 1 */ id /* comment 2 */}/></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"includes comments for expression attribute\",\n\t\t\tsource: `<div><h1 attr={/* comment 1 */ isTrue ? 1 : 2 /* comment 2 */}>Hello</h1><Component attr={/* comment 1 */ isTrue ? 1 : 2 /* comment 2 */}/></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"comment only expressions are removed I\",\n\t\t\tsource: `{/* a comment 1 */}<h1>{/* a comment 2*/}Hello</h1>`,\n\t\t},\n\t\t{\n\t\t\tname: \"comment only expressions are removed II\",\n\t\t\tsource: `{\n    list.map((i) => (\n        <Component>\n            {\n                // hello\n            }\n        </Component>\n    ))\n}`,\n\t\t},\n\t\t{\n\t\t\tname: \"comment only expressions are removed III\",\n\t\t\tsource: `{\n    list.map((i) => (\n        <Component>\n            {\n                /* hello */\n            }\n        </Component>\n    ))\n}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"component with only a script\",\n\t\t\tsource: \"<script>console.log('hello world');</script>\",\n\t\t},\n\t\t{\n\t\t\tname:     \"passes filename into createComponent if passed into the compiler options\",\n\t\t\tsource:   `<div>test</div>`,\n\t\t\tfilename: \"/projects/app/src/pages/page.astro\",\n\t\t},\n\t\t{\n\t\t\tname:     \"passes escaped filename into createComponent if it contains single quotes\",\n\t\t\tsource:   `<div>test</div>`,\n\t\t\tfilename: \"/projects/app/src/pages/page-with-'-quotes.astro\",\n\t\t},\n\t\t{\n\t\t\tname:     \"maybeRenderHead not printed for hoisted scripts\",\n\t\t\tsource:   `<script></script><Layout></Layout>`,\n\t\t\tfilename: \"/projects/app/src/pages/page.astro\",\n\t\t},\n\t\t{\n\t\t\tname:     \"complex recursive component\",\n\t\t\tsource:   `{(<Fragment><Fragment set:html={` + BACKTICK + `<${Node.tag} ${stringifyAttributes(Node.attributes)}>` + BACKTICK + `} />{Node.children.map((child) => (<Astro.self node={child} />))}<Fragment set:html={` + BACKTICK + `</${Node.tag}>` + BACKTICK + `} /></Fragment>)}`,\n\t\t\tfilename: \"/projects/app/src/components/RenderNode.astro\",\n\t\t},\n\t\t{\n\t\t\tname:   \"multibyte character + style\",\n\t\t\tsource: `<style>a { font-size: 16px; }</style><a class=\"test\">ツ</a>`,\n\t\t},\n\t\t{\n\t\t\tname: \"multibyte characters\",\n\t\t\tsource: `---\n---\n<h1>こんにちは</h1>`,\n\t\t},\n\n\t\t{\n\t\t\tname:   \"multibyte character + script\",\n\t\t\tsource: `<script>console.log('foo')</script><a class=\"test\">ツ</a>`,\n\t\t},\n\n\t\t{\n\t\t\tname:        \"transition:name with an expression\",\n\t\t\tsource:      `<div transition:name={one + '-' + 'two'}></div>`,\n\t\t\tfilename:    \"/projects/app/src/pages/page.astro\",\n\t\t\ttransitions: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"transition:name with an template literal\",\n\t\t\tsource:      \"<div transition:name=`${one}-two`></div>\",\n\t\t\tfilename:    \"/projects/app/src/pages/page.astro\",\n\t\t\ttransitions: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"transition:animate with an expression\",\n\t\t\tsource:      \"<div transition:animate={slide({duration:15})}></div>\",\n\t\t\tfilename:    \"/projects/app/src/pages/page.astro\",\n\t\t\ttransitions: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"transition:animate on Component\",\n\t\t\tsource:      `<Component class=\"bar\" transition:animate=\"morph\"></Component>`,\n\t\t\tfilename:    \"/projects/app/src/pages/page.astro\",\n\t\t\ttransitions: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"transition:persist converted to a data attribute\",\n\t\t\tsource:      `<div transition:persist></div>`,\n\t\t\ttransitions: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"transition:persist uses transition:name if defined\",\n\t\t\tsource:      `<div transition:persist transition:name=\"foo\"></div>`,\n\t\t\ttransitions: true,\n\t\t},\n\t\t{\n\t\t\tname:        \"transition:persist-props converted to a data attribute\",\n\t\t\tsource:      `<my-island transition:persist transition:persist-props=\"false\"></my-island>`,\n\t\t\ttransitions: true,\n\t\t},\n\t\t{\n\t\t\tname:   \"trailing expression\",\n\t\t\tsource: `<Component />{}`,\n\t\t},\n\t\t{\n\t\t\tname: \"nested head content stays in the head\",\n\t\t\tsource: `---\nconst meta = { title: 'My App' };\n---\n\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\n\t\t{\n\t\t\tmeta && <title>{meta.title}</title>\n\t\t}\n\n\t\t<meta name=\"after\">\n\t</head>\n\t<body>\n\t\t<h1>My App</h1>\n\t</body>\n</html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"namespace is preserved when inside an expression\",\n\t\t\tsource: `<svg>{<image />}</svg>`,\n\t\t},\n\t\t{\n\t\t\tname: \"head content with component first\",\n\t\t\tsource: `---\nimport Analytics from '../components/Analytics.astro';\n---\n<Analytics />\n<title>{title}</title>\n<meta name=\"description\" content=\"a description\" />`,\n\t\t},\n\t\t{\n\t\t\tname: \"jsx comment between doctype and html\",\n\t\t\tsource: `<!doctype html>\n{/* Comment */}\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t</head>\n</html>`,\n    },\n    {\n\t\t\tname:   \"multiline class attribute on component\",\n\t\t\tsource: \"<Component class=\\\"some-class\\n  another-class\\n  third-class\\\">content</Component>\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tif tt.only {\n\t\t\ttests = make([]testcase, 0)\n\t\t\ttests = append(tests, tt)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// transform output from source\n\t\t\tcode := test_utils.Dedent(tt.source)\n\n\t\t\tdoc, err := astro.Parse(strings.NewReader(code))\n\t\t\th := handler.NewHandler(code, \"<stdin>\")\n\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\n\t\t\thash := astro.HashString(code)\n\t\t\ttransformOptions := transform.TransformOptions{\n\t\t\t\tScope:                   hash,\n\t\t\t}\n\t\t\ttransform.ExtractStyles(doc, &transformOptions)\n\t\t\ttransform.Transform(doc, transformOptions, h) // note: we want to test Transform in context here, but more advanced cases could be tested separately\n\n\t\t\tresult := PrintToJS(code, doc, 0, transform.TransformOptions{\n\t\t\t\tScope:                   \"XXXX\",\n\t\t\t\tInternalURL:             \"http://localhost:3000/\",\n\t\t\t\tFilename:                tt.filename,\n\t\t\t\tAstroGlobalArgs:         \"'https://astro.build'\",\n\t\t\t\tTransitionsAnimationURL: \"transitions.css\",\n\t\t\t}, h)\n\t\t\toutput := string(result.Output)\n\n\t\t\ttest_utils.MakeSnapshot(\n\t\t\t\t&test_utils.SnapshotOptions{\n\t\t\t\t\tTesting:      t,\n\t\t\t\t\tTestCaseName: tt.name,\n\t\t\t\t\tInput:        code,\n\t\t\t\t\tOutput:       output,\n\t\t\t\t\tKind:         test_utils.JsOutput,\n\t\t\t\t\tFolderName:   \"__printer_js__\",\n\t\t\t\t})\n\t\t})\n\t}\n}\n\nfunc TestPrintToJSON(t *testing.T) {\n\ttests := []jsonTestcase{\n\t\t{\n\t\t\tname:   \"basic\",\n\t\t\tsource: `<h1>Hello world!</h1>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"expression\",\n\t\t\tsource: `<h1>Hello {world}</h1>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Component\",\n\t\t\tsource: `<Component />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"custom-element\",\n\t\t\tsource: `<custom-element />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Doctype\",\n\t\t\tsource: `<!DOCTYPE html />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Comment\",\n\t\t\tsource: `<!--hello-->`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Comment preserves whitespace\",\n\t\t\tsource: `<!-- hello -->`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment Shorthand\",\n\t\t\tsource: `<>Hello</>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Fragment Literal\",\n\t\t\tsource: `<Fragment>World</Fragment>`,\n\t\t},\n\t\t{\n\t\t\tname: \"Frontmatter\",\n\t\t\tsource: `---\nconst a = \"hey\"\n---\n<div>{a}</div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"JSON escape\",\n\t\t\tsource: `---\nconst a = \"\\n\"\nconst b = \"\\\"\"\nconst c = '\\''\n---\n{a + b + c}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Preserve namespaces\",\n\t\t\tsource: `<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><rect xlink:href=\"#id\"></svg>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style before html\",\n\t\t\tsource: `<style></style><html><body><h1>Hello world!</h1></body></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style after html\",\n\t\t\tsource: `<html><body><h1>Hello world!</h1></body></html><style></style>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style after empty html\",\n\t\t\tsource: `<html></html><style></style>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style after html with component in head\",\n\t\t\tsource: `<html lang=\"en\"><head><BaseHead /></head></html><style>@use \"../styles/global.scss\";</style>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style after html with component in head and body\",\n\t\t\tsource: `<html lang=\"en\"><head><BaseHead /></head><body><Header /></body></html><style>@use \"../styles/global.scss\";</style>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style after body with component in head and body\",\n\t\t\tsource: `<html lang=\"en\"><head><BaseHead /></head><body><Header /></body><style>@use \"../styles/global.scss\";</style></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style in html\",\n\t\t\tsource: `<html><body><h1>Hello world!</h1></body><style></style></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"style in body\",\n\t\t\tsource: `<html><body><h1>Hello world!</h1><style></style></body></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"element with unterminated double quote attribute\",\n\t\t\tsource: `<main id=\"gotcha />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"element with unterminated single quote attribute\",\n\t\t\tsource: `<main id='gotcha />`,\n\t\t},\n\t\t{\n\t\t\tname:   \"element with unterminated template literal attribute\",\n\t\t\tsource: `<main id=` + BACKTICK + `gotcha />`,\n\t\t},\n\t\t{\n\t\t\tname: \"jsx comment between doctype and html\",\n\t\t\tsource: `<!doctype html>\n{/* Comment */}\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t</head>\n</html>`,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tif tt.only {\n\t\t\ttests = make([]jsonTestcase, 0)\n\t\t\ttests = append(tests, tt)\n\t\t\tbreak\n\t\t}\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// transform output from source\n\t\t\tcode := test_utils.Dedent(tt.source)\n\n\t\t\tdoc, err := astro.ParseWithOptions(strings.NewReader(code), astro.ParseOptionEnableLiteral(true), astro.ParseOptionWithHandler(&handler.Handler{}))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\n\t\t\tresult := PrintToJSON(code, doc, types.ParseOptions{Position: false})\n\n\t\t\ttest_utils.MakeSnapshot(\n\t\t\t\t&test_utils.SnapshotOptions{\n\t\t\t\t\tTesting:      t,\n\t\t\t\t\tTestCaseName: tt.name,\n\t\t\t\t\tInput:        code,\n\t\t\t\t\tOutput:       string(result.Output),\n\t\t\t\t\tKind:         test_utils.JsonOutput,\n\t\t\t\t\tFolderName:   \"__printer_json__\",\n\t\t\t\t})\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/printer/utils.go",
    "content": "package printer\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\n\t\"github.com/iancoleman/strcase\"\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/js_scanner\"\n\t\"github.com/withastro/compiler/internal/transform\"\n)\n\nfunc escapeText(src string) string {\n\treturn escapeBackticks(\n\t\tescapeInterpolation(\n\t\t\tescapeExistingEscapes(src),\n\t\t),\n\t)\n}\n\nfunc escapeBraces(src string) string {\n\treturn escapeStarSlash(escapeTSXExpressions(\n\t\tescapeExistingEscapes(src),\n\t))\n}\n\nfunc escapeStarSlash(src string) string {\n\treturn strings.ReplaceAll(src, \"*/\", \"*\\\\/\")\n}\n\nfunc getTSXComponentName(filename string) string {\n\tif filename == \"<stdin>\" {\n\t\treturn \"__AstroComponent_\"\n\t}\n\tif len(filename) == 0 {\n\t\treturn \"__AstroComponent_\"\n\t}\n\tparts := strings.Split(filename, \"/\")\n\tpart := parts[len(parts)-1]\n\tif len(part) == 0 {\n\t\treturn \"__AstroComponent_\"\n\t}\n\tbasename := strcase.ToCamel(strings.Split(part, \".\")[0])\n\tif js_scanner.IsIdentifier([]byte(basename)) {\n\t\treturn fmt.Sprintf(\"%s%s\", basename, \"__AstroComponent_\")\n\t} else {\n\t\treturn \"__AstroComponent_\"\n\t}\n}\n\nfunc getComponentName(filename string) string {\n\tif len(filename) == 0 {\n\t\treturn \"$$Component\"\n\t}\n\tparts := strings.Split(filename, \"/\")\n\tpart := parts[len(parts)-1]\n\tif len(part) == 0 {\n\t\treturn \"$$Component\"\n\t}\n\tbasename := strcase.ToCamel(strings.Split(part, \".\")[0])\n\tif basename == \"Astro\" {\n\t\treturn \"$$Component\"\n\t}\n\treturn strings.Join([]string{\"$$\", basename}, \"\")\n}\n\nfunc escapeExistingEscapes(src string) string {\n\treturn strings.Replace(src, \"\\\\\", \"\\\\\\\\\", -1)\n}\n\nfunc escapeTSXExpressions(src string) string {\n\topen := regexp.MustCompile(`{`)\n\tclose := regexp.MustCompile(`}`)\n\treturn close.ReplaceAllString(open.ReplaceAllString(src, `\\\\{`), `\\\\}`)\n}\n\nfunc escapeInterpolation(src string) string {\n\tinterpolation := regexp.MustCompile(`\\${`)\n\treturn interpolation.ReplaceAllString(src, \"\\\\${\")\n}\n\n// Escape backtick characters for Text nodes\nfunc escapeBackticks(src string) string {\n\tbackticks := regexp.MustCompile(\"`\")\n\treturn backticks.ReplaceAllString(src, \"\\\\`\")\n}\n\nfunc escapeSingleQuote(str string) string {\n\treturn strings.Replace(str, \"'\", \"\\\\'\", -1)\n}\n\nfunc escapeDoubleQuote(str string) string {\n\treturn strings.Replace(str, `\"`, \"\\\\\\\"\", -1)\n}\n\nfunc escapeNewlines(str string) string {\n\tstr = strings.Replace(str, \"\\n\", `\\n`, -1)\n\tstr = strings.Replace(str, \"\\r\", `\\r`, -1)\n\treturn str\n}\n\nfunc encodeDoubleQuote(str string) string {\n\treturn strings.Replace(str, `\"`, \"&quot;\", -1)\n}\n\nfunc convertAttributeValue(n *astro.Node, attrName string) string {\n\texpr := `\"\"`\n\tif transform.HasAttr(n, attrName) {\n\t\tattr := transform.GetAttr(n, attrName)\n\t\tswitch attr.Type {\n\t\tcase astro.QuotedAttribute:\n\t\t\texpr = fmt.Sprintf(`\"%s\"`, attr.Val)\n\t\tcase astro.ExpressionAttribute:\n\t\t\texpr = fmt.Sprintf(`(%s)`, attr.Val)\n\t\tcase astro.TemplateLiteralAttribute:\n\t\t\texpr = fmt.Sprintf(\"`%s`\", attr.Val)\n\t\t}\n\t}\n\treturn expr\n}\n"
  },
  {
    "path": "internal/sourcemap/sourcemap.go",
    "content": "package sourcemap\n\nimport (\n\t\"bytes\"\n\t\"unicode/utf8\"\n\n\t\"github.com/withastro/compiler/internal/helpers\"\n\t\"github.com/withastro/compiler/internal/loc\"\n)\n\ntype Mapping struct {\n\tGeneratedLine   int // 0-based\n\tGeneratedColumn int // 0-based count of UTF-16 code units\n\n\tSourceIndex    int // 0-based\n\tOriginalLine   int // 0-based\n\tOriginalColumn int // 0-based count of UTF-16 code units\n}\n\ntype SourceMap struct {\n\tSources        []string\n\tSourcesContent []SourceContent\n\tMappings       []Mapping\n}\n\ntype SourceContent struct {\n\t// This stores both the unquoted and the quoted values. We try to use the\n\t// already-quoted value if possible so we don't need to re-quote it\n\t// unnecessarily for maximum performance.\n\tQuoted string\n\n\t// But sometimes we need to re-quote the value, such as when it contains\n\t// non-ASCII characters and we are in ASCII-only mode. In that case we quote\n\t// this parsed UTF-16 value.\n\tValue []uint16\n}\n\nfunc (sm *SourceMap) Find(line int, column int) *Mapping {\n\tmappings := sm.Mappings\n\n\t// Binary search\n\tcount := len(mappings)\n\tindex := 0\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := index + step\n\t\tmapping := mappings[i]\n\t\tif mapping.GeneratedLine < line || (mapping.GeneratedLine == line && mapping.GeneratedColumn <= column) {\n\t\t\tindex = i + 1\n\t\t\tcount -= step + 1\n\t\t} else {\n\t\t\tcount = step\n\t\t}\n\t}\n\n\t// Handle search failure\n\tif index > 0 {\n\t\tmapping := &mappings[index-1]\n\n\t\t// Match the behavior of the popular \"source-map\" library from Mozilla\n\t\tif mapping.GeneratedLine == line {\n\t\t\treturn mapping\n\t\t}\n\t}\n\treturn nil\n}\n\nvar base64 = []byte(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\")\n\n// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n// length quantities we use in the source map spec, the first bit is the sign,\n// the next four bits are the actual value, and the 6th bit is the continuation\n// bit. The continuation bit tells us whether there are more digits in this\n// value following this digit.\n//\n//\tContinuation\n//\t|    Sign\n//\t|    |\n//\tV    V\n//\t101011\nfunc EncodeVLQ(value int) []byte {\n\tvar vlq int\n\tif value < 0 {\n\t\tvlq = ((-value) << 1) | 1\n\t} else {\n\t\tvlq = value << 1\n\t}\n\n\t// Handle the common case up front without allocations\n\tif (vlq >> 5) == 0 {\n\t\tdigit := vlq & 31\n\t\treturn base64[digit : digit+1]\n\t}\n\n\tencoded := []byte{}\n\tfor {\n\t\tdigit := vlq & 31\n\t\tvlq >>= 5\n\n\t\t// If there are still more digits in this value, we must make sure the\n\t\t// continuation bit is marked\n\t\tif vlq != 0 {\n\t\t\tdigit |= 32\n\t\t}\n\n\t\tencoded = append(encoded, base64[digit])\n\n\t\tif vlq == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn encoded\n}\n\nfunc DecodeVLQ(encoded []byte, start int) (int, int) {\n\tshift := 0\n\tvlq := 0\n\n\t// Scan over the input\n\tfor {\n\t\tindex := bytes.IndexByte(base64, encoded[start])\n\t\tif index < 0 {\n\t\t\tbreak\n\t\t}\n\n\t\t// Decode a single byte\n\t\tvlq |= (index & 31) << shift\n\t\tstart++\n\t\tshift += 5\n\n\t\t// Stop if there's no continuation bit\n\t\tif (index & 32) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Recover the value\n\tvalue := vlq >> 1\n\tif (vlq & 1) != 0 {\n\t\tvalue = -value\n\t}\n\treturn value, start\n}\n\nfunc DecodeVLQUTF16(encoded []uint16) (int, int, bool) {\n\tn := len(encoded)\n\tif n == 0 {\n\t\treturn 0, 0, false\n\t}\n\n\t// Scan over the input\n\tcurrent := 0\n\tshift := 0\n\tvlq := 0\n\tfor {\n\t\tif current >= n {\n\t\t\treturn 0, 0, false\n\t\t}\n\t\tindex := bytes.IndexByte(base64, byte(encoded[current]))\n\t\tif index < 0 {\n\t\t\treturn 0, 0, false\n\t\t}\n\n\t\t// Decode a single byte\n\t\tvlq |= (index & 31) << shift\n\t\tcurrent++\n\t\tshift += 5\n\n\t\t// Stop if there's no continuation bit\n\t\tif (index & 32) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Recover the value\n\tvar value = vlq >> 1\n\tif (vlq & 1) != 0 {\n\t\tvalue = -value\n\t}\n\treturn value, current, true\n}\n\ntype LineColumnOffset struct {\n\tLines   int\n\tColumns int\n}\n\nfunc (a LineColumnOffset) ComesBefore(b LineColumnOffset) bool {\n\treturn a.Lines < b.Lines || (a.Lines == b.Lines && a.Columns < b.Columns)\n}\n\nfunc (a *LineColumnOffset) Add(b LineColumnOffset) {\n\tif b.Lines == 0 {\n\t\ta.Columns += b.Columns\n\t} else {\n\t\ta.Lines += b.Lines\n\t\ta.Columns = b.Columns\n\t}\n}\n\nfunc (offset *LineColumnOffset) AdvanceBytes(bytes []byte) {\n\tcolumns := offset.Columns\n\tfor len(bytes) > 0 {\n\t\tc, width := utf8.DecodeRune(bytes)\n\t\tbytes = bytes[width:]\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && len(bytes) > 0 && bytes[0] == '\\n' {\n\t\t\t\tcolumns++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\toffset.Lines++\n\t\t\tcolumns = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumns++\n\t\t\t} else {\n\t\t\t\tcolumns += 2\n\t\t\t}\n\t\t}\n\t}\n\toffset.Columns = columns\n}\n\nfunc (offset *LineColumnOffset) AdvanceString(text string) {\n\tcolumns := offset.Columns\n\tfor i, c := range text {\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && i+1 < len(text) && text[i+1] == '\\n' {\n\t\t\t\tcolumns++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\toffset.Lines++\n\t\t\tcolumns = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumns++\n\t\t\t} else {\n\t\t\t\tcolumns += 2\n\t\t\t}\n\t\t}\n\t}\n\toffset.Columns = columns\n}\n\ntype SourceMapPieces struct {\n\tPrefix   []byte\n\tMappings []byte\n\tSuffix   []byte\n}\n\nfunc (pieces SourceMapPieces) HasContent() bool {\n\treturn len(pieces.Prefix)+len(pieces.Mappings)+len(pieces.Suffix) > 0\n}\n\ntype SourceMapShift struct {\n\tBefore LineColumnOffset\n\tAfter  LineColumnOffset\n}\n\nfunc (pieces SourceMapPieces) Finalize(shifts []SourceMapShift) []byte {\n\t// An optimized path for when there are no shifts\n\tif len(shifts) == 1 {\n\t\tbytes := pieces.Prefix\n\t\tminCap := len(bytes) + len(pieces.Mappings) + len(pieces.Suffix)\n\t\tif cap(bytes) < minCap {\n\t\t\tbytes = append(make([]byte, 0, minCap), bytes...)\n\t\t}\n\t\tbytes = append(bytes, pieces.Mappings...)\n\t\tbytes = append(bytes, pieces.Suffix...)\n\t\treturn bytes\n\t}\n\n\tstartOfRun := 0\n\tcurrent := 0\n\tgenerated := LineColumnOffset{}\n\tprevShiftColumnDelta := 0\n\tj := helpers.Joiner{}\n\n\t// Start the source map\n\tj.AddBytes(pieces.Prefix)\n\n\t// This assumes that a) all mappings are valid and b) all mappings are ordered\n\t// by increasing generated position. This should be the case for all mappings\n\t// generated by esbuild, which should be the only mappings we process here.\n\tfor current < len(pieces.Mappings) {\n\t\t// Handle a line break\n\t\tif pieces.Mappings[current] == ';' {\n\t\t\tgenerated.Lines++\n\t\t\tgenerated.Columns = 0\n\t\t\tprevShiftColumnDelta = 0\n\t\t\tcurrent++\n\t\t\tcontinue\n\t\t}\n\n\t\tpotentialEndOfRun := current\n\n\t\t// Read the generated column\n\t\tgeneratedColumnDelta, next := DecodeVLQ(pieces.Mappings, current)\n\t\tgenerated.Columns += generatedColumnDelta\n\t\tcurrent = next\n\n\t\tpotentialStartOfRun := current\n\n\t\t// Skip over the original position information\n\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original source\n\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original line\n\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original column\n\n\t\t// Skip a trailing comma\n\t\tif current < len(pieces.Mappings) && pieces.Mappings[current] == ',' {\n\t\t\tcurrent++\n\t\t}\n\n\t\t// Detect crossing shift boundaries\n\t\tdidCrossBoundary := false\n\t\tfor len(shifts) > 1 && shifts[1].Before.ComesBefore(generated) {\n\t\t\tshifts = shifts[1:]\n\t\t\tdidCrossBoundary = true\n\t\t}\n\t\tif !didCrossBoundary {\n\t\t\tcontinue\n\t\t}\n\n\t\t// This shift isn't relevant if the next mapping after this shift is on a\n\t\t// following line. In that case, don't split and keep scanning instead.\n\t\tshift := shifts[0]\n\t\tif shift.After.Lines != generated.Lines {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Add all previous mappings in a single run for efficiency. Since source\n\t\t// mappings are relative, no data needs to be modified inside this run.\n\t\tj.AddBytes(pieces.Mappings[startOfRun:potentialEndOfRun])\n\n\t\t// Then modify the first mapping across the shift boundary with the updated\n\t\t// generated column value. It's simplest to only support column shifts. This\n\t\t// is reasonable because import paths should not contain newlines.\n\t\tif shift.Before.Lines != shift.After.Lines {\n\t\t\tpanic(\"Unexpected line change when shifting source maps\")\n\t\t}\n\t\tshiftColumnDelta := shift.After.Columns - shift.Before.Columns\n\t\tj.AddBytes(EncodeVLQ(generatedColumnDelta + shiftColumnDelta - prevShiftColumnDelta))\n\t\tprevShiftColumnDelta = shiftColumnDelta\n\n\t\t// Finally, start the next run after the end of this generated column offset\n\t\tstartOfRun = potentialStartOfRun\n\t}\n\n\t// Finish the source map\n\tj.AddBytes(pieces.Mappings[startOfRun:])\n\tj.AddBytes(pieces.Suffix)\n\treturn j.Done()\n}\n\n// Coordinates in source maps are stored using relative offsets for size\n// reasons. When joining together chunks of a source map that were emitted\n// in parallel for different parts of a file, we need to fix up the first\n// segment of each chunk to be relative to the end of the previous chunk.\ntype SourceMapState struct {\n\t// This isn't stored in the source map. It's only used by the bundler to join\n\t// source map chunks together correctly.\n\tGeneratedLine int\n\n\t// These are stored in the source map in VLQ format.\n\tGeneratedColumn int\n\tSourceIndex     int\n\tOriginalLine    int\n\tOriginalColumn  int\n}\n\n// Source map chunks are computed in parallel for speed. Each chunk is relative\n// to the zero state instead of being relative to the end state of the previous\n// chunk, since it's impossible to know the end state of the previous chunk in\n// a parallel computation.\n//\n// After all chunks are computed, they are joined together in a second pass.\n// This rewrites the first mapping in each chunk to be relative to the end\n// state of the previous chunk.\nfunc AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startState SourceMapState, sourceMap []byte) {\n\t// Handle line breaks in between this mapping and the previous one\n\tif startState.GeneratedLine != 0 {\n\t\tj.AddBytes(bytes.Repeat([]byte{';'}, startState.GeneratedLine))\n\t\tprevEndState.GeneratedColumn = 0\n\t}\n\n\t// Skip past any leading semicolons, which indicate line breaks\n\tsemicolons := 0\n\tfor sourceMap[semicolons] == ';' {\n\t\tsemicolons++\n\t}\n\tif semicolons > 0 {\n\t\tj.AddBytes(sourceMap[:semicolons])\n\t\tsourceMap = sourceMap[semicolons:]\n\t\tprevEndState.GeneratedColumn = 0\n\t\tstartState.GeneratedColumn = 0\n\t}\n\n\t// Strip off the first mapping from the buffer. The first mapping should be\n\t// for the start of the original file (the printer always generates one for\n\t// the start of the file).\n\tgeneratedColumn, i := DecodeVLQ(sourceMap, 0)\n\tsourceIndex, i := DecodeVLQ(sourceMap, i)\n\toriginalLine, i := DecodeVLQ(sourceMap, i)\n\toriginalColumn, i := DecodeVLQ(sourceMap, i)\n\tsourceMap = sourceMap[i:]\n\n\t// Rewrite the first mapping to be relative to the end state of the previous\n\t// chunk. We now know what the end state is because we're in the second pass\n\t// where all chunks have already been generated.\n\tstartState.SourceIndex += sourceIndex\n\tstartState.GeneratedColumn += generatedColumn\n\tstartState.OriginalLine += originalLine\n\tstartState.OriginalColumn += originalColumn\n\tj.AddBytes(appendMappingToBuffer(nil, j.LastByte(), prevEndState, startState))\n\n\t// Then append everything after that without modification.\n\tj.AddBytes(sourceMap)\n}\n\nfunc appendMappingToBuffer(buffer []byte, lastByte byte, prevState SourceMapState, currentState SourceMapState) []byte {\n\t// Put commas in between mappings\n\tif lastByte != 0 && lastByte != ';' && lastByte != '\"' {\n\t\tbuffer = append(buffer, ',')\n\t}\n\n\t// Record the generated column (the line is recorded using ';' elsewhere)\n\tbuffer = append(buffer, EncodeVLQ(currentState.GeneratedColumn-prevState.GeneratedColumn)...)\n\tprevState.GeneratedColumn = currentState.GeneratedColumn\n\n\t// Record the generated source\n\tbuffer = append(buffer, EncodeVLQ(currentState.SourceIndex-prevState.SourceIndex)...)\n\tprevState.SourceIndex = currentState.SourceIndex\n\n\t// Record the original line\n\tbuffer = append(buffer, EncodeVLQ(currentState.OriginalLine-prevState.OriginalLine)...)\n\tprevState.OriginalLine = currentState.OriginalLine\n\n\t// Record the original column\n\tbuffer = append(buffer, EncodeVLQ(currentState.OriginalColumn-prevState.OriginalColumn)...)\n\tprevState.OriginalColumn = currentState.OriginalColumn\n\n\treturn buffer\n}\n\ntype LineOffsetTable struct {\n\tbyteOffsetToStartOfLine int\n\n\t// The source map specification is very loose and does not specify what\n\t// column numbers actually mean. The popular \"source-map\" library from Mozilla\n\t// appears to interpret them as counts of UTF-16 code units, so we generate\n\t// those too for compatibility.\n\t//\n\t// We keep mapping tables around to accelerate conversion from byte offsets\n\t// to UTF-16 code unit counts. However, this mapping takes up a lot of memory\n\t// and generates a lot of garbage. Since most JavaScript is ASCII and the\n\t// mapping for ASCII is 1:1, we avoid creating a table for ASCII-only lines\n\t// as an optimization.\n\tbyteOffsetToFirstNonASCII int\n\tcolumnsForNonASCII        []int\n\tutf16LineLength           int\n}\n\nfunc GenerateLineOffsetTables(contents string, approximateLineCount int) []LineOffsetTable {\n\tvar ColumnsForNonASCII []int\n\tByteOffsetToFirstNonASCII := int(0)\n\tlineByteOffset := 0\n\tcolumnByteOffset := 0\n\tcolumn := int(0)\n\n\t// Preallocate the top-level table using the approximate line count from the lexer\n\tlineOffsetTables := make([]LineOffsetTable, 0, approximateLineCount)\n\n\tfor i, c := range contents {\n\t\t// Mark the start of the next line\n\t\tif column == 0 {\n\t\t\tlineByteOffset = i\n\t\t}\n\n\t\t// Start the mapping if this character is non-ASCII\n\t\tif c > 0x7F && ColumnsForNonASCII == nil {\n\t\t\tcolumnByteOffset = i - lineByteOffset\n\t\t\tByteOffsetToFirstNonASCII = int(columnByteOffset)\n\t\t\tColumnsForNonASCII = []int{}\n\t\t}\n\n\t\t// Update the per-byte column offsets\n\t\tif ColumnsForNonASCII != nil {\n\t\t\tfor lineBytesSoFar := i - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {\n\t\t\t\tColumnsForNonASCII = append(ColumnsForNonASCII, column)\n\t\t\t}\n\t\t}\n\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && i+1 < len(contents) && contents[i+1] == '\\n' {\n\t\t\t\tcolumn++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumn++\n\t\t\t} else {\n\t\t\t\tcolumn += 2\n\t\t\t}\n\n\t\t\tlineOffsetTables = append(lineOffsetTables, LineOffsetTable{\n\t\t\t\tbyteOffsetToStartOfLine:   int(lineByteOffset),\n\t\t\t\tbyteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,\n\t\t\t\tcolumnsForNonASCII:        ColumnsForNonASCII,\n\t\t\t\tutf16LineLength:           column,\n\t\t\t})\n\t\t\tcolumnByteOffset = 0\n\t\t\tByteOffsetToFirstNonASCII = 0\n\t\t\tColumnsForNonASCII = nil\n\t\t\tcolumn = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumn++\n\t\t\t} else {\n\t\t\t\tcolumn += 2\n\t\t\t}\n\t\t}\n\t}\n\n\t// Mark the start of the next line\n\tif column == 0 {\n\t\tlineByteOffset = len(contents)\n\t}\n\n\t// Do one last update for the column at the end of the file\n\tif ColumnsForNonASCII != nil {\n\t\tfor lineBytesSoFar := len(contents) - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {\n\t\t\tColumnsForNonASCII = append(ColumnsForNonASCII, column)\n\t\t}\n\t}\n\n\tlineOffsetTables = append(lineOffsetTables, LineOffsetTable{\n\t\tbyteOffsetToStartOfLine:   int(lineByteOffset),\n\t\tbyteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,\n\t\tcolumnsForNonASCII:        ColumnsForNonASCII,\n\t\tutf16LineLength:           column,\n\t})\n\treturn lineOffsetTables\n}\n\ntype Chunk struct {\n\tBuffer []byte\n\n\t// This end state will be used to rewrite the start of the following source\n\t// map chunk so that the delta-encoded VLQ numbers are preserved.\n\tEndState SourceMapState\n\n\t// There probably isn't a source mapping at the end of the file (nor should\n\t// there be) but if we're appending another source map chunk after this one,\n\t// we'll need to know how many characters were in the last line we generated.\n\tFinalGeneratedColumn int\n\n\tShouldIgnore bool\n}\n\ntype ChunkBuilder struct {\n\tinputSourceMap      *SourceMap\n\tsourceMap           []byte\n\tprevLoc             loc.Loc\n\tprevState           SourceMapState\n\tlastGeneratedUpdate int\n\tgeneratedColumn     int\n\thasPrevState        bool\n\tlineOffsetTables    []LineOffsetTable\n\n\t// This is a workaround for a bug in the popular \"source-map\" library:\n\t// https://github.com/mozilla/source-map/issues/261. The library will\n\t// sometimes return null when querying a source map unless every line\n\t// starts with a mapping at column zero.\n\t//\n\t// The workaround is to replicate the previous mapping if a line ends\n\t// up not starting with a mapping. This is done lazily because we want\n\t// to avoid replicating the previous mapping if we don't need to.\n\tlineStartsWithMapping     bool\n\tcoverLinesWithoutMappings bool\n}\n\nfunc MakeChunkBuilder(inputSourceMap *SourceMap, lineOffsetTables []LineOffsetTable) ChunkBuilder {\n\treturn ChunkBuilder{\n\t\tinputSourceMap:   inputSourceMap,\n\t\tprevLoc:          loc.Loc{Start: -1},\n\t\tlineOffsetTables: lineOffsetTables,\n\n\t\t// We automatically repeat the previous source mapping if we ever generate\n\t\t// a line that doesn't start with a mapping. This helps give files more\n\t\t// complete mapping coverage without gaps.\n\t\t//\n\t\t// However, we probably shouldn't do this if the input file has a nested\n\t\t// source map that we will be remapping through. We have no idea what state\n\t\t// that source map is in and it could be pretty scrambled.\n\t\t//\n\t\t// I've seen cases where blindly repeating the last mapping for subsequent\n\t\t// lines gives very strange and unhelpful results with source maps from\n\t\t// other tools.\n\t\tcoverLinesWithoutMappings: inputSourceMap == nil,\n\t}\n}\n\nfunc (b *ChunkBuilder) GetLineAndColumnForLocation(location loc.Loc) []int {\n\tb.prevLoc = location\n\n\t// Binary search to find the line\n\tlineOffsetTables := b.lineOffsetTables\n\tcount := len(lineOffsetTables)\n\toriginalLine := 0\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := originalLine + step\n\t\tif len(lineOffsetTables) > i && lineOffsetTables[i].byteOffsetToStartOfLine <= location.Start {\n\t\t\toriginalLine = i + 1\n\t\t\tcount = count - step - 1\n\t\t} else {\n\t\t\tcount = step\n\t\t}\n\t}\n\toriginalLine--\n\n\t// Use the line to compute the column\n\tline := &lineOffsetTables[originalLine]\n\toriginalColumn := int(location.Start - line.byteOffsetToStartOfLine)\n\tif line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) {\n\t\tnewColumn := originalColumn - int(line.byteOffsetToFirstNonASCII)\n\t\tif len(line.columnsForNonASCII) > newColumn {\n\t\t\toriginalColumn = int(line.columnsForNonASCII[newColumn])\n\t\t}\n\t}\n\n\t// 1-based line, 1-based column\n\treturn []int{originalLine + 1, originalColumn + 1}\n}\n\nfunc (b *ChunkBuilder) OffsetAt(location loc.Loc) int {\n\tlineAndColumn := b.GetLineAndColumnForLocation(location)\n\tline := lineAndColumn[0] - 1\n\tcolumn := lineAndColumn[1] - 1\n\n\t// Collect the length of every line before this one\n\toffset := 0\n\tfor i := 0; i < line; i++ {\n\t\tcurrentLine := b.lineOffsetTables[i]\n\t\toffset += currentLine.utf16LineLength\n\t}\n\n\t// Add the column within this line\n\treturn offset + column\n}\n\nfunc (b *ChunkBuilder) AddSourceMapping(location loc.Loc, output []byte) {\n\tif location == b.prevLoc {\n\t\treturn\n\t}\n\tb.prevLoc = location\n\tif location.Start < 0 {\n\t\tb.appendMapping(SourceMapState{\n\t\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\t\tGeneratedColumn: b.generatedColumn,\n\t\t\tSourceIndex:     0,\n\t\t\tOriginalLine:    0,\n\t\t\tOriginalColumn:  0,\n\t\t})\n\n\t\t// This line now has a mapping on it, so don't insert another one\n\t\tb.lineStartsWithMapping = true\n\t\treturn\n\t}\n\t// Binary search to find the line\n\tlineOffsetTables := b.lineOffsetTables\n\tcount := len(lineOffsetTables)\n\toriginalLine := 0\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := originalLine + step\n\t\tif i > -1 && lineOffsetTables[i].byteOffsetToStartOfLine <= location.Start {\n\t\t\toriginalLine = i + 1\n\t\t\tcount = count - step - 1\n\t\t} else {\n\t\t\tcount = step\n\t\t}\n\t}\n\toriginalLine--\n\n\t// Use the line to compute the column\n\tline := &lineOffsetTables[originalLine]\n\toriginalColumn := int(location.Start - line.byteOffsetToStartOfLine)\n\tif line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) {\n\t\tif len(line.columnsForNonASCII) > originalColumn-int(line.byteOffsetToFirstNonASCII) {\n\t\t\toriginalColumn = int(line.columnsForNonASCII[originalColumn-int(line.byteOffsetToFirstNonASCII)])\n\t\t}\n\t}\n\n\tb.updateGeneratedLineAndColumn(output)\n\n\t// If this line doesn't start with a mapping and we're about to add a mapping\n\t// that's not at the start, insert a mapping first so the line starts with one.\n\tif b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.generatedColumn > 0 && b.hasPrevState {\n\t\tb.appendMappingWithoutRemapping(SourceMapState{\n\t\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\t\tGeneratedColumn: 0,\n\t\t\tSourceIndex:     b.prevState.SourceIndex,\n\t\t\tOriginalLine:    b.prevState.OriginalLine,\n\t\t\tOriginalColumn:  b.prevState.OriginalColumn,\n\t\t})\n\t}\n\n\tb.appendMapping(SourceMapState{\n\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\tGeneratedColumn: b.generatedColumn,\n\t\tOriginalLine:    originalLine,\n\t\tOriginalColumn:  originalColumn,\n\t})\n\n\t// This line now has a mapping on it, so don't insert another one\n\tb.lineStartsWithMapping = true\n}\n\nfunc (b *ChunkBuilder) GenerateChunk(output []byte) Chunk {\n\tb.updateGeneratedLineAndColumn(output)\n\tshouldIgnore := true\n\tfor _, c := range b.sourceMap {\n\t\tif c != ';' {\n\t\t\tshouldIgnore = false\n\t\t\tbreak\n\t\t}\n\t}\n\treturn Chunk{\n\t\tBuffer:               b.sourceMap,\n\t\tEndState:             b.prevState,\n\t\tFinalGeneratedColumn: b.generatedColumn,\n\t\tShouldIgnore:         shouldIgnore,\n\t}\n}\n\n// Scan over the printed text since the last source mapping and update the\n// generated line and column numbers\nfunc (b *ChunkBuilder) updateGeneratedLineAndColumn(output []byte) {\n\tfor i, c := range string(output[b.lastGeneratedUpdate:]) {\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' {\n\t\t\t\tnewlineCheck := b.lastGeneratedUpdate + i + 1\n\t\t\t\tif newlineCheck < len(output) && output[newlineCheck] == '\\n' {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we're about to move to the next line and the previous line didn't have\n\t\t\t// any mappings, add a mapping at the start of the previous line.\n\t\t\tif b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.hasPrevState {\n\t\t\t\tb.appendMappingWithoutRemapping(SourceMapState{\n\t\t\t\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\t\t\t\tGeneratedColumn: 0,\n\t\t\t\t\tSourceIndex:     b.prevState.SourceIndex,\n\t\t\t\t\tOriginalLine:    b.prevState.OriginalLine,\n\t\t\t\t\tOriginalColumn:  b.prevState.OriginalColumn,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tb.prevState.GeneratedLine++\n\t\t\tb.prevState.GeneratedColumn = 0\n\t\t\tb.generatedColumn = 0\n\t\t\tb.sourceMap = append(b.sourceMap, ';')\n\n\t\t\t// This new line doesn't have a mapping yet\n\t\t\tb.lineStartsWithMapping = false\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tb.generatedColumn++\n\t\t\t} else {\n\t\t\t\tb.generatedColumn += 2\n\t\t\t}\n\t\t}\n\t}\n\n\tb.lastGeneratedUpdate = len(output)\n}\n\nfunc (b *ChunkBuilder) appendMapping(currentState SourceMapState) {\n\t// If the input file had a source map, map all the way back to the original\n\tif b.inputSourceMap != nil {\n\t\tmapping := b.inputSourceMap.Find(\n\t\t\tint(currentState.OriginalLine),\n\t\t\tint(currentState.OriginalColumn))\n\n\t\t// Some locations won't have a mapping\n\t\tif mapping == nil {\n\t\t\treturn\n\t\t}\n\n\t\tcurrentState.SourceIndex = int(mapping.SourceIndex)\n\t\tcurrentState.OriginalLine = int(mapping.OriginalLine)\n\t\tcurrentState.OriginalColumn = int(mapping.OriginalColumn)\n\t}\n\n\tb.appendMappingWithoutRemapping(currentState)\n}\n\nfunc (b *ChunkBuilder) appendMappingWithoutRemapping(currentState SourceMapState) {\n\tvar lastByte byte\n\tif len(b.sourceMap) != 0 {\n\t\tlastByte = b.sourceMap[len(b.sourceMap)-1]\n\t}\n\n\tb.sourceMap = appendMappingToBuffer(b.sourceMap, lastByte, b.prevState, currentState)\n\tb.prevState = currentState\n\tb.hasPrevState = true\n}\n"
  },
  {
    "path": "internal/t/t.go",
    "content": "package t\n\ntype ParseOptions struct {\n\tFilename string\n\tPosition bool\n}\n"
  },
  {
    "path": "internal/test_utils/test_utils.go",
    "content": "package test_utils\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/gkampitakis/go-snaps/snaps\"\n\t\"github.com/google/go-cmp/cmp\"\n\t\"github.com/lithammer/dedent\"\n)\n\nfunc RemoveNewlines(input string) string {\n\treturn strings.ReplaceAll(input, \"\\n\", \"\")\n}\n\nfunc Dedent(input string) string {\n\treturn dedent.Dedent( // removes any leading whitespace\n\t\tstrings.ReplaceAll( // compress linebreaks to 1 or 2 lines max\n\t\t\tstrings.TrimLeft(\n\t\t\t\tstrings.TrimRight(input, \" \\n\\r\"), // remove any trailing whitespace\n\t\t\t\t\" \\t\\r\\n\"),                        // remove leading whitespace\n\t\t\t\"\\n\\n\\n\", \"\\n\\n\"),\n\t)\n}\n\nfunc ANSIDiff(x, y interface{}, opts ...cmp.Option) string {\n\tescapeCode := func(code int) string {\n\t\treturn fmt.Sprintf(\"\\x1b[%dm\", code)\n\t}\n\tdiff := cmp.Diff(x, y, opts...)\n\tif diff == \"\" {\n\t\treturn \"\"\n\t}\n\tss := strings.Split(diff, \"\\n\")\n\tfor i, s := range ss {\n\t\tswitch {\n\t\tcase strings.HasPrefix(s, \"-\"):\n\t\t\tss[i] = escapeCode(31) + s + escapeCode(0)\n\t\tcase strings.HasPrefix(s, \"+\"):\n\t\t\tss[i] = escapeCode(32) + s + escapeCode(0)\n\t\t}\n\t}\n\treturn strings.Join(ss, \"\\n\")\n}\n\n// Removes unsupported characters from the test case name, because it will be used as name for the snapshot\nfunc RedactTestName(testCaseName string) string {\n\tsnapshotName := strings.ReplaceAll(testCaseName, \"#\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"<\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \">\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \")\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"(\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \":\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \" \", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"#\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"'\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"\\\"\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"@\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"`\", \"_\")\n\tsnapshotName = strings.ReplaceAll(snapshotName, \"+\", \"_\")\n\treturn snapshotName\n}\n\ntype OutputKind int\n\nconst (\n\tJsOutput = iota\n\tJsonOutput\n\tCssOutput\n\tHtmlOutput\n\tJsxOutput\n)\n\nvar outputKind = map[OutputKind]string{\n\tJsOutput:   \"js\",\n\tJsonOutput: \"json\",\n\tCssOutput:  \"css\",\n\tHtmlOutput: \"html\",\n\tJsxOutput:  \"jsx\",\n}\n\ntype SnapshotOptions struct {\n\t// The testing instances\n\tTesting *testing.T\n\t// The name of the test case\n\tTestCaseName string\n\t// The initial source code that needs to be tested\n\tInput string\n\t// The final output\n\tOutput string\n\t// The kind of **markdown block** that the output will be wrapped\n\tKind OutputKind\n\t// The folder name that the snapshots will be stored\n\tFolderName string\n}\n\n// It creates a snapshot for the given test case, the snapshot will include the input and the output of the test case\nfunc MakeSnapshot(options *SnapshotOptions) {\n\tt := options.Testing\n\ttestCaseName := options.TestCaseName\n\tinput := options.Input\n\toutput := options.Output\n\tkind := options.Kind\n\n\tfolderName := \"__snapshots__\"\n\tif options.FolderName != \"\" {\n\t\tfolderName = options.FolderName\n\t}\n\tsnapshotName := RedactTestName(testCaseName)\n\n\ts := snaps.WithConfig(\n\t\tsnaps.Filename(snapshotName),\n\t\tsnaps.Dir(folderName),\n\t)\n\n\tsnapshot := \"## Input\\n\\n```\\n\"\n\tsnapshot += Dedent(input)\n\tsnapshot += \"\\n```\\n\\n## Output\\n\\n\"\n\tsnapshot += \"```\" + outputKind[kind] + \"\\n\"\n\tsnapshot += Dedent(output)\n\tsnapshot += \"\\n```\"\n\n\ts.MatchSnapshot(t, snapshot)\n\n}\n"
  },
  {
    "path": "internal/token.go",
    "content": "// Copyright 2010 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage astro\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"strconv\"\n\t\"strings\"\n\t\"unicode\"\n\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\t\"golang.org/x/net/html/atom\"\n)\n\n// A TokenType is the type of a Token.\ntype TokenType uint32\n\nconst (\n\t// ErrorToken means that an error occurred during tokenization.\n\tErrorToken TokenType = iota\n\t// TextToken means a text node.\n\tTextToken\n\t// A StartTagToken looks like <a>.\n\tStartTagToken\n\t// An EndTagToken looks like </a>.\n\tEndTagToken\n\t// A SelfClosingTagToken tag looks like <br/>.\n\tSelfClosingTagToken\n\t// A CommentToken looks like <!--x-->.\n\tCommentToken\n\t// A DoctypeToken looks like <!DOCTYPE x>\n\tDoctypeToken\n\n\t// ASTRO EXTENSIONS\n\t// A FenceToken is the opening or closing --- of Frontmatter\n\tFrontmatterFenceToken\n\n\t// A StartExpressionToken looks like { and can contain\n\tStartExpressionToken\n\t// An EndExpressionToken looks like }\n\tEndExpressionToken\n)\n\n// FrontmatterState tracks the open/closed state of Frontmatter.\ntype FrontmatterState uint32\n\nconst (\n\tFrontmatterInitial FrontmatterState = iota\n\tFrontmatterOpen\n\tFrontmatterClosed\n)\n\n// AttributeType is the type of an Attribute\ntype AttributeType uint32\n\nfunc (t AttributeType) String() string {\n\tswitch t {\n\tcase QuotedAttribute:\n\t\treturn \"quoted\"\n\tcase EmptyAttribute:\n\t\treturn \"empty\"\n\tcase ExpressionAttribute:\n\t\treturn \"expression\"\n\tcase SpreadAttribute:\n\t\treturn \"spread\"\n\tcase ShorthandAttribute:\n\t\treturn \"shorthand\"\n\tcase TemplateLiteralAttribute:\n\t\treturn \"template-literal\"\n\t}\n\treturn \"Invalid(\" + strconv.Itoa(int(t)) + \")\"\n}\n\nconst (\n\tQuotedAttribute AttributeType = iota\n\tEmptyAttribute\n\tExpressionAttribute\n\tSpreadAttribute\n\tShorthandAttribute\n\tTemplateLiteralAttribute\n)\n\n// ErrBufferExceeded means that the buffering limit was exceeded.\nvar ErrBufferExceeded = errors.New(\"max buffer exceeded\")\n\n// String returns a string representation of the TokenType.\nfunc (t TokenType) String() string {\n\tswitch t {\n\tcase ErrorToken:\n\t\treturn \"Error\"\n\tcase TextToken:\n\t\treturn \"Text\"\n\tcase StartTagToken:\n\t\treturn \"StartTag\"\n\tcase EndTagToken:\n\t\treturn \"EndTag\"\n\tcase SelfClosingTagToken:\n\t\treturn \"SelfClosingTag\"\n\tcase CommentToken:\n\t\treturn \"Comment\"\n\tcase DoctypeToken:\n\t\treturn \"Doctype\"\n\tcase FrontmatterFenceToken:\n\t\treturn \"FrontmatterFence\"\n\tcase StartExpressionToken:\n\t\treturn \"StartExpression\"\n\tcase EndExpressionToken:\n\t\treturn \"EndExpression\"\n\t}\n\treturn \"Invalid(\" + strconv.Itoa(int(t)) + \")\"\n}\n\nfunc (fm FrontmatterState) String() string {\n\tswitch fm {\n\tcase FrontmatterInitial:\n\t\treturn \"Initial\"\n\tcase FrontmatterOpen:\n\t\treturn \"Open\"\n\tcase FrontmatterClosed:\n\t\treturn \"Closed\"\n\t}\n\treturn \"Invalid(\" + strconv.Itoa(int(fm)) + \")\"\n}\n\n// An Attribute is an attribute namespace-key-value triple. Namespace is\n// non-empty for foreign attributes like xlink, Key is alphabetic (and hence\n// does not contain escapable characters like '&', '<' or '>'), and Val is\n// unescaped (it looks like \"a<b\" rather than \"a&lt;b\").\n//\n// Namespace is only used by the parser, not the tokenizer.\ntype Attribute struct {\n\tNamespace string\n\tKey       string\n\tKeyLoc    loc.Loc\n\tVal       string\n\tValLoc    loc.Loc\n\tTokenizer *Tokenizer\n\tType      AttributeType\n}\n\ntype Expression struct {\n\tData     string\n\tChildren []Token\n\tLoc      loc.Loc\n}\n\n// A Token consists of a TokenType and some Data (tag name for start and end\n// tags, content for text, comments and doctypes). A tag Token may also contain\n// a slice of Attributes. Data is unescaped for all Tokens (it looks like \"a<b\"\n// rather than \"a&lt;b\"). For tag Tokens, DataAtom is the atom for Data, or\n// zero if Data is not a known tag name.\ntype Token struct {\n\tType     TokenType\n\tDataAtom atom.Atom\n\tData     string\n\tAttr     []Attribute\n\tLoc      loc.Loc\n}\n\n// tagString returns a string representation of a tag Token's Data and Attr.\nfunc (t Token) tagString() string {\n\tif len(t.Attr) == 0 {\n\t\treturn t.Data\n\t}\n\tbuf := bytes.NewBufferString(t.Data)\n\tfor _, a := range t.Attr {\n\t\tbuf.WriteByte(' ')\n\n\t\tswitch a.Type {\n\t\tcase QuotedAttribute:\n\t\t\tbuf.WriteString(a.Key)\n\t\t\tbuf.WriteString(`=\"`)\n\t\t\tescape(buf, a.Val)\n\t\t\tbuf.WriteByte('\"')\n\t\tcase EmptyAttribute:\n\t\t\tbuf.WriteString(a.Key)\n\t\tcase ExpressionAttribute:\n\t\t\tbuf.WriteString(a.Key)\n\t\t\tbuf.WriteString(`={`)\n\t\t\tbuf.WriteString(a.Val)\n\t\t\tbuf.WriteByte('}')\n\t\tcase TemplateLiteralAttribute:\n\t\t\tbuf.WriteString(a.Key)\n\t\t\tbuf.WriteByte('=')\n\t\t\tbuf.WriteByte('{')\n\t\t\tbuf.WriteByte('`')\n\t\t\tescape(buf, a.Val)\n\t\t\tbuf.WriteByte('`')\n\t\t\tbuf.WriteByte('}')\n\t\tcase ShorthandAttribute:\n\t\t\tbuf.WriteByte('{')\n\t\t\tbuf.WriteString(a.Key)\n\t\t\tbuf.WriteByte('}')\n\t\tcase SpreadAttribute:\n\t\t\tbuf.WriteString(\"{...\")\n\t\t\tbuf.WriteString(a.Key)\n\t\t\tbuf.WriteByte('}')\n\t\tdefault:\n\t\t\tbuf.WriteString(a.Key)\n\t\t}\n\t}\n\treturn buf.String()\n}\n\n// String returns a string representation of the Token.\nfunc (t Token) String() string {\n\tswitch t.Type {\n\tcase ErrorToken:\n\t\treturn \"\"\n\tcase TextToken:\n\t\treturn EscapeString(t.Data)\n\tcase StartTagToken:\n\t\treturn \"<\" + t.tagString() + \">\"\n\tcase EndTagToken:\n\t\treturn \"</\" + t.tagString() + \">\"\n\tcase SelfClosingTagToken:\n\t\treturn \"<\" + t.tagString() + \"/>\"\n\tcase CommentToken:\n\t\treturn \"<!--\" + t.Data + \"-->\"\n\tcase DoctypeToken:\n\t\treturn \"<!DOCTYPE \" + t.Data + \">\"\n\tcase FrontmatterFenceToken:\n\t\treturn \"---\"\n\tcase StartExpressionToken:\n\t\treturn \"{\"\n\tcase EndExpressionToken:\n\t\treturn \"}\"\n\t}\n\treturn \"Invalid(\" + strconv.Itoa(int(t.Type)) + \")\"\n}\n\n// A Tokenizer returns a stream of HTML Tokens.\ntype Tokenizer struct {\n\t// r is the source of the HTML text.\n\tr io.Reader\n\t// tt is the TokenType of the current token.\n\ttt        TokenType\n\tprevToken Token\n\tfm        FrontmatterState\n\t// err is the first error encountered during tokenization. It is possible\n\t// for tt != Error && err != nil to hold: this means that Next returned a\n\t// valid token but the subsequent Next call will return an error token.\n\t// For example, if the HTML text input was just \"plain\", then the first\n\t// Next call would set z.err to io.EOF but return a TextToken, and all\n\t// subsequent Next calls would return an ErrorToken.\n\t// err is never reset. Once it becomes non-nil, it stays non-nil.\n\terr error\n\t// buf[raw.Start:raw.End] holds the raw bytes of the current token.\n\t// buf[raw.End:] is buffered input that will yield future tokens.\n\traw loc.Span\n\tbuf []byte\n\t// buf[data.Start:data.End] holds the raw bytes of the current token's data:\n\t// a text token's text, a tag token's tag name, etc.\n\tdata loc.Span\n\t// pendingAttr is the attribute key and value currently being tokenized.\n\t// When complete, pendingAttr is pushed onto attr. nAttrReturned is\n\t// incremented on each call to TagAttr.\n\tpendingAttr              [2]loc.Span\n\tpendingAttrType          AttributeType\n\tattr                     [][2]loc.Span\n\tattrTypes                []AttributeType\n\tattrExpressionStack      int\n\tattrTemplateLiteralStack []int\n\n\tnAttrReturned int\n\tdashCount     int\n\t// expressionStack is an array of counters tracking opening and closing\n\t// braces in nested expressions\n\texpressionStack            []int\n\texpressionElementStack     [][]string\n\topenBraceIsExpressionStart bool\n\t// rawTag is the \"script\" in \"</script>\" that closes the next token. If\n\t// non-empty, the subsequent call to Next will return a raw or RCDATA text\n\t// token: one that treats \"<p>\" as text instead of an element.\n\t// rawTag's contents are lower-cased.\n\trawTag string\n\t// noExpressionTag is the \"math\" in \"<math>\". If non-empty, any instances\n\t// of \"{\" will be treated as raw text rather than an StartExpressionToken.\n\t// noExpressionTag's contents are lower-cased.\n\tnoExpressionTag string\n\t// stringStartChar is the character that opened the last string: ', \", or `\n\t// stringStartChar byte\n\t// stringIsOpen will be true while in the context of a string\n\t// stringIsOpen bool\n\t// textIsRaw is whether the current text token's data is not escaped.\n\ttextIsRaw bool\n\t// convertNUL is whether NUL bytes in the current token's data should\n\t// be converted into \\ufffd replacement characters.\n\tconvertNUL bool\n\t// allowCDATA is whether CDATA sections are allowed in the current context.\n\tallowCDATA bool\n\n\thandler *handler.Handler\n}\n\n// AllowCDATA sets whether or not the tokenizer recognizes <![CDATA[foo]]> as\n// the text \"foo\". The default value is false, which means to recognize it as\n// a bogus comment \"<!-- [CDATA[foo]] -->\" instead.\n//\n// Strictly speaking, an HTML5 compliant tokenizer should allow CDATA if and\n// only if tokenizing foreign content, such as MathML and SVG. However,\n// tracking foreign-contentness is difficult to do purely in the tokenizer,\n// as opposed to the parser, due to HTML integration points: an <svg> element\n// can contain a <foreignObject> that is foreign-to-SVG but not foreign-to-\n// HTML. For strict compliance with the HTML5 tokenization algorithm, it is the\n// responsibility of the user of a tokenizer to call AllowCDATA as appropriate.\n// In practice, if using the tokenizer without caring whether MathML or SVG\n// CDATA is text or comments, such as tokenizing HTML to find all the anchor\n// text, it is acceptable to ignore this responsibility.\nfunc (z *Tokenizer) AllowCDATA(allowCDATA bool) {\n\tz.allowCDATA = allowCDATA\n}\n\n// NextIsNotRawText instructs the tokenizer that the next token should not be\n// considered as 'raw text'. Some elements, such as script and title elements,\n// normally require the next token after the opening tag to be 'raw text' that\n// has no child elements. For example, tokenizing \"<title>a<b>c</b>d</title>\"\n// yields a start tag token for \"<title>\", a text token for \"a<b>c</b>d\", and\n// an end tag token for \"</title>\". There are no distinct start tag or end tag\n// tokens for the \"<b>\" and \"</b>\".\n//\n// The only exception is <style>, which should be treated as raw text no\n// matter what (handled in the conditional).\n//\n// This tokenizer implementation will generally look for raw text at the right\n// times. Strictly speaking, an HTML5 compliant tokenizer should not look for\n// raw text if in foreign content: <title> generally needs raw text, but a\n// <title> inside an <svg> does not. Another example is that a <textarea>\n// generally needs raw text, but a <textarea> is not allowed as an immediate\n// child of a <select>; in normal parsing, a <textarea> implies </select>, but\n// one cannot close the implicit element when parsing a <select>'s InnerHTML.\n// Similarly to AllowCDATA, tracking the correct moment to override raw-text-\n// ness is difficult to do purely in the tokenizer, as opposed to the parser.\n// For strict compliance with the HTML5 tokenization algorithm, it is the\n// responsibility of the user of a tokenizer to call NextIsNotRawText as\n// appropriate. In practice, like AllowCDATA, it is acceptable to ignore this\n// responsibility for basic usage.\n//\n// Note that this 'raw text' concept is different from the one offered by the\n// Tokenizer.Raw method.\nfunc (z *Tokenizer) NextIsNotRawText() {\n\tif z.rawTag != \"style\" {\n\t\tz.rawTag = \"\"\n\t}\n}\n\n// Err returns the error associated with the most recent ErrorToken token.\n// This is typically io.EOF, meaning the end of tokenization.\nfunc (z *Tokenizer) Err() error {\n\tif z.tt != ErrorToken {\n\t\treturn nil\n\t}\n\treturn z.err\n}\n\n// readByte returns the next byte from the input buffer.\n// z.buf[z.raw.Start:z.raw.End] remains a contiguous byte\n// slice that holds all the bytes read so far for the current token.\n// Pre-condition: z.err == nil.\nfunc (z *Tokenizer) readByte() byte {\n\tif z.raw.End >= len(z.buf) {\n\t\tz.err = io.EOF // note: io.EOF is the only “safe” error that is a signal for the compiler to exit cleanly\n\t\treturn 0\n\t}\n\tx := z.buf[z.raw.End]\n\tz.raw.End++\n\treturn x\n}\n\n// Buffered returns a slice containing data buffered but not yet tokenized.\nfunc (z *Tokenizer) Buffered() []byte {\n\treturn z.buf[z.raw.End:]\n}\n\n// skipWhiteSpace skips past any white space.\nfunc (z *Tokenizer) skipWhiteSpace() {\n\tif z.err != nil {\n\t\treturn\n\t}\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tif z.err == io.EOF {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\t\tText: fmt.Sprintf(\"Unexpected character in skipWhiteSpace: \\\"%v\\\"\\n\", string(c)),\n\t\t\t\tRange: loc.Range{\n\t\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\t\tLen: 1,\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif !unicode.IsSpace(rune(c)) {\n\t\t\tz.raw.End--\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readRawOrRCDATA reads until the next \"</foo>\", where \"foo\" is z.rawTag and\n// is typically something like \"script\" or \"textarea\".\nfunc (z *Tokenizer) readRawOrRCDATA() {\n\t// If <script /> or any raw tag, don't try to read any data\n\tif z.Token().Type == SelfClosingTagToken {\n\t\tz.data.End = z.raw.End\n\t\tz.rawTag = \"\"\n\t\tz.noExpressionTag = \"\"\n\t\treturn\n\t}\n\tif z.rawTag == \"script\" {\n\t\tz.readScript()\n\t\tz.textIsRaw = true\n\t\tz.rawTag = \"\"\n\t\tz.noExpressionTag = \"\"\n\t\treturn\n\t}\nloop:\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tif z.err == io.EOF {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\t\tText: fmt.Sprintf(\"Unexpected character in loop: \\\"%v\\\"\\n\", string(c)),\n\t\t\t\tRange: loc.Range{\n\t\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\t\tLen: 1,\n\t\t\t\t},\n\t\t\t})\n\t\t\tbreak loop\n\t\t}\n\t\tif c != '<' {\n\t\t\tcontinue loop\n\t\t}\n\t\tc = z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\t\tif c != '/' {\n\t\t\tz.raw.End--\n\t\t\tcontinue loop\n\t\t}\n\t\tif z.readRawEndTag() || z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\t}\n\tz.data.End = z.raw.End\n\t// A textarea's or title's RCDATA can contain escaped entities.\n\tz.textIsRaw = z.rawTag != \"textarea\" && z.rawTag != \"title\"\n\tz.rawTag = \"\"\n}\n\n// readRawEndTag attempts to read a tag like \"</foo>\", where \"foo\" is z.rawTag.\n// If it succeeds, it backs up the input position to reconsume the tag and\n// returns true. Otherwise it returns false. The opening \"</\" has already been\n// consumed.\nfunc (z *Tokenizer) readRawEndTag() bool {\n\tfor i := 0; i < len(z.rawTag); i++ {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\treturn false\n\t\t}\n\t\tif c != z.rawTag[i] && c != z.rawTag[i]-('a'-'A') {\n\t\t\tz.raw.End--\n\t\t\treturn false\n\t\t}\n\t}\n\tc := z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn false\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in readRawEndTag: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn false\n\t}\n\tswitch c {\n\tcase ' ', '\\n', '\\r', '\\t', '\\f', '/', '>':\n\t\t// The 3 is 2 for the leading \"</\" plus 1 for the trailing character c.\n\t\tz.raw.End -= 3 + len(z.rawTag)\n\t\treturn true\n\t}\n\tz.raw.End--\n\treturn false\n}\n\n// readScript reads until the next </script> tag, following the byzantine\n// rules for escaping/hiding the closing tag.\nfunc (z *Tokenizer) readScript() {\n\tdefer func() {\n\t\tz.data.End = z.raw.End\n\t}()\n\tvar c byte\n\nscriptData:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptData: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tif c == '<' {\n\t\tgoto scriptDataLessThanSign\n\t}\n\tgoto scriptData\n\nscriptDataLessThanSign:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataLessThanSign: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tswitch c {\n\tcase '/':\n\t\tgoto scriptDataEndTagOpen\n\tcase '!':\n\t\tgoto scriptDataEscapeStart\n\t}\n\tz.raw.End--\n\tgoto scriptData\n\nscriptDataEndTagOpen:\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEndTagOpen: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tif z.readRawEndTag() {\n\t\treturn\n\t}\n\tgoto scriptData\n\nscriptDataEscapeStart:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEscapeStart: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tif c == '-' {\n\t\tgoto scriptDataEscapeStartDash\n\t}\n\tz.raw.End--\n\tgoto scriptData\n\nscriptDataEscapeStartDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEscapeStartDash: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tif c == '-' {\n\t\tgoto scriptDataEscapedDashDash\n\t}\n\tz.raw.End--\n\tgoto scriptData\n\nscriptDataEscaped:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEscaped: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataEscapedDash\n\tcase '<':\n\t\tgoto scriptDataEscapedLessThanSign\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataEscapedDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEscapedDash: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataEscapedLessThanSign\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataEscapedDashDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEscapedDashDash: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataEscapedLessThanSign\n\tcase '>':\n\t\tgoto scriptData\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataEscapedLessThanSign:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEscapedLessThanSign: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tif c == '/' {\n\t\tgoto scriptDataEscapedEndTagOpen\n\t}\n\tif 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' {\n\t\tgoto scriptDataDoubleEscapeStart\n\t}\n\tz.raw.End--\n\tgoto scriptData\n\nscriptDataEscapedEndTagOpen:\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataEscapedEndTagOpen: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tif z.readRawEndTag() || z.err != nil {\n\t\treturn\n\t}\n\tgoto scriptDataEscaped\n\nscriptDataDoubleEscapeStart:\n\tz.raw.End--\n\tfor i := 0; i < len(\"script\"); i++ {\n\t\tc = z.readByte()\n\t\tif z.err != nil {\n\t\t\tif z.err == io.EOF {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataDoubleEscapeStart: %v\\n\", string(c)),\n\t\t\t\tRange: loc.Range{\n\t\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\t\tLen: 1,\n\t\t\t\t},\n\t\t\t})\n\t\t\treturn\n\t\t}\n\t\tif c != \"script\"[i] && c != \"SCRIPT\"[i] {\n\t\t\tz.raw.End--\n\t\t\tgoto scriptDataEscaped\n\t\t}\n\t}\n\tc = z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch c {\n\tcase ' ', '\\n', '\\r', '\\t', '\\f', '/', '>':\n\t\tgoto scriptDataDoubleEscaped\n\t}\n\tz.raw.End--\n\tgoto scriptDataEscaped\n\nscriptDataDoubleEscaped:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataDoubleEscaped: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataDoubleEscapedDash\n\tcase '<':\n\t\tgoto scriptDataDoubleEscapedLessThanSign\n\t}\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapedDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataDoubleEscapedDash: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataDoubleEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataDoubleEscapedLessThanSign\n\t}\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapedDashDash:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataDoubleEscapedDashDash: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tswitch c {\n\tcase '-':\n\t\tgoto scriptDataDoubleEscapedDashDash\n\tcase '<':\n\t\tgoto scriptDataDoubleEscapedLessThanSign\n\tcase '>':\n\t\tgoto scriptData\n\t}\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapedLessThanSign:\n\tc = z.readByte()\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataDoubleEscapedLessThanSign: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tif c == '/' {\n\t\tgoto scriptDataDoubleEscapeEnd\n\t}\n\tz.raw.End--\n\tgoto scriptDataDoubleEscaped\n\nscriptDataDoubleEscapeEnd:\n\tif z.readRawEndTag() {\n\t\tz.raw.End += len(\"</script>\")\n\t\tgoto scriptDataEscaped\n\t}\n\tif z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\treturn\n\t\t}\n\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\tCode: loc.WARNING_UNEXPECTED_CHARACTER,\n\t\t\tText: fmt.Sprintf(\"Unexpected character in scriptDataDoubleEscapeEnd: %v\\n\", string(c)),\n\t\t\tRange: loc.Range{\n\t\t\t\tLoc: loc.Loc{Start: z.raw.End - 1},\n\t\t\t\tLen: 1,\n\t\t\t},\n\t\t})\n\t\treturn\n\t}\n\tgoto scriptDataDoubleEscaped\n}\n\n// readHTMLComment reads the next comment token starting with \"<!--\". The opening\n// \"<!--\" has already been consumed.\nfunc (z *Tokenizer) readHTMLComment() {\n\tstart := z.raw.End\n\tz.data.Start = start\n\tdefer func() {\n\t\tif z.data.End < z.data.Start {\n\t\t\t// It's a comment with no data, like <!-->.\n\t\t\tz.data.End = z.data.Start\n\t\t}\n\t}()\n\tfor dashCount := 2; ; {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tif z.err == io.EOF {\n\t\t\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\t\tCode: loc.WARNING_UNTERMINATED_HTML_COMMENT,\n\t\t\t\t\tText: `Unterminated comment`,\n\t\t\t\t\tRange: loc.Range{\n\t\t\t\t\t\tLoc: loc.Loc{Start: start},\n\t\t\t\t\t\tLen: 4,\n\t\t\t\t\t},\n\t\t\t\t})\n\t\t\t}\n\t\t\t// Ignore up to two dashes at EOF.\n\t\t\tif dashCount > 2 {\n\t\t\t\tdashCount = 2\n\t\t\t}\n\t\t\tz.data.End = z.raw.End - dashCount\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase '-':\n\t\t\tdashCount++\n\t\t\tcontinue\n\t\tcase '>':\n\t\t\tif dashCount >= 2 {\n\t\t\t\tz.data.End = z.raw.End - len(\"-->\")\n\t\t\t\treturn\n\t\t\t}\n\t\tcase '!':\n\t\t\tif dashCount >= 2 {\n\t\t\t\tc = z.readByte()\n\t\t\t\tif z.err != nil {\n\t\t\t\t\tz.data.End = z.raw.End\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif c == '>' {\n\t\t\t\t\tz.data.End = z.raw.End - len(\"--!>\")\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdashCount = 0\n\t}\n}\n\n// readUntilCloseAngle reads until the next \">\".\nfunc (z *Tokenizer) readUntilCloseAngle() {\n\tz.data.Start = z.raw.End\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn\n\t\t}\n\t\tif c == '>' {\n\t\t\tz.data.End = z.raw.End - len(\">\")\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readString reads until a JavaScript string is closed.\nfunc (z *Tokenizer) readString(c byte) {\n\tswitch c {\n\t// single quote (ends on newline)\n\tcase '\\'':\n\t\tz.readUntilChar([]byte{'\\'', '\\r', '\\n'})\n\t// double quote (ends on newline)\n\tcase '\"':\n\t\tz.readUntilChar([]byte{'\"', '\\r', '\\n'})\n\t// template literal\n\tcase '`':\n\t\t// Note that we DO NOT have to handle `${}` here because our expression\n\t\t// behavior already handles `{}` and `z.readTagAttrExpression()` handles\n\t\t// template literals separately.\n\t\tz.readUntilChar([]byte{'`'})\n\t}\n}\n\n// generic utility to look ahead until the first char is encountered from given splice\nfunc (z *Tokenizer) readUntilChar(chars []byte) {\nfind_next:\n\tfor {\n\t\tc := z.readByte()\n\t\t// fail on error\n\t\tif z.err != nil {\n\t\t\tz.data.End = z.raw.End - 1\n\t\t\treturn\n\t\t}\n\t\t// handle escape char \\\n\t\tif c == '\\\\' {\n\t\t\tz.raw.End++\n\t\t\tc = z.buf[z.data.Start : z.data.Start+1][0]\n\t\t\t// if this is a match but it’s escaped, skip and move to the next char\n\t\t\tfor _, v := range chars {\n\t\t\t\tif c == v {\n\t\t\t\t\tz.raw.End++\n\t\t\t\t\tcontinue find_next\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// match found!\n\t\tfor _, v := range chars {\n\t\t\tif c == v {\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\n// read RegExp expressions and comments (starting from '/' byte)\nfunc (z *Tokenizer) readCommentOrRegExp(boundaryChars []byte) {\n\tc := z.readByte() // find next character after '/' to know how to handle it\n\tswitch c {\n\t// single-line comment (ends on newline)\n\tcase '/':\n\t\tz.readUntilChar([]byte{'\\r', '\\n'})\n\t// multi-line comment\n\tcase '*':\n\t\tstart := z.data.Start\n\t\tprev := c\n\t\tfor {\n\t\t\tc = z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tif z.err == io.EOF {\n\t\t\t\t\tz.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode: loc.ERROR_UNTERMINATED_JS_COMMENT,\n\t\t\t\t\t\tText: `Unterminated comment`,\n\t\t\t\t\t\tRange: loc.Range{\n\t\t\t\t\t\t\tLoc: loc.Loc{Start: start},\n\t\t\t\t\t\t\tLen: 2,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// look for \"*/\"\n\t\t\tif prev == '*' && c == '/' {\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\treturn\n\t\t\t}\n\t\t\tprev = c\n\t\t}\n\t// RegExp\n\tdefault:\n\t\tz.raw.End--\n\t\tz.readUntilChar(append([]byte{'/', '\\r', '\\n'}, boundaryChars...))\n\t}\n}\n\n// readMarkupDeclaration reads the next token starting with \"<!\". It might be\n// a \"<!--comment-->\", a \"<!DOCTYPE foo>\", a \"<![CDATA[section]]>\" or\n// \"<!a bogus comment\". The opening \"<!\" has already been consumed.\nfunc (z *Tokenizer) readMarkupDeclaration() TokenType {\n\tz.data.Start = z.raw.End\n\tvar c [2]byte\n\tfor i := 0; i < 2; i++ {\n\t\tc[i] = z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn CommentToken\n\t\t}\n\t}\n\tif c[0] == '-' && c[1] == '-' {\n\t\tz.readHTMLComment()\n\t\treturn CommentToken\n\t}\n\tz.raw.End -= 2\n\tif z.readDoctype() {\n\t\treturn DoctypeToken\n\t}\n\tif z.allowCDATA && z.readCDATA() {\n\t\tz.convertNUL = true\n\t\treturn TextToken\n\t}\n\t// It's a bogus comment.\n\tz.readUntilCloseAngle()\n\treturn CommentToken\n}\n\n// readDoctype attempts to read a doctype declaration and returns true if\n// successful. The opening \"<!\" has already been consumed.\nfunc (z *Tokenizer) readDoctype() bool {\n\tconst s = \"DOCTYPE\"\n\tfor i := 0; i < len(s); i++ {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn false\n\t\t}\n\t\tif c != s[i] && c != s[i]+('a'-'A') {\n\t\t\t// Back up to read the fragment of \"DOCTYPE\" again.\n\t\t\tz.raw.End = z.data.Start\n\t\t\treturn false\n\t\t}\n\t}\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\tz.data.Start = z.raw.End\n\t\tz.data.End = z.raw.End\n\t\treturn true\n\t}\n\tz.readUntilCloseAngle()\n\treturn true\n}\n\n// readCDATA attempts to read a CDATA section and returns true if\n// successful. The opening \"<!\" has already been consumed.\nfunc (z *Tokenizer) readCDATA() bool {\n\tconst s = \"[CDATA[\"\n\tfor i := 0; i < len(s); i++ {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn false\n\t\t}\n\t\tif c != s[i] {\n\t\t\t// Back up to read the fragment of \"[CDATA[\" again.\n\t\t\tz.raw.End = z.data.Start\n\t\t\treturn false\n\t\t}\n\t}\n\tz.data.Start = z.raw.End\n\tbrackets := 0\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn true\n\t\t}\n\t\tswitch c {\n\t\tcase ']':\n\t\t\tbrackets++\n\t\tcase '>':\n\t\t\tif brackets >= 2 {\n\t\t\t\tz.data.End = z.raw.End - len(\"]]>\")\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tbrackets = 0\n\t\tdefault:\n\t\t\tbrackets = 0\n\t\t}\n\t}\n}\n\n// startTagIn returns whether the start tag in z.buf[z.data.Start:z.data.End]\n// case-insensitively matches any element of ss.\nfunc (z *Tokenizer) startTagIn(ss ...string) bool {\nloop:\n\tfor _, s := range ss {\n\t\tif z.data.End-z.data.Start != len(s) {\n\t\t\tcontinue loop\n\t\t}\n\t\tfor i := 0; i < len(s); i++ {\n\t\t\tc := z.buf[z.data.Start+i]\n\t\t\tif c != s[i] {\n\t\t\t\tcontinue loop\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (z *Tokenizer) hasAttribute(s string) bool {\n\tfor i := len(z.attr) - 1; i >= 0; i-- {\n\t\tx := z.attr[i]\n\t\tkey := z.buf[x[0].Start:x[0].End]\n\t\tif string(key) == s {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// readStartTag reads the next start tag token. The opening \"<a\" has already\n// been consumed, where 'a' means anything in [A-Za-z].\nfunc (z *Tokenizer) readStartTag() TokenType {\n\tz.readTag(true)\n\t// Several tags flag the tokenizer's next token as raw.\n\tc, raw, noExpression := z.buf[z.data.Start], false, false\n\tswitch c {\n\tcase 'i':\n\t\traw = z.startTagIn(\"iframe\")\n\tcase 'n':\n\t\traw = z.startTagIn(\"noembed\", \"noframes\")\n\tcase 'm':\n\t\tnoExpression = z.startTagIn(\"math\")\n\tcase 'p':\n\t\traw = z.startTagIn(\"plaintext\")\n\tcase 's':\n\t\traw = z.startTagIn(\"script\", \"style\")\n\tcase 't':\n\t\traw = z.startTagIn(\"textarea\", \"title\")\n\tcase 'x':\n\t\traw = z.startTagIn(\"xmp\")\n\t}\n\tif !raw {\n\t\traw = z.hasAttribute(\"is:raw\")\n\t}\n\tif raw {\n\t\tz.rawTag = string(z.buf[z.data.Start:z.data.End])\n\t}\n\tif noExpression {\n\t\tz.noExpressionTag = string(z.buf[z.data.Start:z.data.End])\n\t\tz.openBraceIsExpressionStart = false\n\t}\n\n\t// HTML void tags list: https://www.w3.org/TR/2011/WD-html-markup-20110113/syntax.html#syntax-elements\n\t// Also look for a self-closing token that's not in the list (e.g. \"<svg><path/></svg>\")\n\tif z.startTagIn(\"area\", \"base\", \"br\", \"col\", \"command\", \"embed\", \"hr\", \"img\", \"input\", \"keygen\", \"link\", \"meta\", \"param\", \"source\", \"track\", \"wbr\") || z.err == nil && z.buf[z.raw.End-2] == '/' {\n\t\t// Reset tokenizer state for self-closing elements\n\t\tz.rawTag = \"\"\n\t\treturn SelfClosingTagToken\n\t}\n\t// Special handling for selectedcontent - it's void but can have a closing tag in HTML\n\tif z.startTagIn(\"selectedcontent\") && z.err == nil && z.buf[z.raw.End-2] == '/' {\n\t\t// Only treat as self-closing if it actually has />\n\t\tz.rawTag = \"\"\n\t\treturn SelfClosingTagToken\n\t}\n\n\t// Handle TypeScript Generics\n\tif len(z.expressionElementStack) > 0 && len(z.expressionElementStack[len(z.expressionElementStack)-1]) == 0 {\n\t\tif z.prevToken.Type == TextToken {\n\t\t\ttag := z.buf[z.data.Start:z.data.End]\n\t\t\ta := atom.Lookup(tag)\n\t\t\t// We can be certain this is a start tag if we match an HTML tag, Fragment, or <>\n\t\t\tif a.String() != \"\" || bytes.Equal(tag, []byte(\"Fragment\")) || bytes.Equal(tag, []byte{}) {\n\t\t\t\treturn StartTagToken\n\t\t\t}\n\t\t\ttext := z.prevToken.Data\n\t\t\toriginalLen := len(text)\n\t\t\t// If this \"StartTagToken\" does not include any spaces between it and the end of the expression\n\t\t\t// we can roughly assume it is a TypeScript generic rather than an element. Rough but it works!\n\t\t\tif len(text) != 0 && len(strings.TrimRightFunc(text, unicode.IsSpace)) == originalLen {\n\t\t\t\treturn TextToken\n\t\t\t}\n\t\t}\n\t}\n\n\treturn StartTagToken\n}\n\n// readUnclosedTag reads up until an unclosed tag is implicitly closed.\n// Without this function, the tokenizer could get stuck in infinite loops if a\n// user is in the middle of typing\nfunc (z *Tokenizer) readUnclosedTag() bool {\n\tbuf := z.buf[z.data.Start:]\n\tvar close int\n\tif z.fm == FrontmatterOpen {\n\t\tclose = strings.Index(string(buf), \"---\")\n\t\tif close != -1 {\n\t\t\tbuf = buf[0:close]\n\t\t}\n\t}\n\tclose = bytes.Index(buf, []byte{'>'})\n\tif close != -1 {\n\t\tbuf = buf[0:close]\n\t}\n\tif close == -1 {\n\t\t// We can't find a closing tag...\n\t\tfor i := 0; i < len(buf); i++ {\n\t\t\tc := z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\n', '\\r', '\\t', '\\f':\n\t\t\t\t// Safely read up until a whitespace character\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t}\n\treturn false\n}\n\n// readTag reads the next tag token and its attributes. If saveAttr, those\n// attributes are saved in z.attr, otherwise z.attr is set to an empty slice.\n// The opening \"<a\" or \"</a\" has already been consumed, where 'a' means anything\n// in [A-Za-z].\nfunc (z *Tokenizer) readTag(saveAttr bool) {\n\tz.pendingAttrType = QuotedAttribute\n\tz.attr = z.attr[:0]\n\tz.attrTypes = z.attrTypes[:0]\n\tz.attrExpressionStack = 0\n\tz.attrTemplateLiteralStack = make([]int, 0)\n\tz.nAttrReturned = 0\n\t// Read the tag name and attribute key/value pairs.\n\tz.readTagName()\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\tif z.err == io.EOF {\n\t\t\tstart := z.prevToken.Loc.Start\n\t\t\tend := z.data.Start\n\t\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\tCode: loc.WARNING_UNCLOSED_HTML_TAG,\n\t\t\t\tText: `Unclosed tag`,\n\t\t\t\tRange: loc.Range{\n\t\t\t\t\tLoc: loc.Loc{Start: start},\n\t\t\t\t\tLen: end - start,\n\t\t\t\t},\n\t\t\t})\n\t\t}\n\t\treturn\n\t}\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil || c == '>' {\n\t\t\tbreak\n\t\t}\n\t\tz.raw.End--\n\t\tz.readTagAttrKey()\n\t\tz.readTagAttrVal()\n\t\t// Save pendingAttr if saveAttr and that attribute has a non-empty key.\n\t\tif saveAttr && z.pendingAttr[0].Start != z.pendingAttr[0].End {\n\t\t\tz.attr = append(z.attr, z.pendingAttr)\n\t\t\tz.attrTypes = append(z.attrTypes, z.pendingAttrType)\n\n\t\t\t// Warn for common mistakes\n\t\t\tattr := z.attr[len(z.attr)-1]\n\t\t\t// Possible ...spread attribute without wrapping expression\n\t\t\tif attr[0].End-attr[0].Start > 3 {\n\t\t\t\ttext := string(z.buf[attr[0].Start:attr[0].End])\n\t\t\t\tif len(strings.TrimSpace(text)) > 3 && strings.TrimSpace(text)[0:3] == \"...\" {\n\t\t\t\t\tz.handler.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode: loc.WARNING_INVALID_SPREAD,\n\t\t\t\t\t\tText: fmt.Sprintf(`Invalid spread attribute. Did you mean %s?`, fmt.Sprintf(\"`{%s}`\", text)),\n\t\t\t\t\t\tRange: loc.Range{\n\t\t\t\t\t\t\tLoc: loc.Loc{Start: attr[0].Start},\n\t\t\t\t\t\t\tLen: len(text),\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif z.skipWhiteSpace(); z.err != nil {\n\t\t\tbreak\n\t\t}\n\t}\n}\n\n// readTagName sets z.data to the \"div\" in \"<div k=v>\". The reader (z.raw.End)\n// is positioned such that the first byte of the tag name (the \"d\" in \"<div\")\n// has already been consumed.\nfunc (z *Tokenizer) readTagName() {\n\tz.data.Start = z.raw.End - 1\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase ' ', '\\n', '\\r', '\\t', '\\f':\n\t\t\tz.data.End = z.raw.End - 1\n\t\t\treturn\n\t\tcase '/', '>':\n\t\t\tz.raw.End--\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readTagAttrKey sets z.pendingAttr[0] to the \"k\" in \"<div k=v>\".\n// Precondition: z.err == nil.\nfunc (z *Tokenizer) readTagAttrKey() {\n\tz.pendingAttr[0].Start = z.raw.End\n\tz.pendingAttrType = QuotedAttribute\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tz.pendingAttr[0].End = z.raw.End\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase '{':\n\t\t\tz.pendingAttr[0].Start = z.raw.End\n\t\t\tz.pendingAttrType = ShorthandAttribute\n\t\t\tz.attrExpressionStack = 1\n\t\t\tz.attrTemplateLiteralStack = append(z.attrTemplateLiteralStack, 0)\n\t\t\tz.readTagAttrExpression()\n\t\t\tpendingAttr := z.buf[z.pendingAttr[0].Start:]\n\t\t\tif trimmed := strings.TrimSpace(string(pendingAttr)); len(trimmed) > 3 {\n\t\t\t\tif trimmed[0:3] == \"...\" {\n\t\t\t\t\tz.pendingAttr[0].Start += strings.Index(string(pendingAttr), \"...\") + 3\n\t\t\t\t\tz.pendingAttrType = SpreadAttribute\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue\n\t\tcase ' ', '\\n', '\\r', '\\t', '\\f', '/':\n\t\t\tif z.pendingAttrType == SpreadAttribute || z.pendingAttrType == ShorthandAttribute {\n\t\t\t\tz.pendingAttr[0].End = z.raw.End - 2\n\t\t\t} else {\n\t\t\t\tz.pendingAttr[0].End = z.raw.End - 1\n\t\t\t}\n\t\t\treturn\n\t\tcase '=', '>':\n\t\t\tz.raw.End--\n\t\t\tif z.pendingAttrType == SpreadAttribute || z.pendingAttrType == ShorthandAttribute {\n\t\t\t\tz.pendingAttr[0].End = z.raw.End - 1\n\t\t\t} else {\n\t\t\t\tz.pendingAttr[0].End = z.raw.End\n\t\t\t}\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// readTagAttrVal sets z.pendingAttr[1] to the \"v\" in \"<div k=v>\".\nfunc (z *Tokenizer) readTagAttrVal() {\n\tz.pendingAttr[1].Start = z.raw.End\n\tz.pendingAttr[1].End = z.raw.End\n\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\treturn\n\t}\n\tc := z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tif c != '=' {\n\t\tif z.pendingAttrType == QuotedAttribute {\n\t\t\tz.pendingAttrType = EmptyAttribute\n\t\t}\n\n\t\tz.raw.End--\n\t\treturn\n\t}\n\tif z.skipWhiteSpace(); z.err != nil {\n\t\treturn\n\t}\n\tquote := z.readByte()\n\tif z.err != nil {\n\t\treturn\n\t}\n\tswitch quote {\n\n\tcase '>':\n\t\tz.raw.End--\n\t\treturn\n\n\tcase '\\'', '\"':\n\t\tz.pendingAttr[1].Start = z.raw.End\n\t\tz.pendingAttrType = QuotedAttribute\n\t\tfor {\n\t\t\tc := z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tif z.err == io.EOF {\n\t\t\t\t\t// rescan, closing any potentially unterminated quoted attribute values\n\t\t\t\t\tfor i := z.pendingAttr[1].Start; i < z.raw.End; i++ {\n\t\t\t\t\t\tc := z.buf[i]\n\t\t\t\t\t\tif unicode.IsSpace(rune(c)) || c == '/' || c == '>' {\n\t\t\t\t\t\t\tz.pendingAttr[1].End = i\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif i == z.raw.End-1 {\n\t\t\t\t\t\t\tz.pendingAttr[1].End = i\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tz.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode: loc.ERROR_UNTERMINATED_STRING,\n\t\t\t\t\t\tText: `Unterminated quoted attribute`,\n\t\t\t\t\t\tRange: loc.Range{\n\t\t\t\t\t\t\tLoc: loc.Loc{Start: z.data.Start},\n\t\t\t\t\t\t\tLen: z.raw.End,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tz.pendingAttr[1].End = z.raw.End\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif c == quote {\n\t\t\t\tz.pendingAttr[1].End = z.raw.End - 1\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\tcase '`':\n\t\tz.pendingAttr[1].Start = z.raw.End\n\t\tz.pendingAttrType = TemplateLiteralAttribute\n\t\tfor {\n\t\t\tc := z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tif z.err == io.EOF {\n\t\t\t\t\t// rescan, closing any potentially unterminated attribute values\n\t\t\t\t\tfor i := z.pendingAttr[1].Start; i < z.raw.End; i++ {\n\t\t\t\t\t\tc := z.buf[i]\n\t\t\t\t\t\tif unicode.IsSpace(rune(c)) || c == '/' || c == '>' {\n\t\t\t\t\t\t\tz.pendingAttr[1].End = i\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif i == z.raw.End-1 {\n\t\t\t\t\t\t\tz.pendingAttr[1].End = i\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tz.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode: loc.ERROR_UNTERMINATED_STRING,\n\t\t\t\t\t\tText: `Unterminated template literal attribute`,\n\t\t\t\t\t\tRange: loc.Range{\n\t\t\t\t\t\t\tLoc: loc.Loc{Start: z.data.Start},\n\t\t\t\t\t\t\tLen: z.raw.End,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tz.pendingAttr[1].End = z.raw.End\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif c == quote {\n\t\t\t\tz.pendingAttr[1].End = z.raw.End - 1\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\tcase '{':\n\t\tz.pendingAttr[1].Start = z.raw.End\n\t\tz.pendingAttrType = ExpressionAttribute\n\t\tz.attrExpressionStack = 1\n\t\tz.attrTemplateLiteralStack = append(z.attrTemplateLiteralStack, 0)\n\t\tz.readTagAttrExpression()\n\t\tz.pendingAttr[1].End = z.raw.End - 1\n\t\treturn\n\n\tdefault:\n\t\tz.pendingAttr[1].Start = z.raw.End - 1\n\t\tz.pendingAttrType = QuotedAttribute\n\n\t\tfor {\n\t\t\tc := z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tz.pendingAttr[1].End = z.raw.End\n\t\t\t\treturn\n\t\t\t}\n\t\t\tswitch c {\n\t\t\tcase ' ', '\\n', '\\r', '\\t', '\\f':\n\t\t\t\tz.pendingAttr[1].End = z.raw.End - 1\n\t\t\t\treturn\n\t\t\tcase '>':\n\t\t\t\tz.raw.End--\n\t\t\t\tz.pendingAttr[1].End = z.raw.End\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (z *Tokenizer) allTagAttrExpressionsClosed() bool {\n\tfor i := len(z.attrTemplateLiteralStack); i > 0; i-- {\n\t\titem := z.attrTemplateLiteralStack[i-1]\n\t\tif item != 0 {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (z *Tokenizer) readTagAttrExpression() {\n\tif z.err != nil {\n\t\treturn\n\t}\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\treturn\n\t\t}\n\t\tswitch c {\n\t\tcase '`':\n\t\t\tcurrent := 0\n\t\t\tif len(z.attrTemplateLiteralStack) >= z.attrExpressionStack {\n\t\t\t\tcurrent = z.attrTemplateLiteralStack[z.attrExpressionStack-1]\n\t\t\t}\n\t\t\tif current > 0 {\n\t\t\t\tz.attrTemplateLiteralStack[z.attrExpressionStack-1]--\n\t\t\t} else {\n\t\t\t\tz.attrTemplateLiteralStack[z.attrExpressionStack-1]++\n\t\t\t}\n\t\t// Handle comments, strings within attrs\n\t\tcase '/', '\"', '\\'':\n\t\t\tif z.attrTemplateLiteralStack[z.attrExpressionStack-1] != 0 && c == '/' {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tinTemplateLiteral := len(z.attrTemplateLiteralStack) >= z.attrExpressionStack && z.attrTemplateLiteralStack[z.attrExpressionStack-1] > 0\n\t\t\tif inTemplateLiteral {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tend := z.data.End\n\t\t\tif c == '/' {\n\t\t\t\t// Also stop when we hit a '}' character (end of attribute expression)\n\t\t\t\tz.readCommentOrRegExp([]byte{'}'})\n\t\t\t\t// If we exit on a '}', ignore the final character here\n\t\t\t\tlastChar := z.buf[z.data.End-1 : z.data.End][0]\n\t\t\t\tif lastChar == '}' {\n\t\t\t\t\tz.data.End--\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tz.readString(c)\n\t\t\t}\n\t\t\tz.raw.End = z.data.End\n\t\t\tz.data.End = end\n\t\tcase '{':\n\t\t\tpreviousChar := z.buf[z.raw.End-2]\n\t\t\tinTemplateLiteral := len(z.attrTemplateLiteralStack) >= z.attrExpressionStack && z.attrTemplateLiteralStack[z.attrExpressionStack-1] > 0\n\t\t\tif !inTemplateLiteral || previousChar == '$' {\n\t\t\t\tz.attrExpressionStack++\n\t\t\t\tz.attrTemplateLiteralStack = append(z.attrTemplateLiteralStack, 0)\n\t\t\t}\n\t\tcase '}':\n\t\t\tinTemplateLiteral := len(z.attrTemplateLiteralStack) >= z.attrExpressionStack && z.attrTemplateLiteralStack[z.attrExpressionStack-1] > 0\n\t\t\tif !inTemplateLiteral {\n\t\t\t\tz.attrExpressionStack--\n\t\t\t\tif z.attrExpressionStack == 0 && z.allTagAttrExpressionsClosed() {\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (z *Tokenizer) Loc() loc.Loc {\n\treturn loc.Loc{Start: z.data.Start}\n}\n\n// An expression boundary means the next tokens should be treated as a JS expression\n// (_do_ handle strings, comments, regexp, etc) rather than as plain text\nfunc (z *Tokenizer) isAtExpressionBoundary() bool {\n\tif len(z.expressionStack) == 0 {\n\t\treturn false\n\t}\n\treturn len(z.expressionElementStack[len(z.expressionElementStack)-1]) == 0\n}\n\nfunc (z *Tokenizer) trackExpressionElementStack() {\n\tif len(z.expressionStack) == 0 {\n\t\treturn\n\t}\n\ti := len(z.expressionElementStack) - 1\n\tif z.tt == StartTagToken {\n\t\tz.expressionElementStack[i] = append(z.expressionElementStack[i], string(z.buf[z.data.Start:z.data.End]))\n\t} else if z.tt == EndTagToken {\n\t\tstack := z.expressionElementStack[i]\n\t\tif len(stack) > 0 {\n\t\t\tfor j := 1; j < len(stack)+1; j++ {\n\t\t\t\ttok := stack[len(stack)-j]\n\t\t\t\tif tok == string(z.buf[z.data.Start:z.data.End]) {\n\t\t\t\t\t// When stack is balanced, reset `openBraceIsExpressionStart`\n\t\t\t\t\tif len(stack) == 1 {\n\t\t\t\t\t\tz.expressionElementStack[i] = make([]string, 0)\n\t\t\t\t\t\tz.openBraceIsExpressionStart = false\n\t\t\t\t\t} else {\n\t\t\t\t\t\tz.expressionElementStack[i] = stack[:len(stack)-1]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if z.tt == SelfClosingTagToken {\n\t\tstack := z.expressionElementStack[i]\n\t\tif len(stack) == 0 {\n\t\t\t// Only switch out of this mode if we're not in an active stack\n\t\t\tz.openBraceIsExpressionStart = false\n\t\t}\n\t}\n}\n\n// Next scans the next token and returns its type.\nfunc (z *Tokenizer) Next() TokenType {\n\tz.prevToken = z.Token()\n\tz.raw.Start = z.raw.End\n\tz.data.Start = z.raw.End\n\tz.data.End = z.raw.End\n\tdefer z.trackExpressionElementStack()\n\n\tif z.rawTag != \"\" {\n\t\tif z.rawTag == \"plaintext\" {\n\t\t\t// Read everything up to EOF.\n\t\t\tfor z.err == nil {\n\t\t\t\tz.readByte()\n\t\t\t}\n\t\t\tz.data.End = z.raw.End\n\t\t\tz.textIsRaw = true\n\t\t} else if z.rawTag == \"title\" || z.rawTag == \"textarea\" {\n\t\t\tgoto raw_with_expression_loop\n\t\t} else {\n\t\t\tz.readRawOrRCDATA()\n\t\t}\n\t\tif z.data.End > z.data.Start {\n\t\t\tz.tt = TextToken\n\t\t\tz.convertNUL = true\n\t\t\treturn z.tt\n\t\t}\n\t}\n\tz.textIsRaw = false\n\tz.convertNUL = false\n\tif z.fm != FrontmatterClosed {\n\t\tgoto frontmatter_loop\n\t}\n\tif z.isAtExpressionBoundary() {\n\t\tgoto expression_loop\n\t}\n\nloop:\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\n\t\tvar tokenType TokenType\n\n\t\tif c == '{' || c == '}' {\n\t\t\tif x := z.raw.End - len(\"{\"); z.raw.Start < x {\n\t\t\t\tz.raw.End = x\n\t\t\t\tz.data.End = x\n\t\t\t\tz.tt = TextToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.raw.End--\n\t\t\tgoto expression_loop\n\t\t}\n\n\t\tif c == '-' && z.fm != FrontmatterClosed {\n\t\t\tz.raw.End--\n\t\t\tgoto frontmatter_loop\n\t\t}\n\t\tif c != '<' {\n\t\t\tcontinue loop\n\t\t}\n\t\tif z.fm == FrontmatterOpen {\n\t\t\tz.raw.End--\n\t\t\tgoto frontmatter_loop\n\t\t}\n\n\t\t// Check if the '<' we have just read is part of a tag, comment\n\t\t// or doctype. If not, it's part of the accumulated text token.\n\t\tc = z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak loop\n\t\t}\n\n\t\tz.openBraceIsExpressionStart = z.noExpressionTag == \"\"\n\n\t\t// Empty <> Fragment start tag\n\t\tif c == '>' {\n\t\t\tif x := z.raw.End - len(\"<>\"); z.raw.Start < x {\n\t\t\t\tz.raw.End = x\n\t\t\t\tz.data.End = x\n\t\t\t\tz.tt = TextToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.tt = StartTagToken\n\t\t\treturn z.tt\n\t\t}\n\n\t\tswitch {\n\t\tcase 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z':\n\t\t\ttokenType = StartTagToken\n\t\tcase c == '/':\n\t\t\ttokenType = EndTagToken\n\t\tcase c == '!' || c == '?':\n\t\t\t// We use CommentToken to mean any of \"<!--actual comments-->\",\n\t\t\t// \"<!DOCTYPE declarations>\" and \"<?xml processing instructions?>\".\n\t\t\ttokenType = CommentToken\n\t\tdefault:\n\t\t\traw := z.Raw()\n\t\t\t// Error: encountered an attempted use of <> syntax with attributes, like `< slot=\"named\">Hello world!</>`\n\t\t\tif len(raw) > 1 && unicode.IsSpace(rune(raw[0])) {\n\t\t\t\telement := bytes.Split(z.Buffered(), []byte{'>'})\n\t\t\t\tincorrect := fmt.Sprintf(\"< %s>\", element[0])\n\t\t\t\tcorrect := fmt.Sprintf(\"<Fragment %s>\", element[0])\n\t\t\t\tz.handler.AppendError(&loc.ErrorWithRange{\n\t\t\t\t\tCode:  loc.ERROR_FRAGMENT_SHORTHAND_ATTRS,\n\t\t\t\t\tText:  `Unable to assign attributes when using <> Fragment shorthand syntax!`,\n\t\t\t\t\tRange: loc.Range{Loc: loc.Loc{Start: z.raw.End - 2}, Len: 3 + len(element[0])},\n\t\t\t\t\tHint:  fmt.Sprintf(\"To fix this, please change %s to use the longhand Fragment syntax: %s\", incorrect, correct),\n\t\t\t\t})\n\t\t\t}\n\t\t\t// Reconsume the current character.\n\t\t\tz.raw.End--\n\t\t\tcontinue\n\t\t}\n\n\t\t// We have a non-text token, but we might have accumulated some text\n\t\t// before that. If so, we return the text first, and return the non-\n\t\t// text token on the subsequent call to Next.\n\t\tif x := z.raw.End - len(\"<a\"); z.raw.Start < x {\n\t\t\tz.raw.End = x\n\t\t\tz.data.End = x\n\t\t\tz.tt = TextToken\n\t\t\treturn z.tt\n\t\t}\n\n\t\t// If necessary, implicitly close an unclosed tag to bail out before\n\t\t// an infinite loop occurs. Helpful for IDEs which compile as user types.\n\t\tif x := z.readUnclosedTag(); x {\n\t\t\tz.tt = TextToken\n\t\t\treturn z.tt\n\t\t}\n\n\t\tswitch tokenType {\n\t\tcase StartTagToken:\n\t\t\t// If we see an element before \"---\", ignore any future \"---\"\n\t\t\tif z.fm == FrontmatterInitial {\n\t\t\t\tz.fm = FrontmatterClosed\n\t\t\t}\n\t\t\tz.tt = z.readStartTag()\n\t\t\treturn z.tt\n\t\tcase EndTagToken:\n\t\t\t// If we see an element before \"---\", ignore any future \"---\"\n\t\t\tif z.fm == FrontmatterInitial {\n\t\t\t\tz.fm = FrontmatterClosed\n\t\t\t}\n\n\t\t\tc = z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tif c == '>' {\n\t\t\t\tz.tt = EndTagToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tif 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' {\n\t\t\t\tz.readTag(false)\n\t\t\t\ttagName := string(z.buf[z.data.Start:z.data.End])\n\t\t\t\tif tagName == z.noExpressionTag {\n\t\t\t\t\t// out of the tag block\n\t\t\t\t\tz.noExpressionTag = \"\"\n\t\t\t\t}\n\t\t\t\tif z.err != nil {\n\t\t\t\t\tz.tt = ErrorToken\n\t\t\t\t} else {\n\t\t\t\t\tz.tt = EndTagToken\n\t\t\t\t}\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.raw.End--\n\t\t\tz.tt = CommentToken\n\t\t\treturn z.tt\n\t\tcase CommentToken:\n\t\t\tif c == '!' {\n\t\t\t\tz.tt = z.readMarkupDeclaration()\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.raw.End--\n\t\t\tz.readUntilCloseAngle()\n\t\t\tz.tt = CommentToken\n\t\t\treturn z.tt\n\t\t}\n\t}\n\tif z.raw.Start < z.raw.End {\n\t\t// We're scanning Text, so open braces should be ignored\n\t\tz.openBraceIsExpressionStart = false\n\t\tz.data.End = z.raw.End\n\t\tz.tt = TextToken\n\t\treturn z.tt\n\t}\n\tz.tt = ErrorToken\n\treturn z.tt\n\nfrontmatter_loop:\n\tfor {\n\t\tif z.fm == FrontmatterClosed {\n\t\t\tgoto loop\n\t\t}\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak frontmatter_loop\n\t\t}\n\n\t\t// handle frontmatter fence\n\t\tif c == '-' {\n\t\t\tz.dashCount++ // increase dashCount with each consecutive \"-\"\n\t\t}\n\n\t\tif z.dashCount == 3 {\n\t\t\tswitch z.fm {\n\t\t\tcase FrontmatterInitial:\n\t\t\t\tz.fm = FrontmatterOpen\n\t\t\t\tz.dashCount = 0\n\t\t\t\tz.data.Start = z.raw.End - len(\"---\")\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\tz.tt = FrontmatterFenceToken\n\t\t\t\tz.openBraceIsExpressionStart = false\n\t\t\t\treturn z.tt\n\t\t\tcase FrontmatterOpen:\n\t\t\t\tif z.raw.Start < z.raw.End-len(\"---\") {\n\t\t\t\t\tz.data.End = z.raw.End - len(\"---\")\n\t\t\t\t\tz.openBraceIsExpressionStart = false\n\t\t\t\t\tz.tt = TextToken\n\t\t\t\t\treturn z.tt\n\t\t\t\t}\n\t\t\t\tz.fm = FrontmatterClosed\n\t\t\t\tz.dashCount = 0\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\tz.tt = FrontmatterFenceToken\n\t\t\t\tz.openBraceIsExpressionStart = z.noExpressionTag == \"\"\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t}\n\n\t\tif c == '-' {\n\t\t\tcontinue frontmatter_loop\n\t\t}\n\n\t\t// JS Comment or RegExp\n\t\tif c == '/' {\n\t\t\tz.readCommentOrRegExp([]byte{})\n\t\t\tz.tt = TextToken\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn z.tt\n\t\t}\n\n\t\ts := z.buf[z.raw.Start : z.raw.Start+1][0]\n\n\t\tif s == '<' || s == '{' || s == '}' || c == '<' || c == '{' || c == '}' {\n\t\t\tz.dashCount = 0\n\t\t\tif z.fm == FrontmatterOpen && (s == '<' || c == '<') {\n\t\t\t\t// Do not support elements inside of frontmatter!\n\t\t\t\tcontinue frontmatter_loop\n\t\t\t} else {\n\t\t\t\tz.raw.End--\n\t\t\t\tgoto loop\n\t\t\t}\n\t\t}\n\n\t\t// handle string\n\t\tif c == '\\'' || c == '\"' || c == '`' {\n\t\t\tz.readString(c)\n\t\t\tz.tt = TextToken\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn z.tt\n\t\t}\n\n\t\tz.dashCount = 0\n\t\tcontinue frontmatter_loop\n\t}\n\tz.data.End = z.raw.End\n\nraw_with_expression_loop:\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak raw_with_expression_loop\n\t\t}\n\n\t\t// handle string\n\t\tif c == '`' {\n\t\t\tz.readString(c)\n\t\t\tz.tt = TextToken\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn z.tt\n\t\t}\n\n\t\tif c == '{' || c == '}' {\n\t\t\tif x := z.raw.End - len(\"{\"); z.raw.Start < x {\n\t\t\t\tz.raw.End = x\n\t\t\t\tz.data.End = x\n\t\t\t\tz.tt = TextToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.raw.End--\n\t\t\tgoto expression_loop\n\t\t}\n\t\tif c != '<' {\n\t\t\tcontinue raw_with_expression_loop\n\t\t}\n\t\tc = z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak raw_with_expression_loop\n\t\t}\n\t\tif c != '/' {\n\t\t\tz.raw.End--\n\t\t\tcontinue raw_with_expression_loop\n\t\t}\n\t\tif z.readRawEndTag() || z.err != nil {\n\t\t\tbreak raw_with_expression_loop\n\t\t}\n\t}\n\tz.data.End = z.raw.End\n\t// A textarea's or title's RCDATA can contain escaped entities.\n\tz.textIsRaw = z.rawTag != \"textarea\" && z.rawTag != \"title\"\n\tz.rawTag = \"\"\n\nexpression_loop:\n\tfor {\n\t\tc := z.readByte()\n\t\tif z.err != nil {\n\t\t\tbreak expression_loop\n\t\t}\n\n\t\t// JS Comment or RegExp\n\t\tif c == '/' {\n\t\t\tboundaryChars := []byte{'{', '}', '\\'', '\"', '`'}\n\t\t\tz.readCommentOrRegExp(boundaryChars)\n\t\t\t// If we exit on a '}', ignore the final character here\n\t\t\tlastChar := z.buf[z.data.End-1 : z.data.End][0]\n\t\t\tfor _, c := range boundaryChars {\n\t\t\t\tif lastChar == c {\n\t\t\t\t\tz.raw.End--\n\t\t\t\t}\n\t\t\t}\n\t\t\tz.data.End = z.raw.End\n\t\t\tz.tt = TextToken\n\t\t\treturn z.tt\n\n\t\t}\n\n\t\t// handle string\n\t\tif c == '\\'' || c == '\"' || c == '`' {\n\t\t\tz.readString(c)\n\t\t\tz.tt = TextToken\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn z.tt\n\t\t}\n\n\t\tif c == '<' {\n\t\t\t// Check next byte to see if this is an element or a JS expression.\n\t\t\t// Note: this is not a perfect check, just good enough for most cases!\n\t\t\tc1 := z.readByte()\n\t\t\tif z.err != nil {\n\t\t\t\tbreak expression_loop\n\t\t\t}\n\t\t\tif unicode.IsSpace(rune(c1)) || unicode.IsNumber(rune(c1)) {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, we have an element. Reset pointer and try again.\n\t\t\tz.raw.End -= 2\n\t\t\tz.data.End = z.raw.End\n\t\t\tif z.rawTag != \"\" {\n\t\t\t\tgoto raw_with_expression_loop\n\t\t\t} else {\n\t\t\t\tgoto loop\n\t\t\t}\n\t\t}\n\n\t\tif c != '{' && c != '}' {\n\t\t\tcontinue expression_loop\n\t\t}\n\n\t\tif x := z.raw.End - len(\"{\"); z.raw.Start < x {\n\t\t\tz.raw.End = x\n\t\t\tz.data.End = x\n\t\t\tz.tt = TextToken\n\t\t\treturn z.tt\n\t\t}\n\n\t\tswitch c {\n\t\tcase '{':\n\t\t\tif z.openBraceIsExpressionStart {\n\t\t\t\tz.openBraceIsExpressionStart = false\n\t\t\t\tz.expressionStack = append(z.expressionStack, 0)\n\t\t\t\tz.expressionElementStack = append(z.expressionElementStack, make([]string, 0))\n\t\t\t\tz.data.End = z.raw.End - 1\n\t\t\t\tz.tt = StartExpressionToken\n\t\t\t\treturn z.tt\n\t\t\t} else {\n\t\t\t\tif len(z.expressionStack) > 0 {\n\t\t\t\t\tz.expressionStack[len(z.expressionStack)-1]++\n\t\t\t\t}\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\tz.tt = TextToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\tcase '}':\n\t\t\tif len(z.expressionStack) == 0 {\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\tz.tt = TextToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t\tz.expressionStack[len(z.expressionStack)-1]--\n\t\t\tif z.expressionStack[len(z.expressionStack)-1] == -1 {\n\t\t\t\tz.openBraceIsExpressionStart = z.noExpressionTag == \"\"\n\t\t\t\tz.expressionStack = z.expressionStack[0 : len(z.expressionStack)-1]\n\t\t\t\tz.expressionElementStack = z.expressionElementStack[0 : len(z.expressionElementStack)-1]\n\t\t\t\tz.data.End = z.raw.End\n\t\t\t\tz.tt = EndExpressionToken\n\t\t\t\treturn z.tt\n\t\t\t}\n\t\t}\n\t}\n\tif z.raw.Start < z.raw.End {\n\t\tz.data.End = z.raw.End\n\t\tz.tt = TextToken\n\t\treturn z.tt\n\t}\n\tz.tt = ErrorToken\n\treturn z.tt\n}\n\n// Raw returns the unmodified text of the current token. Calling Next, Token,\n// Text, TagName or TagAttr may change the contents of the returned slice.\n//\n// The token stream's raw bytes partition the byte stream (up until an\n// ErrorToken). There are no overlaps or gaps between two consecutive token's\n// raw bytes. One implication is that the byte offset of the current token is\n// the sum of the lengths of all previous tokens' raw bytes.\nfunc (z *Tokenizer) Raw() []byte {\n\treturn z.buf[z.raw.Start:z.raw.End]\n}\n\nvar (\n\tnul         = []byte(\"\\x00\")\n\treplacement = []byte(\"\\ufffd\")\n)\n\n// Text returns the unescaped text of a text, comment or doctype token. The\n// contents of the returned slice may change on the next call to Next.\nfunc (z *Tokenizer) Text() []byte {\n\tswitch z.tt {\n\tcase TextToken, CommentToken, DoctypeToken:\n\t\ts := z.buf[z.data.Start:z.data.End]\n\t\tz.data.Start = z.raw.End\n\t\tz.data.End = z.raw.End\n\t\tif (z.convertNUL || z.tt == CommentToken) && bytes.Contains(s, nul) {\n\t\t\ts = bytes.Replace(s, nul, replacement, -1)\n\t\t}\n\n\t\t// Do not unescape text, leave it raw for the browser\n\t\t// if !z.textIsRaw {\n\t\t// \ts = unescape(s, false)\n\t\t// }\n\t\treturn s\n\t}\n\treturn nil\n}\n\n// TagName returns the lower-cased name of a tag token (the `img` out of\n// `<IMG SRC=\"foo\">`) and whether the tag has attributes.\n// The contents of the returned slice may change on the next call to Next.\nfunc (z *Tokenizer) TagName() (name []byte, hasAttr bool) {\n\tif z.data.Start < z.data.End {\n\t\tswitch z.tt {\n\t\tcase StartTagToken, EndTagToken, SelfClosingTagToken:\n\t\t\ts := z.buf[z.data.Start:z.data.End]\n\t\t\tz.data.Start = z.raw.End\n\t\t\tz.data.End = z.raw.End\n\t\t\treturn s, z.nAttrReturned < len(z.attr)\n\t\t}\n\t}\n\treturn nil, false\n}\n\n// TagAttr returns the lower-cased key and unescaped value of the next unparsed\n// attribute for the current tag token and whether there are more attributes.\n// The contents of the returned slices may change on the next call to Next.\nfunc (z *Tokenizer) TagAttr() (key []byte, keyLoc loc.Loc, val []byte, valLoc loc.Loc, attrType AttributeType, moreAttr bool) {\n\tif z.nAttrReturned < len(z.attr) {\n\t\tswitch z.tt {\n\t\tcase StartTagToken, SelfClosingTagToken:\n\t\t\tx := z.attr[z.nAttrReturned]\n\t\t\tattrType := z.attrTypes[z.nAttrReturned]\n\t\t\tz.nAttrReturned++\n\t\t\tkey = z.buf[x[0].Start:x[0].End]\n\t\t\tval = z.buf[x[1].Start:x[1].End]\n\t\t\tkeyLoc := loc.Loc{Start: x[0].Start}\n\t\t\tvalLoc := loc.Loc{Start: x[1].Start}\n\n\t\t\tvar attrVal []byte\n\t\t\tif attrType == ExpressionAttribute {\n\t\t\t\tattrVal = val\n\t\t\t} else {\n\t\t\t\tattrVal = unescape(val, true)\n\t\t\t}\n\n\t\t\treturn key, keyLoc, attrVal, valLoc, attrType, z.nAttrReturned < len(z.attr)\n\t\t}\n\t}\n\treturn nil, loc.Loc{Start: 0}, nil, loc.Loc{Start: 0}, QuotedAttribute, false\n}\n\n// Token returns the current Token. The result's Data and Attr values remain\n// valid after subsequent Next calls.\nfunc (z *Tokenizer) Token() Token {\n\tt := Token{Type: z.tt, Loc: z.Loc()}\n\n\tswitch z.tt {\n\tcase StartExpressionToken:\n\t\tt.Data = \"{\"\n\tcase EndExpressionToken:\n\t\tt.Data = \"}\"\n\tcase TextToken, CommentToken, DoctypeToken:\n\t\tt.Data = string(z.Text())\n\tcase StartTagToken, SelfClosingTagToken, EndTagToken:\n\t\tname, moreAttr := z.TagName()\n\t\tfor moreAttr {\n\t\t\tvar key, val []byte\n\t\t\tvar keyLoc, valLoc loc.Loc\n\t\t\tvar attrType AttributeType\n\t\t\tvar attrTokenizer *Tokenizer = nil\n\t\t\tkey, keyLoc, val, valLoc, attrType, moreAttr = z.TagAttr()\n\t\t\tt.Attr = append(t.Attr, Attribute{\"\", atom.String(key), keyLoc, string(val), valLoc, attrTokenizer, attrType})\n\t\t}\n\t\tif isFragment(string(name)) || isComponent(string(name)) {\n\t\t\tt.DataAtom, t.Data = 0, string(name)\n\t\t} else if a := atom.Lookup(name); a != 0 {\n\t\t\tt.DataAtom, t.Data = a, a.String()\n\t\t} else {\n\t\t\tt.DataAtom, t.Data = 0, string(name)\n\t\t}\n\t}\n\treturn t\n}\n\n// NewTokenizer returns a new HTML Tokenizer for the given Reader.\n// The input is assumed to be UTF-8 encoded.\nfunc NewTokenizer(r io.Reader) *Tokenizer {\n\treturn NewTokenizerFragment(r, \"\")\n}\n\n// NewTokenizerFragment returns a new HTML Tokenizer for the given Reader, for\n// tokenizing an existing element's InnerHTML fragment. contextTag is that\n// element's tag, such as \"div\" or \"iframe\".\n//\n// For example, how the InnerHTML \"a<b\" is tokenized depends on whether it is\n// for a <p> tag or a <script> tag.\n//\n// The input is assumed to be UTF-8 encoded.\nfunc NewTokenizerFragment(r io.Reader, contextTag string) *Tokenizer {\n\tbuf := new(bytes.Buffer)\n\tbuf.ReadFrom(r)\n\tz := &Tokenizer{\n\t\tr:                          r,\n\t\tbuf:                        buf.Bytes(),\n\t\tfm:                         FrontmatterInitial,\n\t\topenBraceIsExpressionStart: true,\n\t}\n\tif contextTag != \"\" {\n\t\tswitch s := strings.ToLower(contextTag); s {\n\t\tcase \"iframe\", \"noembed\", \"noframes\", \"plaintext\", \"script\", \"style\", \"title\", \"textarea\", \"xmp\":\n\t\t\tz.rawTag = s\n\t\t}\n\t}\n\treturn z\n}\n"
  },
  {
    "path": "internal/token_test.go",
    "content": "package astro\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/withastro/compiler/internal/test_utils\"\n)\n\ntype TokenTypeTest struct {\n\tname     string\n\tinput    string\n\texpected []TokenType\n}\n\ntype AttributeTest struct {\n\tname     string\n\tinput    string\n\texpected []AttributeType\n}\n\ntype LocTest struct {\n\tname     string\n\tinput    string\n\texpected []int\n}\n\nfunc TestBasic(t *testing.T) {\n\tBasic := []TokenTypeTest{\n\t\t{\n\t\t\t\"doctype\",\n\t\t\t`<!DOCTYPE html>`,\n\t\t\t[]TokenType{DoctypeToken},\n\t\t},\n\t\t{\n\t\t\t\"start tag\",\n\t\t\t`<html>`,\n\t\t\t[]TokenType{StartTagToken},\n\t\t},\n\t\t{\n\t\t\t\"dot component\",\n\t\t\t`<pkg.Item>`,\n\t\t\t[]TokenType{StartTagToken},\n\t\t},\n\t\t{\n\t\t\t\"noscript component\",\n\t\t\t`<noscript><Component /></noscript>`,\n\t\t\t[]TokenType{StartTagToken, SelfClosingTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"end tag\",\n\t\t\t`</html>`,\n\t\t\t[]TokenType{EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"unclosed tag\",\n\t\t\t`<components.`,\n\t\t\t[]TokenType{TextToken},\n\t\t},\n\t\t{\n\t\t\t\"self-closing tag (slash)\",\n\t\t\t`<meta charset=\"utf-8\" />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"self-closing title\",\n\t\t\t`<title set:html={} /><div></div>`,\n\t\t\t[]TokenType{SelfClosingTagToken, StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"self-closing tag (no slash)\",\n\t\t\t`<img width=\"480\" height=\"320\">`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"text\",\n\t\t\t`Hello@`,\n\t\t\t[]TokenType{TextToken},\n\t\t},\n\t\t{\n\t\t\t\"self-closing script\",\n\t\t\t`<script />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"self-closing script with sibling\",\n\t\t\t`<script /><div></div><div />`,\n\t\t\t[]TokenType{SelfClosingTagToken, StartTagToken, EndTagToken, SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"self-closing style\",\n\t\t\t`<style />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"self-closing style with sibling\",\n\t\t\t`<style /><div></div><div />`,\n\t\t\t[]TokenType{SelfClosingTagToken, StartTagToken, EndTagToken, SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute with quoted template literal\",\n\t\t\t\"<a :href=\\\"`/home`\\\">Home</a>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"No expressions inside math\",\n\t\t\t`<math>{test}</math>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, TextToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"No expressions inside math (complex)\",\n\t\t\t`<span><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><mo>4</mo><mi /><semantics><annotation encoding=\"application/x-tex\">\\sqrt {x}</annotation></semantics></math></span>`,\n\t\t\t[]TokenType{StartTagToken, StartTagToken, StartTagToken, TextToken, EndTagToken, SelfClosingTagToken, StartTagToken, StartTagToken, TextToken, TextToken, TextToken, TextToken, EndTagToken, EndTagToken, EndTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"Expression attributes allowed inside math\",\n\t\t\t`<math set:html={test} />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"SVG (self-closing)\",\n\t\t\t`<svg><path/></svg>`,\n\t\t\t[]TokenType{StartTagToken, SelfClosingTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"SVG (left open)\",\n\t\t\t`<svg><path></svg>`, // note: this test isn’t “ideal” it’s just testing current behavior\n\t\t\t[]TokenType{StartTagToken, StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"SVG with style\",\n\t\t\t`<svg><style>\n\t\t\t\t#fire {\n\t\t\t\t\tfill: orange;\n\t\t\t\t\tstroke: purple;\n\t\t\t\t}\n\t\t\t\t.wordmark {\n\t\t\t\t\tfill: black;\n\t\t\t\t}\n\t\t</style><path id=\"#fire\" d=\"M0,0 M340,29\"></path><path class=\"wordmark\" d=\"M0,0 M340,29\"></path></svg>`,\n\t\t\t[]TokenType{StartTagToken, StartTagToken, TextToken, EndTagToken, StartTagToken, EndTagToken, StartTagToken, EndTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"form element with expression follwed by another form\",\n\t\t\t`<form>{data.formLabelA}</form><form><button></button></form>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, StartTagToken, StartTagToken, EndTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"text\",\n\t\t\t\"test\",\n\t\t\t[]TokenType{TextToken},\n\t\t},\n\t\t{\n\t\t\t\"comment\",\n\t\t\t`<!-- comment -->`,\n\t\t\t[]TokenType{CommentToken},\n\t\t},\n\t\t{\n\t\t\t\"top-level expression\",\n\t\t\t`{ value }`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression inside element\",\n\t\t\t`<div>{ value }</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with solidus inside element\",\n\t\t\t`<div>{ 16 / 4 }</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with strings inside element\",\n\t\t\t`<div>{ \"string\" + 16 / 4 + \"}\" }</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression inside component\",\n\t\t\t`<Component>{items.map(item => <div>{item}</div>)}</Component>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression inside component with quoted attr\",\n\t\t\t`<Component a=\"b\">{items.map(item => <div>{item}</div>)}</Component>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression inside component with expression attr\",\n\t\t\t`<Component data={data}>{items.map(item => <div>{item}</div>)}</Component>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression inside component with named expression attr\",\n\t\t\t`<Component named={data}>{items.map(item => <div>{item}</div>)}</Component>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with multiple returns\",\n\t\t\t`<div>{() => {\n\t\t\tlet generate = (input) => {\n\t\t\t\tlet a = () => { return; };\n\t\t\t\tlet b = () => { return; };\n\t\t\t\tlet c = () => { return; };\n\t\t\t};\n\t\t}}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with multiple elements\",\n\t\t\t`<div>{() => {\n\t\t\t\tif (value > 0.25) {\n\t\t\t\t\treturn <span>Default</span>\n\t\t\t\t} else if (value > 0.5) {\n\t\t\t\t\treturn <span>Another</span>\n\t\t\t\t} else if (value > 0.75) {\n\t\t\t\t\treturn <span>Other</span>\n\t\t\t\t}\n\t\t\t\treturn <span>Yet Other</span>\n\t\t\t}}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with multiple elements returning self closing tags\",\n\t\t\t`<div>{()=>{\n\t\t\t\tif (true) {\n\t\t\t\t\treturn <hr />;\n\t\t\t\t};\n\t\t\t\tif (true) {\n\t\t\t\t\treturn <img />;\n\t\t\t\t}\n\t\t\t}}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression returning a mix of self-closing tags and elements\",\n\t\t\t`<div>{() => {\n\t\t\t\tif (value > 0.25) {\n\t\t\t\t\treturn <br />\n\t\t\t\t} else if (value > 0.5) {\n\t\t\t\t\treturn <hr />\n\t\t\t\t} else if (value > 0.75) {\n\t\t\t\t\treturn <div />\n\t\t\t\t}\n\t\t\t\treturn <div>Yaaay</div>\n\t\t\t}}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with switch returning a mix of self-closing tags and elements\",\n\t\t\t`<div>{items.map(({ type, ...data }) => { switch (type) { case 'card': { return (<Card {...data} />);}case 'paragraph': { return (<p>{data.body}</p>);}}})}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with < operators\",\n\t\t\t`<div>{() => {\n\t\t\t\tif (value < 0.25) {\n\t\t\t\t\treturn <span>Default</span>\n\t\t\t\t} else if (value <0.5) {\n\t\t\t\t\treturn <span>Another</span>\n\t\t\t\t} else if (value < 0.75) {\n\t\t\t\t\treturn <span>Other</span>\n\t\t\t\t}\n\t\t\t\treturn <span>Yet Other</span>\n\t\t\t}}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\n\t\t{\n\t\t\t\"attribute expression with quoted braces\",\n\t\t\t`<div value={\"{\"} />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with solidus\",\n\t\t\t`<div value={100 / 2} />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with solidus inside template literal\",\n\t\t\t\"<div value={attr ? `a/b` : \\\"c\\\"} />\",\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"complex attribute expression\",\n\t\t\t\"<div value={`${attr ? `a/b ${`c ${`d ${cool}`}`}` : \\\"d\\\"} awesome`} />\",\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with solidus no spaces\",\n\t\t\t`<div value={(100/2)} />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with quote\",\n\t\t\t`<div value={/* hello */} />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"JSX-style comment inside element\",\n\t\t\t`<div {/* hello */} a=b />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"quotes within textContent\",\n\t\t\t`<p>can't</p>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"apostrophe within title\",\n\t\t\t`<title>Astro's</title>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"quotes within title\",\n\t\t\t`<title>My Astro \"Website\"</title>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"textarea inside expression\",\n\t\t\t`\n\t\t\t\t\t\t{bool && <textarea>It was a dark and stormy night...</textarea>}\n\t\t\t\t\t\t{bool && <input>}\n\t\t\t\t\t`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, TextToken, EndTagToken, EndExpressionToken, TextToken, StartExpressionToken, TextToken, SelfClosingTagToken, EndExpressionToken, TextToken},\n\t\t},\n\t\t{\n\t\t\t\"text containing a /\",\n\t\t\t\"<span>next/router</span>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"iframe allows attributes\",\n\t\t\t\"<iframe src=\\\"https://google.com\\\"></iframe>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"is:raw allows children to be parsed as Text\",\n\t\t\t\"<span is:raw>function foo() { }</span>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"is:raw treats all children as raw text\",\n\t\t\t\"<Fragment is:raw><ul></ue></Fragment>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"is:raw treats all children as raw text\",\n\t\t\t\"<Fragment is:raw><ul></ue></Fragment>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"is:raw allows other attributes\",\n\t\t\t\"<span data-raw={true} is:raw><%= Hi =%></span>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"Doesn't throw on other data attributes\",\n\t\t\t\"<span data-foo></span>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"Doesn't work if attr is named data\",\n\t\t\t\"<span data>{Hello}</span>\",\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"Supports <style> inside of <svg>\",\n\t\t\t`<svg><style><div>:root { color: red; }</style></svg>`,\n\t\t\t[]TokenType{StartTagToken, StartTagToken, TextToken, EndTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"multiple scoped :global\",\n\t\t\t`<style>:global(test-2) {}</style><style>test-1{}</style>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken, StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"multiple styles\",\n\t\t\t`<style global>a {}</style><style>b {}</style><style>c {}</style>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken, StartTagToken, TextToken, EndTagToken, StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"element with single quote\",\n\t\t\t`<div>Don't panic</div>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"fragment\",\n\t\t\t`<>foo</>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"fragment shorthand\",\n\t\t\t`<h1>A{cond && <>item <span>{text}</span></>}</h1>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, StartExpressionToken, TextToken, StartTagToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, EndTagToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"fragment\",\n\t\t\t`<Fragment>foo</Fragment>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"fragment shorthand in nested expression\",\n\t\t\t`<div>{x.map((x) => (<>{x ? \"truthy\" : \"falsy\"}</>))}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"select with expression\",\n\t\t\t`<select>{[1, 2, 3].map(num => <option>{num}</option>)}</select>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"select with expression\",\n\t\t\t`<select>{[1, 2, 3].map(num => <option>{num}</option>)}</select><div>Hello</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken, StartTagToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"selectedcontent element\",\n\t\t\t`<select><button><selectedcontent></selectedcontent></button><option>A</option></select>`,\n\t\t\t[]TokenType{StartTagToken, StartTagToken, StartTagToken, EndTagToken, EndTagToken, StartTagToken, TextToken, EndTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"selectedcontent self-closing\",\n\t\t\t`<select><button><selectedcontent /></button><option>A</option></select>`,\n\t\t\t[]TokenType{StartTagToken, StartTagToken, SelfClosingTagToken, EndTagToken, StartTagToken, TextToken, EndTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"single open brace\",\n\t\t\t\"<main id={`{`}></main>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"single close brace\",\n\t\t\t\"<main id={`}`}></main>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"extra close brace\",\n\t\t\t\"<main id={`${}}`}></main>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"Empty expression\",\n\t\t\t\"({})\",\n\t\t\t[]TokenType{TextToken, StartExpressionToken, EndExpressionToken, TextToken},\n\t\t},\n\t\t{\n\t\t\t\"expression after text\",\n\t\t\t`<h1>A{cond && <span>Test {text}</span>}</h1>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, StartExpressionToken, TextToken, StartTagToken, TextToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression surrounded by text\",\n\t\t\t`<h1>A{cond && <span>Test {text} Cool</span>}</h1>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, StartExpressionToken, TextToken, StartTagToken, TextToken, StartExpressionToken, TextToken, EndExpressionToken, TextToken, EndTagToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"switch statement\",\n\t\t\t`<div>{() => { switch(value) { case 'a': return <A></A>; case 'b': return <B />; case 'c': return <C></C> }}}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, EndTagToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, StartTagToken, EndTagToken, TextToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"switch statement with expression\",\n\t\t\t`<div>{() => { switch(value) { case 'a': return <A>{value}</A>; case 'b': return <B />; case 'c': return <C>{value.map(i => <span>{i}</span>)}</C> }}}</div>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, SelfClosingTagToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with unmatched quotes\",\n\t\t\t\"<h1 set:text={`Houston we've got a problem`}></h1>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with unmatched quotes\",\n\t\t\t\"<h1 set:html={`Oh \\\"no...`}></h1>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with unmatched quotes inside matched quotes\",\n\t\t\t\"<h1 set:html={\\\"hello y'all\\\"}></h1>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with unmatched quotes inside matched quotes II\",\n\t\t\t\"<h1 set:html={'\\\"Did Nate handle this case, too?\\\", Fred pondered...'}></h1>\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"typescript generic\",\n\t\t\t`<ul>{items.map((item: Item<Checkbox>)) => <li>{item.checked}</li>)}</ul>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"typescript generic II\",\n\t\t\t`<ul>{items.map((item: Item<Checkbox>)) => <Checkbox>{item.checked}</Checkbox>)}</ul>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"incomplete tag\",\n\t\t\t`<MyAstroComponent`,\n\t\t\t[]TokenType{TextToken},\n\t\t},\n\t\t{\n\t\t\t\"incomplete tag II\",\n\t\t\t`<MyAstroComponent` + \"\\n\",\n\t\t\t[]TokenType{TextToken},\n\t\t},\n\t\t{\n\t\t\t\"incomplete tag III\",\n\t\t\t`<div></div><MyAstroComponent` + \"\\n\",\n\t\t\t[]TokenType{StartTagToken, EndTagToken, TextToken},\n\t\t},\n\t}\n\n\trunTokenTypeTest(t, Basic)\n}\n\nfunc TestFrontmatter(t *testing.T) {\n\tFrontmatter := []TokenTypeTest{\n\t\t{\n\t\t\t\"simple token\",\n\t\t\t`---`,\n\t\t\t[]TokenType{FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"basic case\",\n\t\t\t`\n\t\t\t---\n\t\t\tconst a = 0;\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"ignores leading whitespace\",\n\t\t\t`\n\n\t\t\t---\n\t\t\tconst a = 0;\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"allows leading comments\",\n\t\t\t`\n\t\t\t<!-- Why? Who knows! -->\n\t\t\t---\n\t\t\tconst a = 0;\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{CommentToken, FrontmatterFenceToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"treated as text after element\",\n\t\t\t`\n\t\t\t<div />\n\n\t\t\t---\n\t\t\tconst a = 0;\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{SelfClosingTagToken, TextToken},\n\t\t},\n\t\t{\n\t\t\t\"treated as text after closed\",\n\t\t\t`\n\t\t\t---\n\t\t\tconst a = 0;\n\t\t\t---\n\t\t\t<div>\n\t\t\t---\n\t\t\t</div>\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, FrontmatterFenceToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken},\n\t\t},\n\t\t{\n\t\t\t\"does not tokenize elements inside\",\n\t\t\t`\n\t\t\t---\n\t\t\tconst a = <div />;\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"no elements or expressions in frontmatter\",\n\t\t\t`\n\t\t\t---\n\t\t\tconst contents = \"foo\";\n\t\t\tconst a = <div>{contents}</div>;\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"brackets within frontmatter treated as text\",\n\t\t\t`\n\t\t\t---\n\t\t\tconst someProps = {\n\t\t\t\tcount: 0,\n\t\t\t}\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, TextToken, TextToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"frontmatter tags and brackets all treated as text\",\n\t\t\t`\n\t\t\t---\n\t\t\tconst contents = \"foo\";\n\t\t\tconst a = <ul>{contents}</ul>\n\t\t\tconst someProps = {\n\t\t\t\tcount: 0,\n\t\t\t}\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"less than isn’t a tag\",\n\t\t\t`\n\t\t\t---\n\t\t\tconst a = 2;\n\t\t\tconst div = 4\n\t\t\tconst isBigger = a < div;\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"less than attr\",\n\t\t\t`<div aria-hidden={count < 1} />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"greater than attr\",\n\t\t\t`<div aria-hidden={count > 1} />`,\n\t\t\t[]TokenType{SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"greater than attr inside expression\",\n\t\t\t`{values.map(value => <div aria-hidden={count > 1} />)}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, SelfClosingTagToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"single-line comments\",\n\t\t\t`\n\t\t\t---\n\t\t\t// --- <div>\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"multi-line comments\",\n\t\t\t`\n\t\t\t---\n\t\t\t/* --- <div> */\n\t\t\t---\n\t\t\t`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, FrontmatterFenceToken},\n\t\t},\n\t\t{\n\t\t\t\"RegExp\",\n\t\t\t`---\nconst RegExp = /---< > > { }; import thing from \"thing\"; /\n---\n\t\t\t{html}`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, FrontmatterFenceToken, TextToken, StartExpressionToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"RegExp with Escape\",\n\t\t\t`---\nexport async function getStaticPaths() {\n  const pattern = /\\.md$/g;\n}\n---\n<div />`,\n\t\t\t[]TokenType{FrontmatterFenceToken, TextToken, TextToken, TextToken, TextToken, TextToken, TextToken, FrontmatterFenceToken, SelfClosingTagToken},\n\t\t},\n\t\t{\n\t\t\t\"textarea\",\n\t\t\t`<textarea>{html}</textarea>`,\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t// {\n\t\t// \t\"less than with no space isn’t a tag\",\n\t\t// \t`\n\t\t// \t---\n\t\t// \tconst a = 2;\n\t\t// \tconst div = 4\n\t\t// \tconst isBigger = a <div\n\t\t// \t---\n\t\t// \t`,\n\t\t// \t[]TokenType{FrontmatterFenceToken, TextToken, FrontmatterFenceToken},\n\t\t// },\n\t}\n\n\trunTokenTypeTest(t, Frontmatter)\n}\n\nfunc TestExpressions(t *testing.T) {\n\tExpressions := []TokenTypeTest{\n\t\t{\n\t\t\t\"simple expression\",\n\t\t\t`{value}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"object expression\",\n\t\t\t`{{ value }}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"tag expression\",\n\t\t\t`{<div />}`,\n\t\t\t[]TokenType{StartExpressionToken, SelfClosingTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"string expression\",\n\t\t\t`{\"<div {attr} />\"}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"function expression\",\n\t\t\t`{() => {\n\t\t\t\treturn value\n\t\t\t}}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"nested one level\",\n\t\t\t`{() => {\n\t\t\t\treturn <div>{value}</div>\n\t\t\t}}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"nested one level with self-closing tag before expression\",\n\t\t\t`{() => {\n\t\t\t\treturn <div><div />{value}</div>\n\t\t\t}}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, StartTagToken, SelfClosingTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"nested two levels\",\n\t\t\t`{() => {\n\t\t\t\treturn <div>{() => {\n\t\t\t\t\treturn value\n\t\t\t\t}}</div>\n\t\t\t}}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"nested two levels with tag\",\n\t\t\t`{() => {\n\t\t\t\treturn <div>{() => {\n\t\t\t\t\treturn <div>{value}</div>\n\t\t\t\t}}</div>\n\t\t\t}}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, EndExpressionToken, EndTagToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression map\",\n\t\t\t`<div>\n\t\t\t  {items.map((item) => (\n\t\t      // < > < }\n\t\t      <div>{item}</div>\n\t\t    ))}\n\t\t  </div>`,\n\t\t\t[]TokenType{StartTagToken, TextToken, StartExpressionToken, TextToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken, TextToken, EndExpressionToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"left bracket within string\",\n\t\t\t`{\"{\"}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"right bracket within string\",\n\t\t\t`{'}'}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression within string\",\n\t\t\t`{'{() => <Component />}'}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression within single-line comment\",\n\t\t\t`{ // < > < }\n\t\t    'text'\n\t\t  }`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression within multi-line comment\",\n\t\t\t`{/* < > < } */ 'text'}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with nested strings\",\n\t\t\t\"{`${`${`${foo}`}`}`}\",\n\t\t\t[]TokenType{StartExpressionToken, TextToken, TextToken, TextToken, TextToken, TextToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"element with multiple expressions\",\n\t\t\t\"<div>Hello {first} {last}</div>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, StartExpressionToken, TextToken, EndExpressionToken, TextToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"ternary render\",\n\t\t\t\"{false ? <div>#f</div> : <div>#t</div>}\",\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, StartTagToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"title\",\n\t\t\t\"<title>test {expr} test</title>\",\n\t\t\t[]TokenType{StartTagToken, TextToken, StartExpressionToken, TextToken, EndExpressionToken, TextToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"String interpolation inside an expression within a title\",\n\t\t\t\"<title>{content.title && `${title} 🚀 ${title}`}</title>\",\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"Nested use of string templates inside expressions\",\n\t\t\t\"<div>{`${a} inner${a > 1 ? 's' : ''}.`}</div>\",\n\t\t\t[]TokenType{StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, EndTagToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with single quote\",\n\t\t\t`{true && <div>Don't panic</div>}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with double quote\",\n\t\t\t`{true && <div>Don't panic</div>}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"expression with literal quote\",\n\t\t\t`{true && <div>Don` + \"`\" + `t panic</div>}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"ternary expression with single quote\",\n\t\t\t`{true ? <div>Don't panic</div> : <div>Do' panic</div>}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, TextToken, EndTagToken, TextToken, StartTagToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"single quote after expression\",\n\t\t\t`{true && <div>{value} Don't panic</div>}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, StartExpressionToken, TextToken, EndExpressionToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"single quote after self-closing\",\n\t\t\t`{true && <div><span /> Don't panic</div>}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, SelfClosingTagToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t\t{\n\t\t\t\"single quote after end tag\",\n\t\t\t`{true && <div><span></span> Don't panic</div>}`,\n\t\t\t[]TokenType{StartExpressionToken, TextToken, StartTagToken, StartTagToken, EndTagToken, TextToken, EndTagToken, EndExpressionToken},\n\t\t},\n\t}\n\n\trunTokenTypeTest(t, Expressions)\n}\n\nfunc TestAttributes(t *testing.T) {\n\tAttributes := []AttributeTest{\n\t\t{\n\t\t\t\"double quoted\",\n\t\t\t`<div a=\"value\" />`,\n\t\t\t[]AttributeType{QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"single quoted\",\n\t\t\t`<div a='value' />`,\n\t\t\t[]AttributeType{QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"not quoted\",\n\t\t\t`<div a=value />`,\n\t\t\t[]AttributeType{QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"expression\",\n\t\t\t`<div a={value} />`,\n\t\t\t[]AttributeType{ExpressionAttribute},\n\t\t},\n\t\t{\n\t\t\t\"expression with apostrophe\",\n\t\t\t`<div a=\"fred's\" />`,\n\t\t\t[]AttributeType{QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"expression with template literal\",\n\t\t\t\"<div a=\\\"`value`\\\" />\",\n\t\t\t[]AttributeType{QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"expression with template literal interpolation\",\n\t\t\t\"<div a=\\\"`${value}`\\\" />\",\n\t\t\t[]AttributeType{QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"shorthand\",\n\t\t\t`<div {value} />`,\n\t\t\t[]AttributeType{ShorthandAttribute},\n\t\t},\n\t\t{\n\t\t\t\"less than expression\",\n\t\t\t`<div a={a < b} />`,\n\t\t\t[]AttributeType{ExpressionAttribute},\n\t\t},\n\t\t{\n\t\t\t\"greater than expression\",\n\t\t\t`<div a={a > b} />`,\n\t\t\t[]AttributeType{ExpressionAttribute},\n\t\t},\n\t\t{\n\t\t\t\"spread\",\n\t\t\t`<div {...value} />`,\n\t\t\t[]AttributeType{SpreadAttribute},\n\t\t},\n\t\t{\n\t\t\t\"template literal\",\n\t\t\t\"<div a=`value` />\",\n\t\t\t[]AttributeType{TemplateLiteralAttribute},\n\t\t},\n\t\t{\n\t\t\t\"all\",\n\t\t\t\"<div a='value' a={value} {value} {...value} a=`value` />\",\n\t\t\t[]AttributeType{QuotedAttribute, ExpressionAttribute, ShorthandAttribute, SpreadAttribute, TemplateLiteralAttribute},\n\t\t},\n\t\t{\n\t\t\t\"multiple quoted\",\n\t\t\t`<div a=\"value\" b='value' c=value/>`,\n\t\t\t[]AttributeType{QuotedAttribute, QuotedAttribute, QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"expression with quoted braces\",\n\t\t\t`<div value={ \"{\" } />`,\n\t\t\t[]AttributeType{ExpressionAttribute},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with solidus inside template literal\",\n\t\t\t\"<div value={attr ? `a/b` : \\\"c\\\"} />\",\n\t\t\t[]AttributeType{ExpressionAttribute},\n\t\t},\n\t\t{\n\t\t\t\"attribute expression with solidus inside template literal with trailing text\",\n\t\t\t\"<div value={`${attr ? `a/b` : \\\"c\\\"} awesome`} />\",\n\t\t\t[]AttributeType{ExpressionAttribute},\n\t\t},\n\t\t{\n\t\t\t\"iframe allows attributes\",\n\t\t\t\"<iframe src=\\\"https://google.com\\\"></iframe>\",\n\t\t\t[]AttributeType{QuotedAttribute},\n\t\t},\n\t\t{\n\t\t\t\"shorthand attribute with comment\",\n\t\t\t\"<div {/* a comment */ value} />\",\n\t\t\t[]AttributeType{ShorthandAttribute},\n\t\t},\n\t\t{\n\t\t\t\"expression with comment\",\n\t\t\t\"<div a={/* a comment */ value} />\",\n\t\t\t[]AttributeType{ExpressionAttribute},\n\t\t},\n\t}\n\n\trunAttributeTypeTest(t, Attributes)\n}\n\nfunc TestLoc(t *testing.T) {\n\tLocs := []LocTest{\n\t\t{\n\t\t\t\"doctype\",\n\t\t\t`<!DOCTYPE html>`,\n\t\t\t[]int{0, 11},\n\t\t},\n\t\t{\n\t\t\t\"frontmatter\",\n\t\t\t`---\ndoesNotExist\n---\n`,\n\t\t\t[]int{0, 1, 4},\n\t\t},\n\t\t{\n\t\t\t\"expression\",\n\t\t\t`<div>{console.log(hey)}</div>`,\n\t\t\t[]int{0, 2, 6, 7, 23, 26},\n\t\t},\n\t\t{\n\t\t\t\"expression II\",\n\t\t\t`{\"hello\" + hey}`,\n\t\t\t[]int{0, 1, 2, 9, 15},\n\t\t},\n\t\t{\n\t\t\t\"element I\",\n\t\t\t`<div></div>`,\n\t\t\t[]int{0, 2, 8},\n\t\t},\n\t}\n\n\trunTokenLocTest(t, Locs)\n}\n\nfunc runTokenTypeTest(t *testing.T, suite []TokenTypeTest) {\n\tfor _, tt := range suite {\n\t\tvalue := test_utils.Dedent(tt.input)\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\ttokens := make([]TokenType, 0)\n\t\t\ttokenizer := NewTokenizer(strings.NewReader(value))\n\t\t\tvar next TokenType\n\t\t\tfor {\n\t\t\t\tnext = tokenizer.Next()\n\t\t\t\tif next == ErrorToken {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttokens = append(tokens, next)\n\t\t\t}\n\t\t\tif !reflect.DeepEqual(tokens, tt.expected) {\n\t\t\t\tt.Errorf(\"Tokens = %v\\nExpected = %v\", tokens, tt.expected)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc runAttributeTypeTest(t *testing.T, suite []AttributeTest) {\n\tfor _, tt := range suite {\n\t\tvalue := test_utils.Dedent(tt.input)\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tattributeTypes := make([]AttributeType, 0)\n\t\t\ttokenizer := NewTokenizer(strings.NewReader(value))\n\t\t\tvar next TokenType\n\t\t\tfor {\n\t\t\t\tnext = tokenizer.Next()\n\t\t\t\tif next == ErrorToken {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\tfor _, attr := range tokenizer.Token().Attr {\n\t\t\t\t\tattributeTypes = append(attributeTypes, attr.Type)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !reflect.DeepEqual(attributeTypes, tt.expected) {\n\t\t\t\tt.Errorf(\"Attributes = %v\\nExpected = %v\", attributeTypes, tt.expected)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc runTokenLocTest(t *testing.T, suite []LocTest) {\n\tfor _, tt := range suite {\n\t\tvalue := test_utils.Dedent(tt.input)\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tlocs := make([]int, 0)\n\t\t\ttokenizer := NewTokenizer(strings.NewReader(value))\n\t\t\tvar next TokenType\n\t\t\tlocs = append(locs, tokenizer.Token().Loc.Start)\n\t\t\tfor {\n\t\t\t\tnext = tokenizer.Next()\n\t\t\t\tif next == ErrorToken {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ttok := tokenizer.Token()\n\t\t\t\tlocs = append(locs, tok.Loc.Start+1)\n\t\t\t}\n\t\t\tif !reflect.DeepEqual(locs, tt.expected) {\n\t\t\t\tt.Errorf(\"Tokens = %v\\nExpected = %v\", locs, tt.expected)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/transform/scope-css.go",
    "content": "package transform\n\nimport (\n\n\t// \"strings\"\n\n\t\"fmt\"\n\t\"strings\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_parser\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_printer\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n\ta \"golang.org/x/net/html/atom\"\n)\n\n// Take a slice of DOM nodes, and scope CSS within every <style> tag\nfunc ScopeStyle(styles []*astro.Node, opts TransformOptions) bool {\n\tdidScope := false\n\tfor _, n := range styles {\n\t\tif n.DataAtom != a.Style {\n\t\t\tcontinue\n\t\t}\n\t\tif hasTruthyAttr(n, \"global\") {\n\t\t\tfmt.Printf(\"Found `<style global>` in %s! Please migrate to the `is:global` directive.\\n\", opts.Filename)\n\t\t\tcontinue\n\t\t}\n\t\tif hasTruthyAttr(n, \"is:global\") {\n\t\t\tcontinue\n\t\t}\n\t\tif n.FirstChild == nil || strings.TrimSpace(n.FirstChild.Data) == \"\" {\n\t\t\tif !HasAttr(n, \"define:vars\") {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tdidScope = true\n\t\tn.Attr = append(n.Attr, astro.Attribute{\n\t\t\tKey: \"data-astro-id\",\n\t\t\tVal: opts.Scope,\n\t\t})\n\t\tif n.FirstChild == nil || strings.TrimSpace(n.FirstChild.Data) == \"\" {\n\t\t\tcontinue\n\t\t}\n\t\tscopeStrategy := css_printer.ScopeStrategyWhere\n\t\tif opts.ScopedStyleStrategy == \"class\" {\n\t\t\tscopeStrategy = css_printer.ScopeStrategyClass\n\t\t} else if opts.ScopedStyleStrategy == \"attribute\" {\n\t\t\tscopeStrategy = css_printer.ScopeStrategyAttribute\n\t\t}\n\n\t\t// Use vendored version of esbuild internals to parse AST\n\t\ttree := css_parser.Parse(logger.Log{AddMsg: func(msg logger.Msg) {}}, logger.Source{Contents: n.FirstChild.Data}, css_parser.Options{MinifySyntax: false, MinifyWhitespace: true})\n\t\t// esbuild's internal `css_printer` has been modified to emit Astro scoped styles\n\t\tresult := css_printer.Print(tree, css_printer.Options{MinifyWhitespace: true, Scope: opts.Scope, ScopeStrategy: scopeStrategy})\n\t\tn.FirstChild.Data = string(result.CSS)\n\t}\n\n\treturn didScope\n}\n\nfunc GetDefineVars(styles []*astro.Node) []string {\n\tvalues := make([]string, 0)\n\tfor _, n := range styles {\n\t\tif n.DataAtom != a.Style {\n\t\t\tcontinue\n\t\t}\n\t\tif !HasAttr(n, \"define:vars\") {\n\t\t\tcontinue\n\t\t}\n\t\tattr := GetAttr(n, \"define:vars\")\n\t\tif attr != nil {\n\t\t\tswitch attr.Type {\n\t\t\tcase astro.QuotedAttribute:\n\t\t\t\tvalues = append(values, fmt.Sprintf(\"'%s'\", attr.Val))\n\t\t\tcase astro.TemplateLiteralAttribute:\n\t\t\t\tvalues = append(values, fmt.Sprintf(\"`%s`\", attr.Val))\n\t\t\tcase astro.ExpressionAttribute:\n\t\t\t\tvalues = append(values, attr.Val)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn values\n}\n"
  },
  {
    "path": "internal/transform/scope-css_test.go",
    "content": "package transform\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/test_utils\"\n)\n\nfunc TestScopeStyle(t *testing.T) {\n\t// note: the tests have hashes inlined because it’s easier to read\n\t// note: this must be valid CSS, hence the empty \"{}\"\n\ttests := []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname:   \"class\",\n\t\t\tsource: \".class{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"id\",\n\t\t\tsource: \"#class{}\",\n\t\t\twant:   \"#class:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"element\",\n\t\t\tsource: \"h1{}\",\n\t\t\twant:   \"h1:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"adjacent sibling\",\n\t\t\tsource: \".class+.class{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx)+.class:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"and selector\",\n\t\t\tsource: \".class,.class{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx),.class:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"children universal\",\n\t\t\tsource: \".class *{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx) :where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"attr\",\n\t\t\tsource: \"a[aria-current=page]{}\",\n\t\t\twant:   \"a:where(.astro-xxxxxx)[aria-current=page]{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"attr universal implied\",\n\t\t\tsource: \"[aria-visible],[aria-hidden]{}\",\n\t\t\twant:   \":where(.astro-xxxxxx)[aria-visible],:where(.astro-xxxxxx)[aria-hidden]{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"universal pseudo state\",\n\t\t\tsource: \"*:hover{}\",\n\t\t\twant:   \":where(.astro-xxxxxx):hover{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"immediate child universal\",\n\t\t\tsource: \".class>*{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx)>:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"element + pseudo state\",\n\t\t\tsource: \".class button:focus{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx) button:where(.astro-xxxxxx):focus{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"element + pseudo element\",\n\t\t\tsource: \".class h3::before{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx) h3:where(.astro-xxxxxx)::before{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"media query\",\n\t\t\tsource: \"@media screen and (min-width:640px){.class{}}\",\n\t\t\twant:   \"@media screen and (min-width:640px){.class:where(.astro-xxxxxx){}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"element + pseudo state + pseudo element\",\n\t\t\tsource: \"button:focus::before{}\",\n\t\t\twant:   \"button:where(.astro-xxxxxx):focus::before{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global children\",\n\t\t\tsource: \".class :global(ul li){}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx) ul li{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global universal\",\n\t\t\tsource: \".class :global(*){}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx) *{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global with scoped children\",\n\t\t\tsource: \":global(section) .class{}\",\n\t\t\twant:   \"section .class:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"subsequent siblings + global\",\n\t\t\tsource: \".class~:global(a){}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx)~a{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global nested parens\",\n\t\t\tsource: \".class :global(.nav:not(.is-active)){}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx) .nav:not(.is-active){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global nested parens + chained class\",\n\t\t\tsource: \":global(body:not(.is-light)).is-dark,:global(body:not(.is-dark)).is-light{}\",\n\t\t\twant:   \"body:not(.is-light).is-dark,body:not(.is-dark).is-light{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global chaining global\",\n\t\t\tsource: \":global(.foo):global(.bar){}\",\n\t\t\twant:   \".foo.bar{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"class chained global\",\n\t\t\tsource: \".class:global(.bar){}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx).bar{}\", // technically this may be incorrect, but would require a lookahead to fix\n\t\t},\n\t\t{\n\t\t\tname:   \"chained :not()\",\n\t\t\tsource: \".class:not(.is-active):not(.is-disabled){}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx):not(.is-active):not(.is-disabled){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"weird chaining\",\n\t\t\tsource: \":hover.a:focus{}\", // yes this is valid. yes I’m just upset as you are :(\n\t\t\twant:   \":hover.a:where(.astro-xxxxxx):focus{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"more weird chaining\",\n\t\t\tsource: \":not(.is-disabled).a{}\",\n\t\t\twant:   \":not(.is-disabled).a:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"body\",\n\t\t\tsource: \"body h1{}\",\n\t\t\twant:   \"body h1:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"body class\",\n\t\t\tsource: \"body.theme-dark{}\",\n\t\t\twant:   \"body.theme-dark{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"html and body\",\n\t\t\tsource: \"html,body{}\",\n\t\t\twant:   \"html,body{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \":root\",\n\t\t\tsource: \":root{}\",\n\t\t\twant:   \":root{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"escaped characters\",\n\t\t\tsource: \".class\\\\:class:focus{}\",\n\t\t\twant:   \".class\\\\:class:where(.astro-xxxxxx):focus{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"only pseudo element\",\n\t\t\tsource: \".class>::before{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx)>:where(.astro-xxxxxx)::before{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"only pseudo class + pseudo element\",\n\t\t\tsource: \".class>:not(:first-child)::after{}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx)>:where(.astro-xxxxxx):not(:first-child)::after{}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nested only pseudo element\",\n\t\t\tsource: \".class{& .other_class{&::after{}}}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx){& .other_class:where(.astro-xxxxxx){&::after{}}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global with nesting pseudo class\",\n\t\t\tsource: \"div :global(.curve){&:last-of-type{transform:scaleY(-1)}}\",\n\t\t\twant:   \"div:where(.astro-xxxxxx) .curve{&:last-of-type{transform:scaleY(-1)}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global with nesting pseudo element\",\n\t\t\tsource: \"div :global(.icon){&::after{content:''}}\",\n\t\t\twant:   \"div:where(.astro-xxxxxx) .icon{&::after{content:\\\"\\\"}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"global with nesting multiple pseudo\",\n\t\t\tsource: \".wrap :global(.item){&:first-child:hover{color:red}}\",\n\t\t\twant:   \".wrap:where(.astro-xxxxxx) .item{&:first-child:hover{color:red}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nesting & with pseudo element\",\n\t\t\tsource: \".class{&::before{}}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx){&::before{}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nesting & with pseudo class\",\n\t\t\tsource: \".class{&:hover{}}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx){&:hover{}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nesting & with multiple pseudo classes\",\n\t\t\tsource: \".class{&:hover:focus{}}\",\n\t\t\twant:   \".class:where(.astro-xxxxxx){&:hover:focus{}}\",\n\t\t},\n\t\t// the following tests assert we leave valid CSS alone\n\t\t{\n\t\t\tname:   \"attributes\",\n\t\t\tsource: \"body{background-image:url('/assets/bg.jpg');clip-path:polygon(0% 0%,100% 0%,100% 100%,0% 100%);}\",\n\t\t\twant:   \"body{background-image:url(/assets/bg.jpg);clip-path:polygon(0% 0%,100% 0%,100% 100%,0% 100%)}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"variables\",\n\t\t\tsource: \"body{--bg:red;background:var(--bg);color:black;}\",\n\t\t\twant:   \"body{--bg:red;background:var(--bg);color:black}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"keyframes\",\n\t\t\tsource: \"@keyframes shuffle{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}\",\n\t\t\twant:   \"@keyframes shuffle{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"keyframes 2\",\n\t\t\tsource: \"@keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}}\",\n\t\t\twant:   \"@keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"keyframes start\",\n\t\t\tsource: \"@keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}} h1{} h2{}\",\n\t\t\twant:   \"@keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}}h1:where(.astro-xxxxxx){}h2:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"keyframes middle\",\n\t\t\tsource: \"h1{} @keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}} h2{}\",\n\t\t\twant:   \"h1:where(.astro-xxxxxx){}@keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}}h2:where(.astro-xxxxxx){}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"keyframes end\",\n\t\t\tsource: \"h1{} h2{} @keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}}\",\n\t\t\twant:   \"h1:where(.astro-xxxxxx){}h2:where(.astro-xxxxxx){}@keyframes shuffle{0%{transform:rotate(0deg);color:blue}100%{transform:rotate(360deg)}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"calc\",\n\t\t\tsource: \":root{padding:calc(var(--space) * 2);}\",\n\t\t\twant:   \":root{padding:calc(var(--space) * 2)}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"grid-template-columns\",\n\t\t\tsource: \"div{grid-template-columns: [content-start] 1fr [content-end];}\",\n\t\t\twant:   \"div:where(.astro-xxxxxx){grid-template-columns:[content-start] 1fr [content-end]}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"charset\",\n\t\t\tsource: \"@charset \\\"utf-8\\\";\",\n\t\t\twant:   \"@charset \\\"utf-8\\\";\",\n\t\t},\n\t\t{\n\t\t\tname:   \"import (plain)\",\n\t\t\tsource: \"@import \\\"./my-file.css\\\";\",\n\t\t\twant:   \"@import\\\"./my-file.css\\\";\",\n\t\t},\n\t\t{\n\t\t\tname:   \"import (url)\",\n\t\t\tsource: \"@import url(\\\"./my-file.css\\\");\",\n\t\t\twant:   \"@import\\\"./my-file.css\\\";\",\n\t\t},\n\t\t{\n\t\t\tname:   \"valid CSS, madeup syntax\",\n\t\t\tsource: \"@tailwind base;\",\n\t\t\twant:   \"@tailwind base;\",\n\t\t},\n\t\t{\n\t\t\tname: \"invalid CSS (`missing semi`)\",\n\t\t\tsource: `.foo {\n  color: blue\n  font-size: 18px;\n}`,\n\t\t\twant: `.foo:where(.astro-xxxxxx){color:blue font-size: 18px}`,\n\t\t},\n\t\t{\n\t\t\tname:   \"nesting media\",\n\t\t\tsource: \":global(html) { @media (min-width: 640px) { color: blue } }html { background-color: lime }\",\n\t\t\twant:   \"html{@media (min-width: 640px){color:blue}}html{background-color:lime}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nesting combinator\",\n\t\t\tsource: \"div { & span { color: blue } }\",\n\t\t\twant:   \"div:where(.astro-xxxxxx){& span:where(.astro-xxxxxx){color:blue}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nesting modifier\",\n\t\t\tsource: \".header { background-color: white; &.dark { background-color: blue; }}\",\n\t\t\twant:   \".header:where(.astro-xxxxxx){background-color:white;&.dark{background-color:blue}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nesting without ampersand\",\n\t\t\tsource: \".nesting-root{p{color:#123456}:global(h1){color:#abcdef}}\",\n\t\t\twant:   \".nesting-root:where(.astro-xxxxxx){p{color:#123456}h1{color:#abcdef}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"nested descendant selector should stay unscoped\",\n\t\t\tsource: \"nav{a{color:deeppink}}\",\n\t\t\twant:   \"nav:where(.astro-xxxxxx){a{color:deeppink}}\",\n\t\t},\n\t\t{\n\t\t\tname: \"@container\",\n\t\t\tsource: `@container (min-width: 200px) and (min-height: 200px) {\n        h1 {\n          font-size: 30px;\n        }\n      }`,\n\t\t\twant: \"@container (min-width: 200px) and (min-height: 200px){h1:where(.astro-xxxxxx){font-size:30px}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"@layer\",\n\t\t\tsource: \"@layer theme, layout, utilities; @layer special { .item { color: rebeccapurple; }}\",\n\t\t\twant:   \"@layer theme,layout,utilities;@layer special{.item:where(.astro-xxxxxx){color:rebeccapurple}}\",\n\t\t},\n\t\t{\n\t\t\tname:   \"@starting-style\",\n\t\t\tsource: \"@starting-style{.class{}}\",\n\t\t\twant:   \"@starting-style{.class:where(.astro-xxxxxx){}}\",\n\t\t},\n\t}\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\t// note: the \"{}\" is only added to make it valid CSS\n\t\t\tcode := test_utils.Dedent(\"<style>\\n\" + tt.source + \" \\n</style>\")\n\t\t\tdoc, err := astro.Parse(strings.NewReader(code))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tstyleEl := doc.LastChild.FirstChild.FirstChild // note: root is <html>, and we need to get <style> which lives in head\n\t\t\tstyles := []*astro.Node{styleEl}\n\t\t\tScopeStyle(styles, TransformOptions{Scope: \"xxxxxx\"})\n\t\t\tgot := styles[0].FirstChild.Data\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/transform/scope-html.go",
    "content": "package transform\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"golang.org/x/net/html/atom\"\n)\n\nfunc ScopeElement(n *astro.Node, opts TransformOptions) {\n\tif n.Type == astro.ElementNode {\n\t\tif _, noScope := NeverScopedElements[n.Data]; !noScope {\n\t\t\tinjectScopedClass(n, opts)\n\t\t}\n\t}\n}\n\nfunc AddDefineVars(n *astro.Node, values []string) bool {\n\tif n.Type == astro.ElementNode && !n.Component {\n\t\tif _, noScope := NeverScopedElements[n.Data]; !noScope {\n\t\t\tif !IsImplicitNode(n) {\n\t\t\t\tinjectDefineVars(n, values)\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc AnnotateElement(n *astro.Node, opts TransformOptions) {\n\tif n.Type == astro.ElementNode && !n.Component && !n.Fragment {\n\t\tif _, noScope := NeverScopedElements[n.Data]; !noScope {\n\t\t\tannotateElement(n, opts)\n\t\t}\n\t}\n}\n\nvar NeverScopedElements map[string]bool = map[string]bool{\n\t\"Fragment\": true,\n\t\"base\":     true,\n\t\"font\":     true,\n\t\"frame\":    true,\n\t\"frameset\": true,\n\t\"head\":     true,\n\t\"link\":     true,\n\t\"meta\":     true,\n\t\"noframes\": true,\n\t\"noscript\": true,\n\t\"script\":   true,\n\t\"style\":    true,\n\t\"slot\":     true,\n\t\"title\":    true,\n}\n\nvar NeverScopedSelectors map[string]bool = map[string]bool{\n\t\":root\": true,\n}\n\nfunc annotateElement(n *astro.Node, opts TransformOptions) {\n\tif n.DataAtom == atom.Html {\n\t\treturn\n\t}\n\tn.Attr = append(n.Attr, astro.Attribute{\n\t\tKey:  \"data-astro-source-file\",\n\t\tType: astro.QuotedAttribute,\n\t\tVal:  opts.Filename,\n\t})\n}\n\nfunc injectDefineVars(n *astro.Node, values []string) {\n\tdefinedVars := \"$$definedVars\"\n\tfor i, attr := range n.Attr {\n\t\tif attr.Key == \"style\" {\n\t\t\tswitch attr.Type {\n\t\t\tcase astro.ShorthandAttribute:\n\t\t\t\tattr.Type = astro.ExpressionAttribute\n\t\t\t\tattr.Val = fmt.Sprintf(\"`${%s}; ${%s}`\", attr.Key, definedVars)\n\t\t\t\tn.Attr[i] = attr\n\t\t\t\treturn\n\t\t\tcase astro.EmptyAttribute:\n\t\t\t\tattr.Type = astro.ExpressionAttribute\n\t\t\t\tattr.Val = definedVars\n\t\t\t\tn.Attr[i] = attr\n\t\t\t\treturn\n\t\t\tcase astro.QuotedAttribute:\n\t\t\t\tattr.Type = astro.ExpressionAttribute\n\t\t\t\tattr.Val = fmt.Sprintf(\"`${\\\"%s\\\"}; ${%s}`\", attr.Val, definedVars)\n\t\t\t\tn.Attr[i] = attr\n\t\t\t\treturn\n\t\t\tcase astro.TemplateLiteralAttribute:\n\t\t\t\tattr.Type = astro.ExpressionAttribute\n\t\t\t\tattr.Val = fmt.Sprintf(\"`${`%s`}; ${%s}`\", attr.Val, definedVars)\n\t\t\t\tn.Attr[i] = attr\n\t\t\t\treturn\n\t\t\tcase astro.ExpressionAttribute:\n\t\t\t\tattr.Type = astro.ExpressionAttribute\n\t\t\t\ttrimmed := strings.TrimSpace(attr.Val)\n\t\t\t\tif trimmed[0] == '{' {\n\t\t\t\t\tattr.Val = fmt.Sprintf(\"[%s,%s]\", trimmed, definedVars)\n\t\t\t\t} else {\n\t\t\t\t\tattr.Val = fmt.Sprintf(\"`${%s}; ${%s}`\", attr.Val, definedVars)\n\t\t\t\t}\n\t\t\t\tn.Attr[i] = attr\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\tn.Attr = append(n.Attr, astro.Attribute{\n\t\tKey:  \"style\",\n\t\tType: astro.ExpressionAttribute,\n\t\tVal:  definedVars,\n\t})\n}\n\nfunc injectScopedClass(n *astro.Node, opts TransformOptions) {\n\thasSpreadAttr := false\n\tif opts.ScopedStyleStrategy != \"attribute\" {\n\t\tscopedClass := fmt.Sprintf(`astro-%s`, opts.Scope)\n\n\t\tfor i, attr := range n.Attr {\n\t\t\tif !hasSpreadAttr && attr.Type == astro.SpreadAttribute {\n\t\t\t\t// We only handle this special case on built-in elements\n\t\t\t\thasSpreadAttr = !n.Component\n\t\t\t}\n\n\t\t\t// If we find an existing class attribute, append the scoped class\n\t\t\tif attr.Key == \"class\" || (n.Component && attr.Key == \"className\") {\n\t\t\t\tswitch attr.Type {\n\t\t\t\tcase astro.ShorthandAttribute:\n\t\t\t\t\tif n.Component {\n\t\t\t\t\t\tattr.Val = fmt.Sprintf(`%s + \" %s\"`, attr.Key, scopedClass)\n\t\t\t\t\t\tattr.Type = astro.ExpressionAttribute\n\t\t\t\t\t\tn.Attr[i] = attr\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\tcase astro.EmptyAttribute:\n\t\t\t\t\t// instead of an empty string\n\t\t\t\t\tattr.Type = astro.QuotedAttribute\n\t\t\t\t\tattr.Val = scopedClass\n\t\t\t\t\tn.Attr[i] = attr\n\t\t\t\t\treturn\n\t\t\t\tcase astro.QuotedAttribute, astro.TemplateLiteralAttribute:\n\t\t\t\t\t// as a plain string\n\t\t\t\t\tattr.Val = fmt.Sprintf(`%s %s`, attr.Val, scopedClass)\n\t\t\t\t\tn.Attr[i] = attr\n\t\t\t\t\treturn\n\t\t\t\tcase astro.ExpressionAttribute:\n\t\t\t\t\t// as an expression\n\t\t\t\t\tattr.Val = fmt.Sprintf(`((%s) ?? \"\") + \" %s\"`, attr.Val, scopedClass)\n\t\t\t\t\tn.Attr[i] = attr\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif attr.Key == \"class:list\" {\n\t\t\t\tswitch attr.Type {\n\t\t\t\tcase astro.EmptyAttribute:\n\t\t\t\t\t// instead of an empty string\n\t\t\t\t\tattr.Type = astro.QuotedAttribute\n\t\t\t\t\tattr.Val = \"astro-\" + opts.Scope\n\t\t\t\t\tn.Attr[i] = attr\n\t\t\t\t\treturn\n\t\t\t\tcase astro.QuotedAttribute, astro.TemplateLiteralAttribute:\n\t\t\t\t\t// as a plain string\n\t\t\t\t\tattr.Val = attr.Val + \" astro-\" + opts.Scope\n\t\t\t\t\tn.Attr[i] = attr\n\t\t\t\t\treturn\n\t\t\t\tcase astro.ExpressionAttribute:\n\t\t\t\t\t// as an expression\n\t\t\t\t\tattr.Val = fmt.Sprintf(`[(%s), \"%s\"]`, attr.Val, scopedClass)\n\t\t\t\t\tn.Attr[i] = attr\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If there's a spread attribute, `class` might be there, so do not inject `class` here\n\t\t// `class` will be injected by the `spreadAttributes` helper\n\t\tif hasSpreadAttr {\n\t\t\treturn\n\t\t}\n\t\t// If we didn't find an existing class attribute, let's add one\n\t\tn.Attr = append(n.Attr, astro.Attribute{\n\t\t\tKey:  \"class\",\n\t\t\tType: astro.QuotedAttribute,\n\t\t\tVal:  scopedClass,\n\t\t})\n\t} else {\n\t\tn.Attr = append(n.Attr, astro.Attribute{\n\t\t\tKey:  fmt.Sprintf(`data-astro-cid-%s`, opts.Scope),\n\t\t\tType: astro.EmptyAttribute,\n\t\t})\n\t}\n\n}\n"
  },
  {
    "path": "internal/transform/scope-html_test.go",
    "content": "package transform\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\t\"unicode/utf8\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"golang.org/x/net/html/atom\"\n)\n\nfunc tests() []struct {\n\tname   string\n\tsource string\n\twant   string\n} {\n\treturn []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname:   \"none\",\n\t\t\tsource: \"<div />\",\n\t\t\twant:   `<div class=\"astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"quoted\",\n\t\t\tsource: `<div class=\"test\" />`,\n\t\t\twant:   `<div class=\"test astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"quoted no trim\",\n\t\t\tsource: `<div class=\"test \" />`,\n\t\t\twant:   `<div class=\"test  astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"expression string\",\n\t\t\tsource: `<div class={\"test\"} />`,\n\t\t\twant:   `<div class={((\"test\") ?? \"\") + \" astro-xxxxxx\"}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"expression function\",\n\t\t\tsource: `<div class={clsx({ [test]: true })} />`,\n\t\t\twant:   `<div class={((clsx({ [test]: true })) ?? \"\") + \" astro-xxxxxx\"}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"expression dynamic\",\n\t\t\tsource: \"<div class={condition ? 'a' : 'b'} />\",\n\t\t\twant:   `<div class={((condition ? 'a' : 'b') ?? \"\") + \" astro-xxxxxx\"}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"empty\",\n\t\t\tsource: \"<div class />\",\n\t\t\twant:   `<div class=\"astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"template literal\",\n\t\t\tsource: \"<div class=`${value}` />\",\n\t\t\twant:   \"<div class=`${value} astro-xxxxxx`></div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"component className not scoped\",\n\t\t\tsource: `<Component className=\"test\" />`,\n\t\t\twant:   `<Component className=\"test astro-xxxxxx\"></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"component className expression\",\n\t\t\tsource: `<Component className={\"test\"} />`,\n\t\t\twant:   `<Component className={((\"test\") ?? \"\") + \" astro-xxxxxx\"}></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"component className shorthand\",\n\t\t\tsource: \"<Component {className} />\",\n\t\t\twant:   `<Component className={className + \" astro-xxxxxx\"}></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"element class:list\",\n\t\t\tsource: \"<div class:list={{ a: true }} />\",\n\t\t\twant:   `<div class:list={[({ a: true }), \"astro-xxxxxx\"]}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"element class:list string\",\n\t\t\tsource: \"<div class:list=\\\"weird but ok\\\" />\",\n\t\t\twant:   `<div class:list=\"weird but ok astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"component class:list\",\n\t\t\tsource: \"<Component class:list={{ a: true }} />\",\n\t\t\twant:   `<Component class:list={[({ a: true }), \"astro-xxxxxx\"]}></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"fault input currently accepted\",\n\t\t\tsource: `<A { 0>`,\n\t\t\twant:   `<A  0>={0>} class=\"astro-xxxxxx\"></A>`,\n\t\t},\n\t}\n\n}\n\nfunc TestScopeHTML(t *testing.T) {\n\ttests := tests()\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\th := handler.NewHandler(tt.source, \"TestScopeHTML.astro\")\n\t\t\tnodes, err := astro.ParseFragmentWithOptions(strings.NewReader(tt.source), &astro.Node{Type: astro.ElementNode, DataAtom: atom.Body, Data: atom.Body.String()}, astro.ParseOptionWithHandler(h))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tScopeElement(nodes[0], TransformOptions{Scope: \"xxxxxx\"})\n\t\t\tvar b strings.Builder\n\t\t\tastro.PrintToSource(&b, nodes[0])\n\t\t\tgot := b.String()\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\t\t\t// check whether another pass doesn't error\n\t\t\tnodes, err = astro.ParseFragmentWithOptions(strings.NewReader(tt.source), &astro.Node{Type: astro.ElementNode, DataAtom: atom.Body, Data: atom.Body.String()}, astro.ParseOptionWithHandler(h))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\n\t\t\tScopeElement(nodes[0], TransformOptions{Scope: \"xxxxxx\"})\n\t\t\tastro.PrintToSource(&b, nodes[0])\n\t\t})\n\t}\n\n}\n\nfunc FuzzScopeHTML(f *testing.F) {\n\ttests := tests()\n\tfor _, tt := range tests {\n\t\tf.Add(tt.source) // Use f.Add to provide a seed corpus\n\t}\n\tf.Fuzz(func(t *testing.T, source string) {\n\t\th := handler.NewHandler(source, \"FuzzScopeHTML.astro\")\n\t\tnodes, err := astro.ParseFragmentWithOptions(strings.NewReader(source), &astro.Node{Type: astro.ElementNode, DataAtom: atom.Body, Data: atom.Body.String()}, astro.ParseOptionWithHandler(h))\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\t// if the doc doesn't parse as an element node, we don't care\n\t\tif len(nodes) == 0 || nodes[0].Type != astro.ElementNode {\n\t\t\tt.Skip(nodes)\n\t\t}\n\t\tScopeElement(nodes[0], TransformOptions{Scope: \"xxxxxx\"})\n\t\t// nodes[0] should still be an element node\n\t\tif len(nodes) == 0 || nodes[0].Type != astro.ElementNode {\n\t\t\tt.Errorf(\"`nodes[0]` is not an element node: %q\\n nodes[0].Type: %q\", source, nodes[0].Type)\n\t\t}\n\t\tvar b strings.Builder\n\t\tastro.PrintToSource(&b, nodes[0])\n\t\tgot := b.String()\n\t\tif !strings.Contains(got, \"astro-xxxxxx\") {\n\t\t\tt.Errorf(\"HTML scoping failed to include the astro scope\\n source: %q\\n got: %q\\n `nodes[0].Data: %q\", source, got, nodes[0].Data)\n\t\t}\n\t\tif utf8.ValidString(source) && !utf8.ValidString(got) {\n\t\t\tt.Errorf(\"HTML scoping produced invalid html string: %q\", got)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "internal/transform/transform.go",
    "content": "package transform\n\nimport (\n\t\"fmt\"\n\t\"path/filepath\"\n\t\"strings\"\n\t\"unicode\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n\t\"github.com/withastro/compiler/internal/js_scanner\"\n\t\"github.com/withastro/compiler/internal/loc\"\n\ta \"golang.org/x/net/html/atom\"\n)\n\nconst TRANSITION_ANIMATE = \"transition:animate\"\nconst TRANSITION_NAME = \"transition:name\"\nconst TRANSITION_PERSIST = \"transition:persist\"\nconst DATA_ASTRO_RELOAD = \"data-astro-reload\"\nconst TRANSITION_PERSIST_PROPS = \"transition:persist-props\"\nconst SERVER_DEFER = \"server:defer\"\n\ntype TransformOptions struct {\n\tScope                   string\n\tFilename                string\n\tNormalizedFilename      string\n\tInternalURL             string\n\tSourceMap               string\n\tAstroGlobalArgs         string\n\tScopedStyleStrategy     string\n\tCompact                 bool\n\tResultScopedSlot        bool\n\tTransitionsAnimationURL string\n\tResolvePath             func(string) string\n\tPreprocessStyle         interface{}\n\tAnnotateSourceFile      bool\n}\n\nfunc Transform(doc *astro.Node, opts TransformOptions, h *handler.Handler) *astro.Node {\n\tshouldScope := len(doc.Styles) > 0 && ScopeStyle(doc.Styles, opts)\n\tdefinedVars := GetDefineVars(doc.Styles)\n\tdidAddDefinedVars := false\n\ti := 0\n\twalk(doc, func(n *astro.Node) {\n\t\ti++\n\t\tWarnAboutRerunOnExternalESMs(n, h)\n\t\tWarnAboutMisplacedReload(n, h)\n\t\tHintAboutImplicitInlineDirective(n, h)\n\t\tExtractScript(doc, n, &opts, h)\n\t\tAddComponentProps(doc, n, &opts)\n\t\tif shouldScope {\n\t\t\tScopeElement(n, opts)\n\t\t}\n\t\tif HasAttr(n, TRANSITION_ANIMATE) || HasAttr(n, TRANSITION_NAME) || HasAttr(n, TRANSITION_PERSIST) {\n\t\t\tdoc.Transition = true\n\t\t\tdoc.HeadPropagation = true\n\t\t\tgetOrCreateTransitionScope(n, &opts, i)\n\t\t}\n\t\tif HasAttr(n, SERVER_DEFER) {\n\t\t\tdoc.HeadPropagation = true\n\t\t}\n\t\tif len(definedVars) > 0 {\n\t\t\tdidAdd := AddDefineVars(n, definedVars)\n\t\t\tif !didAddDefinedVars {\n\t\t\t\tdidAddDefinedVars = didAdd\n\t\t\t}\n\t\t}\n\t\tmergeClassList(doc, n, &opts)\n\t\tif n.DataAtom == a.Head && !IsImplicitNode(n) {\n\t\t\tdoc.ContainsHead = true\n\t\t}\n\t\tif opts.AnnotateSourceFile {\n\t\t\tAnnotateElement(n, opts)\n\t\t}\n\t})\n\tif len(definedVars) > 0 && !didAddDefinedVars {\n\t\tfor _, style := range doc.Styles {\n\t\t\tfor _, a := range style.Attr {\n\t\t\t\tif a.Key == \"define:vars\" {\n\t\t\t\t\th.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode:  loc.WARNING_CANNOT_DEFINE_VARS,\n\t\t\t\t\t\tText:  \"Unable to inject `define:vars` declaration\",\n\t\t\t\t\t\tRange: loc.Range{Loc: a.KeyLoc, Len: len(\"define:vars\")},\n\t\t\t\t\t\tHint:  \"Try wrapping this component in an element so that Astro can inject a \\\"style\\\" attribute.\",\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tNormalizeSetDirectives(doc, h)\n\n\t// If we've emptied out all the nodes, this was a Fragment that only contained hoisted elements\n\t// Add an empty FrontmatterNode to allow the empty component to be printed\n\tif doc.FirstChild == nil {\n\t\tempty := &astro.Node{\n\t\t\tType: astro.FrontmatterNode,\n\t\t}\n\t\tempty.AppendChild(&astro.Node{\n\t\t\tType: astro.TextNode,\n\t\t\tData: \"\",\n\t\t})\n\t\tdoc.AppendChild(empty)\n\t}\n\n\tTrimTrailingSpace(doc)\n\n\tif opts.Compact {\n\t\tcollapseWhitespace(doc)\n\t}\n\n\treturn doc\n}\n\nfunc ExtractStyles(doc *astro.Node, opts *TransformOptions) {\n\twalk(doc, func(n *astro.Node) {\n\t\tif n.Type == astro.ElementNode && n.DataAtom == a.Style {\n\t\t\tif HasSetDirective(n) || HasInlineDirective(n) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// Ignore styles in svg/noscript/etc\n\t\t\tif !IsHoistable(n, false) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\t// append node to maintain authored order\n\t\t\tdoc.Styles = append(doc.Styles, n)\n\t\t}\n\t})\n\t// Important! Remove styles from original location *after* walking the doc\n\tfor _, style := range doc.Styles {\n\t\tremoveNodeWithTrailingWhitespace(style)\n\t}\n}\n\n// removeNodeWithTrailingWhitespace removes a node and also removes any preceding\n// whitespace-only text node if it would become trailing whitespace after removal.\n// This prevents orphaned whitespace when extracting style/script tags.\nfunc removeNodeWithTrailingWhitespace(n *astro.Node) {\n\tprev := n.PrevSibling\n\tnext := n.NextSibling\n\n\t// Check if we should remove preceding whitespace:\n\t// 1. There is a previous sibling\n\t// 2. It's a whitespace-only text node\n\t// 3. After removing n, this whitespace would be trailing (no more non-whitespace siblings after)\n\tif prev != nil && prev.Type == astro.TextNode && strings.TrimSpace(prev.Data) == \"\" {\n\t\t// Check if there are any non-whitespace siblings after n\n\t\thasNonWhitespaceAfter := false\n\t\tfor sib := next; sib != nil; sib = sib.NextSibling {\n\t\t\tif sib.Type != astro.TextNode || strings.TrimSpace(sib.Data) != \"\" {\n\t\t\t\thasNonWhitespaceAfter = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\t// If no non-whitespace content follows, remove the preceding whitespace\n\t\tif !hasNonWhitespaceAfter {\n\t\t\tprev.Parent.RemoveChild(prev)\n\t\t}\n\t}\n\n\tn.Parent.RemoveChild(n)\n}\n\nfunc NormalizeSetDirectives(doc *astro.Node, h *handler.Handler) {\n\tvar nodes []*astro.Node\n\tvar directives []*astro.Attribute\n\twalk(doc, func(n *astro.Node) {\n\t\tif n.Type == astro.ElementNode && HasSetDirective(n) {\n\t\t\tfor _, attr := range n.Attr {\n\t\t\t\tif attr.Key == \"set:html\" || attr.Key == \"set:text\" {\n\t\t\t\t\tnodes = append(nodes, n)\n\t\t\t\t\tdirectives = append(directives, &attr)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n\n\tif len(nodes) > 0 {\n\t\tfor i, n := range nodes {\n\t\t\tdirective := directives[i]\n\t\t\tn.RemoveAttribute(directive.Key)\n\n\t\t\tvar nodeToAppend *astro.Node\n\t\t\tvar shouldWrapInQuotes,\n\t\t\t\tisTemplateLiteralAttribute,\n\t\t\t\tisQuotedAttribute,\n\t\t\t\tisExpressionAttribute,\n\t\t\t\tshouldWrapInTemplateLiteral,\n\t\t\t\tshouldAddExpression bool\n\n\t\t\tswitch directive.Type {\n\t\t\tcase astro.QuotedAttribute:\n\t\t\t\tisQuotedAttribute = true\n\t\t\tcase astro.TemplateLiteralAttribute:\n\t\t\t\tisTemplateLiteralAttribute = true\n\t\t\tcase astro.ExpressionAttribute:\n\t\t\t\tisExpressionAttribute = true\n\t\t\t}\n\n\t\t\tif directive.Key == \"set:html\" && isQuotedAttribute {\n\t\t\t\tshouldWrapInQuotes = true\n\t\t\t}\n\t\t\tif isTemplateLiteralAttribute {\n\t\t\t\tshouldWrapInTemplateLiteral = true\n\t\t\t}\n\t\t\tif directive.Key == \"set:html\" || (directive.Key == \"set:text\" && isTemplateLiteralAttribute) || isExpressionAttribute {\n\t\t\t\tshouldAddExpression = true\n\t\t\t}\n\n\t\t\tl := make([]loc.Loc, 1)\n\t\t\tl = append(l, directive.ValLoc)\n\t\t\tdata := directive.Val\n\n\t\t\tif shouldWrapInQuotes {\n\t\t\t\tdata = fmt.Sprintf(\"\\\"%s\\\"\", data)\n\t\t\t}\n\n\t\t\tif shouldWrapInTemplateLiteral {\n\t\t\t\tdata = fmt.Sprintf(\"`%s`\", data)\n\t\t\t}\n\n\t\t\tif directive.Key == \"set:html\" && isExpressionAttribute {\n\t\t\t\tdata = fmt.Sprintf(\"$$unescapeHTML(%s)\", data)\n\t\t\t}\n\t\t\tif shouldAddExpression {\n\t\t\t\tnodeToAppend = &astro.Node{\n\t\t\t\t\tType:       astro.ElementNode,\n\t\t\t\t\tData:       \"astro:expression\",\n\t\t\t\t\tExpression: true,\n\t\t\t\t}\n\t\t\t\tnodeToAppend.AppendChild(&astro.Node{\n\t\t\t\t\tType: astro.TextNode,\n\t\t\t\t\tData: data,\n\t\t\t\t\tLoc:  l,\n\t\t\t\t})\n\t\t\t} else {\n\t\t\t\tnodeToAppend = &astro.Node{\n\t\t\t\t\tType: astro.TextNode,\n\t\t\t\t\tData: data,\n\t\t\t\t\tLoc:  l,\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tshouldWarn := false\n\t\t\t// Remove all existing children\n\t\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\t\tif !shouldWarn {\n\t\t\t\t\tshouldWarn = c.Type == astro.CommentNode || (c.Type == astro.TextNode && len(strings.TrimSpace(c.Data)) != 0)\n\t\t\t\t}\n\t\t\t\tn.RemoveChild(c)\n\t\t\t}\n\t\t\tif shouldWarn {\n\t\t\t\th.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\t\tCode:  loc.WARNING_SET_WITH_CHILDREN,\n\t\t\t\t\tText:  fmt.Sprintf(\"%s directive will overwrite child nodes.\", directive.Key),\n\t\t\t\t\tRange: loc.Range{Loc: directive.KeyLoc, Len: len(directive.Key)},\n\t\t\t\t\tHint:  \"Remove the child nodes to suppress this warning.\",\n\t\t\t\t})\n\t\t\t}\n\t\t\tn.AppendChild(nodeToAppend)\n\t\t}\n\t}\n}\n\nfunc TrimTrailingSpace(doc *astro.Node) {\n\tif doc.LastChild == nil {\n\t\treturn\n\t}\n\n\tif doc.LastChild.Type == astro.TextNode {\n\t\tdoc.LastChild.Data = strings.TrimRightFunc(doc.LastChild.Data, unicode.IsSpace)\n\t\treturn\n\t}\n\n\tn := doc.LastChild\n\tfor i := 0; i < 2; i++ {\n\t\t// Loop through implicit nodes to find final trailing text node (html > body > #text)\n\t\tif n != nil && n.Type == astro.ElementNode && IsImplicitNode(n) {\n\t\t\tn = n.LastChild\n\t\t\tcontinue\n\t\t} else {\n\t\t\tn = nil\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Collapse all trailing text nodes\n\tfor n != nil && n.Type == astro.TextNode {\n\t\tn.Data = strings.TrimRightFunc(n.Data, unicode.IsSpace)\n\t\tn = n.PrevSibling\n\t}\n}\n\nfunc isRawElement(n *astro.Node) bool {\n\tif n.Type == astro.FrontmatterNode {\n\t\treturn true\n\t}\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == \"is:raw\" {\n\t\t\treturn true\n\t\t}\n\t}\n\trawTags := []string{\"pre\", \"listing\", \"iframe\", \"noembed\", \"noframes\", \"math\", \"plaintext\", \"script\", \"style\", \"textarea\", \"title\", \"xmp\"}\n\tfor _, tag := range rawTags {\n\t\tif n.Data == tag {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc isWhitespaceInsensitiveElement(n *astro.Node) bool {\n\treturn n.Data == \"head\"\n}\n\nfunc collapseWhitespace(doc *astro.Node) {\n\twalk(doc, func(n *astro.Node) {\n\t\tif n.Type == astro.TextNode {\n\t\t\t// Don't trim any whitespace if the node or any of its ancestors is raw\n\t\t\tif n.Closest(isRawElement) != nil {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Trim the whitespace on each end of top-level expressions\n\t\t\tif n.Parent != nil && n.Parent.Expression {\n\t\t\t\t// Trim left whitespace in the first child\n\t\t\t\tif n.PrevSibling == nil {\n\t\t\t\t\tn.Data = strings.TrimLeftFunc(n.Data, unicode.IsSpace)\n\t\t\t\t}\n\t\t\t\t// Trim right whitespace in the last child\n\t\t\t\tif n.NextSibling == nil {\n\t\t\t\t\tn.Data = strings.TrimRightFunc(n.Data, unicode.IsSpace)\n\t\t\t\t}\n\t\t\t\t// Don't trim any more!\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If the node is only whitespace, clear it\n\t\t\tif len(strings.TrimFunc(n.Data, unicode.IsSpace)) == 0 {\n\t\t\t\t// If it's a lone text node, or if it's within a whitespace-insensitive element, clear completely\n\t\t\t\tif (n.PrevSibling == nil && n.NextSibling == nil) || n.Closest(isWhitespaceInsensitiveElement) != nil {\n\t\t\t\t\tn.Data = \"\"\n\t\t\t\t} else {\n\t\t\t\t\tn.Data = \" \"\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Collapse left whitespace into a single space\n\t\t\toriginalLen := len(n.Data)\n\t\t\thasNewline := false\n\t\t\tn.Data = strings.TrimLeftFunc(n.Data, func(r rune) bool {\n\t\t\t\tif r == '\\n' {\n\t\t\t\t\thasNewline = true\n\t\t\t\t}\n\t\t\t\treturn unicode.IsSpace(r)\n\t\t\t})\n\t\t\tif originalLen != len(n.Data) {\n\t\t\t\tif hasNewline {\n\t\t\t\t\tn.Data = \"\\n\" + n.Data\n\t\t\t\t} else {\n\t\t\t\t\tn.Data = \" \" + n.Data\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Collapse right whitespace into a single space\n\t\t\toriginalLen = len(n.Data)\n\t\t\thasNewline = false\n\t\t\tn.Data = strings.TrimRightFunc(n.Data, func(r rune) bool {\n\t\t\t\tif r == '\\n' {\n\t\t\t\t\thasNewline = true\n\t\t\t\t}\n\t\t\t\treturn unicode.IsSpace(r)\n\t\t\t})\n\t\t\tif originalLen != len(n.Data) {\n\t\t\t\tif hasNewline {\n\t\t\t\t\tn.Data = n.Data + \"\\n\"\n\t\t\t\t} else {\n\t\t\t\t\tn.Data = n.Data + \" \"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc WarnAboutMisplacedReload(n *astro.Node, h *handler.Handler) {\n\tif HasAttr(n, DATA_ASTRO_RELOAD) {\n\t\tattr := &n.Attr[AttrIndex(n, DATA_ASTRO_RELOAD)]\n\n\t\t/*\n\t\t * When set on <a>, <form> or <area>,\n\t\t * the data-astro-reload attribute replaces view transitions between pages with a full page loads.\n\t\t */\n\n\t\tif n.Type != astro.ElementNode || n.Data != \"a\" && n.Data != \"area\" && n.Data != \"form\" {\n\t\t\th.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\tCode:  loc.WARNING,\n\t\t\t\tText:  \"The data-astro-reload attribute is only supported on <a>, <form> and <area> elements.\",\n\t\t\t\tRange: loc.Range{Loc: attr.KeyLoc, Len: len(attr.Key)},\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc WarnAboutRerunOnExternalESMs(n *astro.Node, h *handler.Handler) {\n\tif n.Data == \"script\" && HasAttr(n, \"src\") && HasAttr(n, \"type\") && HasAttr(n, \"data-astro-rerun\") {\n\n\t\t/*\n\t\t * The browser caches external ECMAScript Modules. Even if such a script is included several times on a page,\n\t\t * it will only run once. This means that the data-astro-rerun attribute will not have any effect.\n\t\t */\n\t\tsrc := &n.Attr[AttrIndex(n, \"src\")]\n\t\ttyp := &n.Attr[AttrIndex(n, \"type\")]\n\t\trerun := &n.Attr[AttrIndex(n, \"data-astro-rerun\")]\n\t\tif typ.Val == \"module\" && src.Val != \"\" {\n\t\t\th.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\tCode:  loc.WARNING_CANNOT_RERUN,\n\t\t\t\tText:  \"The data-astro-rerun attribute is not supported on an external module <script>\",\n\t\t\t\tHint:  \"Two out of three is OK: type=\\\"module\\\", src=\\\"...\\\", or data-astro-rerun\",\n\t\t\t\tRange: loc.Range{Loc: rerun.KeyLoc, Len: len(rerun.Key)},\n\t\t\t})\n\t\t}\n\t}\n}\n\nfunc ExtractScript(doc *astro.Node, n *astro.Node, opts *TransformOptions, h *handler.Handler) {\n\tif n.Type == astro.ElementNode && n.DataAtom == a.Script {\n\t\tif HasSetDirective(n) || HasInlineDirective(n) {\n\t\t\treturn\n\t\t}\n\t\t// Ignore scripts in svg/noscript/etc\n\t\tif !IsHoistable(n, true) {\n\t\t\treturn\n\t\t}\n\n\t\t// if <script>, hoist to the document root\n\t\t// If also using define:vars, that overrides the hoist tag.\n\t\tif (hasTruthyAttr(n, \"hoist\")) ||\n\t\t\tlen(n.Attr) == 0 || (len(n.Attr) == 1 && n.Attr[0].Key == \"src\") {\n\t\t\tshouldAdd := true\n\t\t\tfor _, attr := range n.Attr {\n\t\t\t\tif attr.Key == \"hoist\" {\n\t\t\t\t\th.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode:  loc.WARNING_DEPRECATED_DIRECTIVE,\n\t\t\t\t\t\tText:  \"<script hoist> is no longer needed. You may remove the `hoist` attribute.\",\n\t\t\t\t\t\tRange: loc.Range{Loc: n.Loc[0], Len: len(n.Data)},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t\tif attr.Key == \"src\" {\n\t\t\t\t\tif attr.Type == astro.ExpressionAttribute {\n\t\t\t\t\t\tshouldAdd = false\n\t\t\t\t\t\th.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\t\t\t\tCode:  loc.WARNING_UNSUPPORTED_EXPRESSION,\n\t\t\t\t\t\t\tText:  \"<script> uses an expression for the src attribute and will be ignored.\",\n\t\t\t\t\t\t\tHint:  fmt.Sprintf(\"Replace src={%s} with a string literal\", attr.Val),\n\t\t\t\t\t\t\tRange: loc.Range{Loc: n.Loc[0], Len: len(n.Data)},\n\t\t\t\t\t\t})\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// append node to maintain authored order\n\t\t\tif shouldAdd {\n\t\t\t\tdoc.Scripts = append(doc.Scripts, n)\n\t\t\t\tn.HandledScript = true\n\t\t\t}\n\t\t} else {\n\t\t\tfor _, attr := range n.Attr {\n\t\t\t\tif strings.HasPrefix(attr.Key, \"client:\") {\n\t\t\t\t\th.AppendWarning(&loc.ErrorWithRange{\n\t\t\t\t\t\tCode:  loc.WARNING_IGNORED_DIRECTIVE,\n\t\t\t\t\t\tText:  fmt.Sprintf(\"<script> does not need the %s directive and is always added as a module script.\", attr.Key),\n\t\t\t\t\t\tRange: loc.Range{Loc: n.Loc[0], Len: len(n.Data)},\n\t\t\t\t\t})\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc HintAboutImplicitInlineDirective(n *astro.Node, h *handler.Handler) {\n\tif n.Type == astro.ElementNode && n.DataAtom == a.Script && len(n.Attr) > 0 && !HasInlineDirective(n) {\n\t\tif len(n.Attr) == 1 && n.Attr[0].Key == \"src\" {\n\t\t\treturn\n\t\t}\n\t\th.AppendHint(&loc.ErrorWithRange{\n\t\t\tCode:  loc.HINT,\n\t\t\tText:  \"This script will be treated as if it has the `is:inline` directive because it contains an attribute. Therefore, features that require processing (e.g. using TypeScript or npm packages in the script) are unavailable.\\n\\nSee docs for more details: https://docs.astro.build/en/guides/client-side-scripts/#script-processing.\\n\\nAdd the `is:inline` directive explicitly to silence this hint.\",\n\t\t\tRange: loc.Range{Loc: n.Attr[0].KeyLoc, Len: len(n.Attr[0].Key)},\n\t\t})\n\t}\n}\n\nfunc AddComponentProps(doc *astro.Node, n *astro.Node, opts *TransformOptions) {\n\tif n.Type == astro.ElementNode && (n.Component || n.CustomElement) {\n\t\tfor _, attr := range n.Attr {\n\t\t\tif strings.HasPrefix(attr.Key, \"client:\") {\n\t\t\t\tparts := strings.Split(attr.Key, \":\")\n\t\t\t\tdirective := parts[1]\n\n\t\t\t\t// Add the hydration directive so it can be extracted statically.\n\t\t\t\tdoc.HydrationDirectives[directive] = true\n\n\t\t\t\thydrationAttr := astro.Attribute{\n\t\t\t\t\tKey: \"client:component-hydration\",\n\t\t\t\t\tVal: directive,\n\t\t\t\t}\n\t\t\t\tn.Attr = append(n.Attr, hydrationAttr)\n\n\t\t\t\tif attr.Key == \"client:only\" {\n\t\t\t\t\tdoc.ClientOnlyComponentNodes = append([]*astro.Node{n}, doc.ClientOnlyComponentNodes...)\n\n\t\t\t\t\tmatch := matchNodeToImportStatement(doc, n)\n\t\t\t\t\tif match != nil {\n\t\t\t\t\t\tdoc.ClientOnlyComponents = append(doc.ClientOnlyComponents, &astro.HydratedComponentMetadata{\n\t\t\t\t\t\t\tExportName:   match.ExportName,\n\t\t\t\t\t\t\tSpecifier:    match.Specifier,\n\t\t\t\t\t\t\tResolvedPath: ResolveIdForMatch(match.Specifier, opts),\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\t// prepend node to maintain authored order\n\t\t\t\tdoc.HydratedComponentNodes = append([]*astro.Node{n}, doc.HydratedComponentNodes...)\n\n\t\t\t\tmatch := matchNodeToImportStatement(doc, n)\n\t\t\t\tif match != nil {\n\t\t\t\t\tdoc.HydratedComponents = append(doc.HydratedComponents, &astro.HydratedComponentMetadata{\n\t\t\t\t\t\tExportName:   match.ExportName,\n\t\t\t\t\t\tSpecifier:    match.Specifier,\n\t\t\t\t\t\tResolvedPath: ResolveIdForMatch(match.Specifier, opts),\n\t\t\t\t\t})\n\n\t\t\t\t\tpathAttr := astro.Attribute{\n\t\t\t\t\t\tKey:  \"client:component-path\",\n\t\t\t\t\t\tVal:  fmt.Sprintf(`\"%s\"`, ResolveIdForMatch(match.Specifier, opts)),\n\t\t\t\t\t\tType: astro.ExpressionAttribute,\n\t\t\t\t\t}\n\t\t\t\t\tn.Attr = append(n.Attr, pathAttr)\n\n\t\t\t\t\texportAttr := astro.Attribute{\n\t\t\t\t\t\tKey:  \"client:component-export\",\n\t\t\t\t\t\tVal:  fmt.Sprintf(`\"%s\"`, match.ExportName),\n\t\t\t\t\t\tType: astro.ExpressionAttribute,\n\t\t\t\t\t}\n\t\t\t\t\tn.Attr = append(n.Attr, exportAttr)\n\t\t\t\t}\n\n\t\t\t\tbreak\n\t\t\t} else if strings.HasPrefix(attr.Key, \"server:\") {\n\t\t\t\tparts := strings.Split(attr.Key, \":\")\n\t\t\t\tdirective := parts[1]\n\n\t\t\t\thydrationAttr := astro.Attribute{\n\t\t\t\t\tKey: \"server:component-directive\",\n\t\t\t\t\tVal: directive,\n\t\t\t\t}\n\t\t\t\tn.Attr = append(n.Attr, hydrationAttr)\n\n\t\t\t\tmatch := matchNodeToImportStatement(doc, n)\n\t\t\t\tif match != nil {\n\t\t\t\t\tdoc.ServerComponents = append(doc.ServerComponents, &astro.HydratedComponentMetadata{\n\t\t\t\t\t\tExportName:   match.ExportName,\n\t\t\t\t\t\tLocalName:    n.Data,\n\t\t\t\t\t\tSpecifier:    match.Specifier,\n\t\t\t\t\t\tResolvedPath: ResolveIdForMatch(match.Specifier, opts),\n\t\t\t\t\t})\n\n\t\t\t\t\tpathAttr := astro.Attribute{\n\t\t\t\t\t\tKey:  \"server:component-path\",\n\t\t\t\t\t\tVal:  fmt.Sprintf(`\"%s\"`, ResolveIdForMatch(match.Specifier, opts)),\n\t\t\t\t\t\tType: astro.ExpressionAttribute,\n\t\t\t\t\t}\n\t\t\t\t\tn.Attr = append(n.Attr, pathAttr)\n\n\t\t\t\t\texportAttr := astro.Attribute{\n\t\t\t\t\t\tKey:  \"server:component-export\",\n\t\t\t\t\t\tVal:  fmt.Sprintf(`\"%s\"`, match.ExportName),\n\t\t\t\t\t\tType: astro.ExpressionAttribute,\n\t\t\t\t\t}\n\t\t\t\t\tn.Attr = append(n.Attr, exportAttr)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\ntype ImportMatch struct {\n\tExportName string\n\tSpecifier  string\n}\n\nfunc matchNodeToImportStatement(doc *astro.Node, n *astro.Node) *ImportMatch {\n\tvar match *ImportMatch\n\n\teachImportStatement(doc, func(stmt js_scanner.ImportStatement) bool {\n\t\tfor _, imported := range stmt.Imports {\n\t\t\texportName, isUsed := js_scanner.ExtractComponentExportName(n.Data, imported)\n\t\t\tif isUsed {\n\t\t\t\tmatch = &ImportMatch{\n\t\t\t\t\tExportName: exportName,\n\t\t\t\t\tSpecifier:  stmt.Specifier,\n\t\t\t\t}\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\n\t\treturn true\n\t})\n\treturn match\n}\n\nfunc ResolveIdForMatch(id string, opts *TransformOptions) string {\n\t// Try custom resolvePath if provided\n\tif opts.ResolvePath != nil {\n\t\treturn opts.ResolvePath(id)\n\t} else if opts.Filename != \"<stdin>\" && id[0] == '.' {\n\t\treturn filepath.Join(filepath.Dir(opts.Filename), id)\n\t} else {\n\t\treturn id\n\t}\n}\n\nfunc eachImportStatement(doc *astro.Node, cb func(stmt js_scanner.ImportStatement) bool) {\n\tif doc.FirstChild.Type == astro.FrontmatterNode && doc.FirstChild.FirstChild != nil {\n\t\tsource := []byte(doc.FirstChild.FirstChild.Data)\n\t\tloc, statement := js_scanner.NextImportStatement(source, 0)\n\t\tfor loc != -1 {\n\t\t\tif !cb(statement) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tloc, statement = js_scanner.NextImportStatement(source, loc)\n\t\t}\n\t}\n}\n\nfunc walk(doc *astro.Node, cb func(*astro.Node)) {\n\tvar f func(*astro.Node)\n\tf = func(n *astro.Node) {\n\t\tcb(n)\n\t\tfor c := n.FirstChild; c != nil; c = c.NextSibling {\n\t\t\tf(c)\n\t\t}\n\t}\n\tf(doc)\n}\n\n// This function merges the values of `class=\"\"` and `class:list=\"\"` in `class:list`\nfunc mergeClassList(doc *astro.Node, n *astro.Node, opts *TransformOptions) {\n\tvar classListAttrValue string\n\tvar classListAttrIndex int = -1\n\n\tvar classAttrType astro.AttributeType\n\tvar classAttrValue string\n\tvar classAttrIndex int = -1\n\n\tfor i, attr := range n.Attr {\n\t\tif attr.Key == \"class:list\" {\n\t\t\tclassListAttrValue = attr.Val\n\t\t\tclassListAttrIndex = i\n\t\t}\n\t\tif attr.Key == \"class\" {\n\t\t\tclassAttrType = attr.Type\n\t\t\tclassAttrValue = attr.Val\n\t\t\tclassAttrIndex = i\n\t\t}\n\t}\n\n\t// Check if both `class:list` and `class` attributes are present\n\tif classListAttrIndex >= 0 && classAttrIndex >= 0 {\n\t\t// Merge the `class` attribute value into `class:list`\n\t\tif classAttrType == astro.ExpressionAttribute {\n\t\t\t// If the `class` attribute is an expression, include it directly without surrounding quotes.\n\t\t\t// This respects the fact that expressions are evaluated dynamically and should not be treated as strings.\n\t\t\tn.Attr[classListAttrIndex].Val = fmt.Sprintf(\"[%s, %s]\", classAttrValue, classListAttrValue)\n\t\t} else {\n\t\t\t// If the `class` attribute is a static string, wrap it in quotes.\n\t\t\t// This ensures that static class names are treated as string values within the list.\n\t\t\tn.Attr[classListAttrIndex].Val = fmt.Sprintf(\"['%s', %s]\", classAttrValue, classListAttrValue)\n\t\t}\n\t\t// Now that the value of `class` is carried by `class:list`, we can remove the `class` node from the AST.\n\t\t// Doing so will allow us to generate valid HTML at runtime\n\t\tn.Attr = remove(n.Attr, classAttrIndex)\n\t}\n}\n\nfunc remove(slice []astro.Attribute, s int) []astro.Attribute {\n\treturn append(slice[:s], slice[s+1:]...)\n}\n\nfunc getOrCreateTransitionScope(n *astro.Node, opts *TransformOptions, i int) string {\n\tif n.TransitionScope != \"\" {\n\t\treturn n.TransitionScope\n\t}\n\tn.TransitionScope = astro.HashString(fmt.Sprintf(\"%s-%v\", opts.Scope, i))\n\treturn n.TransitionScope\n}\n"
  },
  {
    "path": "internal/transform/transform_test.go",
    "content": "package transform\n\nimport (\n\t\"regexp\"\n\t\"strings\"\n\t\"testing\"\n\t\"unicode/utf8\"\n\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n)\n\nfunc transformScopingFixtures() []struct {\n\tname       string\n\tsource     string\n\twant       string\n\tscopeStyle string // \"attribute\" | \"class\" | \"where\"\n} {\n\treturn []struct {\n\t\tname       string\n\t\tsource     string\n\t\twant       string\n\t\tscopeStyle string\n\t}{\n\t\t{\n\t\t\tname: \"basic\",\n\t\t\tsource: `\n\t\t\t\t<style>div { color: red }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div class=\"astro-xxxxxx\"></div>`,\n\t\t},\n\n\t\t{\n\t\t\tname: \"global empty\",\n\t\t\tsource: `\n\t\t\t\t<style is:global>div { color: red }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"global true\",\n\t\t\tsource: `\n\t\t\t\t<style is:global={true}>div { color: red }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"global string\",\n\t\t\tsource: `\n\t\t\t\t<style is:global=\"\">div { color: red }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"global string true\",\n\t\t\tsource: `\n\t\t\t\t<style is:global=\"true\">div { color: red }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"empty (space)\",\n\t\t\tsource: `\n\t\t\t\t<style>\n\n\t\t\t\t</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"empty (nil)\",\n\t\t\tsource: `\n\t\t\t\t<style></style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"empty (define:vars)\",\n\t\t\tsource: `\n\t\t\t\t<style define:vars={{ a }}></style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div class=\"astro-xxxxxx\" style={$$definedVars}></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"scoped multiple\",\n\t\t\tsource: `\n\t\t\t\t<style>div { color: red }</style>\n\t\t\t\t<style>div { color: green }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div class=\"astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"global multiple\",\n\t\t\tsource: `\n\t\t\t\t<style is:global>div { color: red }</style>\n\t\t\t\t<style is:global>div { color: green }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"mixed multiple\",\n\t\t\tsource: `\n\t\t\t\t<style>div { color: red }</style>\n\t\t\t\t<style is:global>div { color: green }</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div class=\"astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"multiple scoped :global\",\n\t\t\tsource: `\n\t\t\t\t<style>:global(test-2) {}</style>\n\t\t\t\t<style>:global(test-1) {}</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div class=\"astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"inline does not scope\",\n\t\t\tsource: `\n\t\t\t\t<style is:inline>div{}</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant: `<div></div>`,\n\t\t},\n\t\t{\n\t\t\tname: \"attribute -> creates a new data attribute\",\n\t\t\tsource: `\n\t\t\t\t<style>.class{}</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant:       `<div data-astro-cid-xxxxxx></div>`,\n\t\t\tscopeStyle: \"attribute\",\n\t\t},\n\t\t{\n\t\t\tname: \"attribute -> creates data attribute when there's a class\",\n\t\t\tsource: `\n\t\t\t\t<style>.font{}</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant:       `<div data-astro-cid-xxxxxx></div>`,\n\t\t\tscopeStyle: \"attribute\",\n\t\t},\n\t\t{\n\t\t\tname: \"attribute -> creates data attribute when there's a CSS class\",\n\t\t\tsource: `\n\t\t\t\t<style>.font{}</style>\n\t\t\t\t<div />\n\t\t\t`,\n\t\t\twant:       `<div data-astro-cid-xxxxxx></div>`,\n\t\t\tscopeStyle: \"attribute\",\n\t\t},\n\t\t{\n\t\t\tname: \"attribute -> creates data attribute when there's already a class attribute\",\n\t\t\tsource: `\n\t\t\t\t<style>.font{}</style>\n\t\t\t\t<div class=\"foo\" />\n\t\t\t`,\n\t\t\twant:       `<div class=\"foo\" data-astro-cid-xxxxxx></div>`,\n\t\t\tscopeStyle: \"attribute\",\n\t\t},\n\t}\n}\n\nfunc TestTransformScoping(t *testing.T) {\n\ttests := transformScopingFixtures()\n\tvar b strings.Builder\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tb.Reset()\n\t\t\tdoc, err := astro.Parse(strings.NewReader(tt.source))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tvar scopeStyle string\n\t\t\tif tt.scopeStyle == \"attribute\" {\n\t\t\t\tscopeStyle = \"attribute\"\n\t\t\t} else if tt.scopeStyle == \"class\" {\n\t\t\t\tscopeStyle = \"class\"\n\t\t\t} else {\n\t\t\t\tscopeStyle = \"where\"\n\t\t\t}\n\t\t\ttransformOptions := TransformOptions{Scope: \"xxxxxx\", ScopedStyleStrategy: scopeStyle}\n\t\t\tExtractStyles(doc, &transformOptions)\n\t\t\tTransform(doc, transformOptions, handler.NewHandler(tt.source, \"/test.astro\"))\n\t\t\tastro.PrintToSource(&b, doc.LastChild.FirstChild.NextSibling.FirstChild)\n\t\t\tgot := b.String()\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc FuzzTransformScoping(f *testing.F) {\n\ttests := transformScopingFixtures()\n\tfor _, tt := range tests {\n\t\tf.Add(tt.source) // Use f.Add to provide a seed corpus\n\t}\n\tf.Fuzz(func(t *testing.T, source string) {\n\t\tdoc, err := astro.Parse(strings.NewReader(source))\n\t\tif err != nil {\n\t\t\tt.Skip(\"Invalid parse, skipping rest of fuzz test\")\n\t\t}\n\t\ttransformOptions := TransformOptions{Scope: \"xxxxxx\"}\n\t\tExtractStyles(doc, &transformOptions)\n\t\tTransform(doc, transformOptions, handler.NewHandler(source, \"/test.astro\"))\n\t\tvar b strings.Builder\n\t\tastro.PrintToSource(&b, doc.LastChild.FirstChild.NextSibling.FirstChild)\n\t\tgot := b.String()\n\t\t// hacky - we only expect scoping for non global styles / non inline styles\n\t\ttestRegex := regexp.MustCompile(`is:global|:global\\(|is:inline|<style>\\s*</style>`)\n\t\tif !testRegex.MatchString(source) && !strings.Contains(got, \"astro-xxxxxx\") {\n\t\t\tt.Errorf(\"HTML scoping failed to include the astro scope\\n source: %q\\n got: %q\", source, got)\n\t\t}\n\t\tif utf8.ValidString(source) && !utf8.ValidString(got) {\n\t\t\tt.Errorf(\"HTML scoping produced invalid html string: %q\", got)\n\t\t}\n\t})\n}\n\nfunc TestFullTransform(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname:   \"top-level component with leading style\",\n\t\t\tsource: `<style>:root{}</style><Component><h1>Hello world</h1></Component>`,\n\t\t\twant:   `<Component><h1>Hello world</h1></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"top-level component with leading style body\",\n\t\t\tsource: `<style>:root{}</style><Component><div><h1>Hello world</h1></div></Component>`,\n\t\t\twant:   `<Component><div><h1>Hello world</h1></div></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"top-level component with trailing style\",\n\t\t\tsource: `<Component><h1>Hello world</h1></Component><style>:root{}</style>`,\n\t\t\twant:   `<Component><h1>Hello world</h1></Component>`,\n\t\t},\n\n\t\t{\n\t\t\tname:   \"Component before html I\",\n\t\t\tsource: `<Navigation /><html><body><h1>Astro</h1></body></html>`,\n\t\t\twant:   `<Navigation></Navigation><h1>Astro</h1>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Component before html II\",\n\t\t\tsource: `<MainHead title={title} description={description} /><html lang=\"en\"><body><slot /></body></html>`,\n\t\t\twant:   `<MainHead title={title} description={description}></MainHead><slot></slot>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"respects explicitly authored elements\",\n\t\t\tsource: `<html><Component /></html>`,\n\t\t\twant:   `<html><Component></Component></html>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"respects explicitly authored elements 2\",\n\t\t\tsource: `<head></head><Component />`,\n\t\t\twant:   `<head></head><Component></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"respects explicitly authored elements 3\",\n\t\t\tsource: `<body><Component /></body>`,\n\t\t\twant:   `<body><Component></Component></body>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"removes implicitly generated elements\",\n\t\t\tsource: `<Component />`,\n\t\t\twant:   `<Component></Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"works with nested components\",\n\t\t\tsource: `<style></style><A><div><B /></div></A>`,\n\t\t\twant:   `<A><div><B></B></div></A>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"does not remove trailing siblings\",\n\t\t\tsource: `<title>Title</title><span /><Component /><span />`,\n\t\t\twant:   `<title>Title</title><span></span><Component></Component><span></span>`,\n\t\t},\n\t}\n\tvar b strings.Builder\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tb.Reset()\n\t\t\tdoc, err := astro.Parse(strings.NewReader(tt.source))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\ttransformOptions := TransformOptions{}\n\t\t\tExtractStyles(doc, &transformOptions)\n\t\t\t// Clear doc.Styles to avoid scoping behavior, we're not testing that here\n\t\t\tdoc.Styles = make([]*astro.Node, 0)\n\t\t\tTransform(doc, transformOptions, handler.NewHandler(tt.source, \"/test.astro\"))\n\t\t\tastro.PrintToSource(&b, doc)\n\t\t\tgot := strings.TrimSpace(b.String())\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTransformTransitionAndHeadPropagationFlags(t *testing.T) {\n\ttests := []struct {\n\t\tname                string\n\t\tsource              string\n\t\twantTransition      bool\n\t\twantHeadPropagation bool\n\t}{\n\t\t{\n\t\t\tname:                \"server:defer only\",\n\t\t\tsource:              `<Component server:defer />`,\n\t\t\twantTransition:      false,\n\t\t\twantHeadPropagation: true,\n\t\t},\n\t\t{\n\t\t\tname:                \"transition directive\",\n\t\t\tsource:              `<div transition:animate=\"slide\"></div>`,\n\t\t\twantTransition:      true,\n\t\t\twantHeadPropagation: true,\n\t\t},\n\t\t{\n\t\t\tname:                \"transition:persist-props alone does not count as transition directive\",\n\t\t\tsource:              `<Component transition:persist-props=\"true\" />`,\n\t\t\twantTransition:      false,\n\t\t\twantHeadPropagation: false,\n\t\t},\n\t}\n\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tdoc, err := astro.Parse(strings.NewReader(tt.source))\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\n\t\t\ttransformOptions := TransformOptions{}\n\t\t\tExtractStyles(doc, &transformOptions)\n\t\t\tTransform(doc, transformOptions, handler.NewHandler(tt.source, \"/test.astro\"))\n\n\t\t\tif doc.Transition != tt.wantTransition {\n\t\t\t\tt.Fatalf(\"unexpected doc.Transition value: want %v, got %v\", tt.wantTransition, doc.Transition)\n\t\t\t}\n\t\t\tif doc.HeadPropagation != tt.wantHeadPropagation {\n\t\t\t\tt.Fatalf(\"unexpected doc.HeadPropagation value: want %v, got %v\", tt.wantHeadPropagation, doc.HeadPropagation)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestTransformTrailingSpace(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname:   \"component with trailing space\",\n\t\t\tsource: \"<h1>Hello world</h1>\\n\\n\\t \",\n\t\t\twant:   `<h1>Hello world</h1>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"component with no trailing space\",\n\t\t\tsource: \"<h1>Hello world</h1>\",\n\t\t\twant:   \"<h1>Hello world</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"component with leading and trailing space\",\n\t\t\tsource: \"<span/>\\n\\n\\t <h1>Hello world</h1>\\n\\n\\t \",\n\t\t\twant:   \"<span></span>\\n\\n\\t <h1>Hello world</h1>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"html with explicit space\",\n\t\t\tsource: \"<html><body>\\n\\n\\n</body></html>\",\n\t\t\twant:   \"<html><body>\\n\\n\\n</body></html>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"trailing whitespace before style is removed\",\n\t\t\tsource: \"<html><head></head><body><slot />\\n<style>div { color: red; }</style></body></html>\",\n\t\t\twant:   \"<html><head></head><body><slot></slot></body></html>\",\n\t\t},\n\t}\n\n\tvar b strings.Builder\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tb.Reset()\n\t\t\tdoc, err := astro.Parse(strings.NewReader(tt.source))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\ttransformOptions := TransformOptions{}\n\t\t\tExtractStyles(doc, &transformOptions)\n\t\t\t// Clear doc.Styles to avoid scoping behavior, we're not testing that here\n\t\t\tdoc.Styles = make([]*astro.Node, 0)\n\t\t\tTransform(doc, transformOptions, handler.NewHandler(tt.source, \"/test.astro\"))\n\t\t\tastro.PrintToSource(&b, doc)\n\t\t\tgot := b.String()\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestCompactTransform(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname:   \"trims whitespace\",\n\t\t\tsource: `<div>    Test     </div>`,\n\t\t\twant:   `<div> Test </div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"pre\",\n\t\t\tsource: `<pre>  Test  </pre>`,\n\t\t\twant:   `<pre>  Test  </pre>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"textarea\",\n\t\t\tsource: `<textarea>  Test  </textarea>`,\n\t\t\twant:   `<textarea>  Test  </textarea>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"deep pre\",\n\t\t\tsource: `<pre>  <div> Test </div>  </pre>`,\n\t\t\twant:   `<pre>  <div> Test </div>  </pre>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"remove whitespace only\",\n\t\t\tsource: `<head>  <script>console.log(\"test\")</script>  <head>`,\n\t\t\twant:   `<head><script>console.log(\"test\")</script></head>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"collapse surrounding whitespace\",\n\t\t\tsource: `<div>  COOL  </div>`,\n\t\t\twant:   `<div> COOL </div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"collapse only surrounding whitespace\",\n\t\t\tsource: `<div>  C O O L  </div>`,\n\t\t\twant:   `<div> C O O L </div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"collapse surrounding newlines\",\n\t\t\tsource: \"<div>\\n\\n\\tC O O L\\n\\n\\t</div>\",\n\t\t\twant:   \"<div>\\nC O O L\\n</div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"collapse in-between inline elements\",\n\t\t\tsource: \"<div>Click   <a>here</a> <span>space</span></div>\",\n\t\t\twant:   \"<div>Click <a>here</a> <span>space</span></div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"expression trim first\",\n\t\t\tsource: \"<div>{\\n() => {\\n\\t\\treturn <span />}}</div>\",\n\t\t\twant:   \"<div>{() => {\\n\\t\\treturn <span></span>}}</div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"expression trim last\",\n\t\t\tsource: \"<div>{() => {\\n\\t\\treturn <span />}\\n}</div>\",\n\t\t\twant:   \"<div>{() => {\\n\\t\\treturn <span></span>}}</div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"expression collapse inside\",\n\t\t\tsource: \"<div>{() => {\\n\\t\\treturn <span>  HEY  </span>}}</div>\",\n\t\t\twant:   \"<div>{() => {\\n\\t\\treturn <span> HEY </span>}}</div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"expression collapse newlines\",\n\t\t\tsource: \"<div>{() => {\\n\\t\\treturn <span>\\n\\nTEST</span>}}</div>\",\n\t\t\twant:   \"<div>{() => {\\n\\t\\treturn <span>\\nTEST</span>}}</div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"expression remove only whitespace\",\n\t\t\tsource: \"<div>{() => {\\n\\t\\treturn <span>\\n\\n\\n</span>}}</div>\",\n\t\t\twant:   \"<div>{() => {\\n\\t\\treturn <span></span>}}</div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"attributes\",\n\t\t\tsource: `<div    a=\"1\"    b={0} />`,\n\t\t\twant:   `<div a=\"1\" b={0}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"expression quoted\",\n\t\t\tsource: \"<div test={\\n`  test  `\\n} />\",\n\t\t\twant:   \"<div test={`  test  `}></div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"expression attribute math\",\n\t\t\tsource: \"<div test={ a + b } />\",\n\t\t\twant:   \"<div test={a + b}></div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"expression math\",\n\t\t\tsource: \"<div>{ a + b }</div>\",\n\t\t\twant:   \"<div>{a + b}</div>\",\n\t\t},\n\t}\n\tvar b strings.Builder\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tb.Reset()\n\t\t\tdoc, err := astro.Parse(strings.NewReader(tt.source))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\ttransformOptions := TransformOptions{\n\t\t\t\tCompact: true,\n\t\t\t}\n\t\t\tExtractStyles(doc, &transformOptions)\n\t\t\t// Clear doc.Styles to avoid scoping behavior, we're not testing that here\n\t\t\tdoc.Styles = make([]*astro.Node, 0)\n\t\t\tTransform(doc, transformOptions, &handler.Handler{})\n\t\t\tastro.PrintToSource(&b, doc)\n\t\t\tgot := strings.TrimSpace(b.String())\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestAnnotation(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname:   \"basic\",\n\t\t\tsource: `<div>Hello world!</div>`,\n\t\t\twant:   `<div data-astro-source-file=\"/src/pages/index.astro\">Hello world!</div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"no components\",\n\t\t\tsource: `<Component>Hello world!</Component>`,\n\t\t\twant:   `<Component>Hello world!</Component>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"injects root\",\n\t\t\tsource: `<html></html>`,\n\t\t\twant:   `<html></html>`,\n\t\t},\n\t}\n\tvar b strings.Builder\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tb.Reset()\n\t\t\tdoc, err := astro.Parse(strings.NewReader(tt.source))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\th := handler.NewHandler(tt.source, \"/src/pages/index.astro\")\n\t\t\tTransform(doc, TransformOptions{\n\t\t\t\tAnnotateSourceFile: true,\n\t\t\t\tFilename:           \"/src/pages/index.astro\",\n\t\t\t\tNormalizedFilename: \"/src/pages/index.astro\",\n\t\t\t}, h)\n\t\t\tastro.PrintToSource(&b, doc)\n\t\t\tgot := strings.TrimSpace(b.String())\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\n\t\t})\n\t}\n}\n\nfunc TestClassAndClassListMerging(t *testing.T) {\n\ttests := []struct {\n\t\tname   string\n\t\tsource string\n\t\twant   string\n\t}{\n\t\t{\n\t\t\tname:   \"Single class attribute\",\n\t\t\tsource: `<div class=\"astro-xxxxxx\" />`,\n\t\t\twant:   `<div class=\"astro-xxxxxx\"></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Class attribute with parameter\",\n\t\t\tsource: \"<div class={`astro-xxxxxx ${astro}`} />\",\n\t\t\twant:   \"<div class={`astro-xxxxxx ${astro}`}></div>\",\n\t\t},\n\t\t{\n\t\t\tname:   \"Single class:list attribute\",\n\t\t\tsource: `<div class:list={\"astro-xxxxxx\"} />`,\n\t\t\twant:   `<div class:list={\"astro-xxxxxx\"}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Merge class with empty class:list (double quotes)\",\n\t\t\tsource: `<div class=\"astro-xxxxxx\" class:list={} />`,\n\t\t\twant:   `<div class:list={['astro-xxxxxx', ]}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Merge class with empty class:list (single quotes)\",\n\t\t\tsource: `<div class='astro-xxxxxx' class:list={} />`,\n\t\t\twant:   `<div class:list={['astro-xxxxxx', ]}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Merge class and class:list attributes (string)\",\n\t\t\tsource: `<div class=\"astro-xxxxxx\" class:list={\"astro-yyyyyy\"} />`,\n\t\t\twant:   `<div class:list={['astro-xxxxxx', \"astro-yyyyyy\"]}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Merge class and class:list attributes (expression)\",\n\t\t\tsource: `<div class={\"astro-xxxxxx\"} class:list={\"astro-yyyyyy\"} />`,\n\t\t\twant:   `<div class:list={[\"astro-xxxxxx\", \"astro-yyyyyy\"]}></div>`,\n\t\t},\n\t\t{\n\t\t\tname:   \"Merge Class and Class List Attributes (concatenation)\",\n\t\t\tsource: `<div class={\"astro-xxxxxx\" + name} class:list={\"astro-yyyyyy\"} />`,\n\t\t\twant:   `<div class:list={[\"astro-xxxxxx\" + name, \"astro-yyyyyy\"]}></div>`,\n\t\t},\n\t}\n\n\tvar b strings.Builder\n\tfor _, tt := range tests {\n\t\tt.Run(tt.name, func(t *testing.T) {\n\t\t\tb.Reset()\n\t\t\tdoc, err := astro.Parse(strings.NewReader(tt.source))\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tTransform(doc, TransformOptions{}, handler.NewHandler(tt.source, \"/test.astro\"))\n\t\t\tastro.PrintToSource(&b, doc.LastChild.FirstChild.NextSibling.FirstChild)\n\t\t\tgot := b.String()\n\t\t\tif tt.want != got {\n\t\t\t\tt.Errorf(\"\\nFAIL: %s\\n  want: %s\\n  got:  %s\", tt.name, tt.want, got)\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "internal/transform/utils.go",
    "content": "package transform\n\nimport (\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"golang.org/x/net/html/atom\"\n)\n\nfunc hasTruthyAttr(n *astro.Node, key string) bool {\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == key &&\n\t\t\t(attr.Type == astro.EmptyAttribute) ||\n\t\t\t(attr.Type == astro.ExpressionAttribute && attr.Val == \"true\") ||\n\t\t\t(attr.Type == astro.QuotedAttribute && (attr.Val == \"\" || attr.Val == \"true\")) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc HasSetDirective(n *astro.Node) bool {\n\treturn HasAttr(n, \"set:html\") || HasAttr(n, \"set:text\")\n}\n\nfunc HasInlineDirective(n *astro.Node) bool {\n\treturn HasAttr(n, \"is:inline\")\n}\n\nfunc AttrIndex(n *astro.Node, key string) int {\n\tfor i, attr := range n.Attr {\n\t\tif attr.Key == key {\n\t\t\treturn i\n\t\t}\n\t}\n\treturn -1\n}\n\nfunc HasAttr(n *astro.Node, key string) bool {\n\treturn AttrIndex(n, key) != -1\n}\n\nfunc GetAttr(n *astro.Node, key string) *astro.Attribute {\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == key {\n\t\t\treturn &attr\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc IsHoistable(n *astro.Node, renderScript bool) bool {\n\tparent := n.Closest(func(p *astro.Node) bool {\n\t\treturn p.DataAtom == atom.Svg || p.DataAtom == atom.Noscript || p.DataAtom == atom.Template\n\t})\n\n\tif renderScript && parent != nil && parent.Expression {\n\t\treturn true\n\t}\n\n\treturn parent == nil\n}\n\nfunc IsImplicitNode(n *astro.Node) bool {\n\treturn HasAttr(n, astro.ImplicitNodeMarker)\n}\n\nfunc IsImplicitNodeMarker(attr astro.Attribute) bool {\n\treturn attr.Key == astro.ImplicitNodeMarker\n}\n\nfunc IsTopLevel(n *astro.Node) bool {\n\tif IsImplicitNode(n) || n.Data == \"\" {\n\t\treturn false\n\t}\n\tp := n.Parent\n\tif p == nil {\n\t\treturn true\n\t}\n\tif IsImplicitNode(p) || p.Data == \"\" {\n\t\treturn true\n\t}\n\tif p.Component {\n\t\treturn IsTopLevel(p)\n\t}\n\treturn false\n}\n\nfunc GetQuotedAttr(n *astro.Node, key string) string {\n\tfor _, attr := range n.Attr {\n\t\tif attr.Key == key {\n\t\t\tif attr.Type == astro.QuotedAttribute {\n\t\t\t\treturn attr.Val\n\t\t\t}\n\t\t\treturn \"\"\n\t\t}\n\t}\n\treturn \"\"\n}\n"
  },
  {
    "path": "internal/xxhash/LICENSE.txt",
    "content": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "internal/xxhash/xxhash.go",
    "content": "// Package xxhash implements the 64-bit variant of xxHash (XXH64) as described\n// at http://cyan4973.github.io/xxHash/.\npackage xxhash\n\nimport (\n\t\"encoding/binary\"\n\t\"errors\"\n\t\"math/bits\"\n)\n\nconst (\n\tprime1 uint64 = 11400714785074694791\n\tprime2 uint64 = 14029467366897019727\n\tprime3 uint64 = 1609587929392839161\n\tprime4 uint64 = 9650029242287828579\n\tprime5 uint64 = 2870177450012600261\n)\n\n// NOTE(caleb): I'm using both consts and vars of the primes. Using consts where\n// possible in the Go code is worth a small (but measurable) performance boost\n// by avoiding some MOVQs. Vars are needed for the asm and also are useful for\n// convenience in the Go code in a few places where we need to intentionally\n// avoid constant arithmetic (e.g., v1 := prime1 + prime2 fails because the\n// result overflows a uint64).\nvar (\n\tprime1v = prime1\n\tprime2v = prime2\n\tprime3v = prime3\n\tprime4v = prime4\n\tprime5v = prime5\n)\n\n// Digest implements hash.Hash64.\ntype Digest struct {\n\tv1    uint64\n\tv2    uint64\n\tv3    uint64\n\tv4    uint64\n\ttotal uint64\n\tmem   [32]byte\n\tn     int // how much of mem is used\n}\n\n// New creates a new Digest that computes the 64-bit xxHash algorithm.\nfunc New() *Digest {\n\tvar d Digest\n\td.Reset()\n\treturn &d\n}\n\n// Reset clears the Digest's state so that it can be reused.\nfunc (d *Digest) Reset() {\n\td.v1 = prime1v + prime2\n\td.v2 = prime2\n\td.v3 = 0\n\td.v4 = -prime1v\n\td.total = 0\n\td.n = 0\n}\n\n// Size always returns 8 bytes.\nfunc (d *Digest) Size() int { return 8 }\n\n// BlockSize always returns 32 bytes.\nfunc (d *Digest) BlockSize() int { return 32 }\n\n// Write adds more data to d. It always returns len(b), nil.\nfunc (d *Digest) Write(b []byte) (n int, err error) {\n\tn = len(b)\n\td.total += uint64(n)\n\n\tif d.n+n < 32 {\n\t\t// This new data doesn't even fill the current block.\n\t\tcopy(d.mem[d.n:], b)\n\t\td.n += n\n\t\treturn\n\t}\n\n\tif d.n > 0 {\n\t\t// Finish off the partial block.\n\t\tcopy(d.mem[d.n:], b)\n\t\td.v1 = round(d.v1, u64(d.mem[0:8]))\n\t\td.v2 = round(d.v2, u64(d.mem[8:16]))\n\t\td.v3 = round(d.v3, u64(d.mem[16:24]))\n\t\td.v4 = round(d.v4, u64(d.mem[24:32]))\n\t\tb = b[32-d.n:]\n\t\td.n = 0\n\t}\n\n\tif len(b) >= 32 {\n\t\t// One or more full blocks left.\n\t\tnw := writeBlocks(d, b)\n\t\tb = b[nw:]\n\t}\n\n\t// Store any remaining partial block.\n\tcopy(d.mem[:], b)\n\td.n = len(b)\n\n\treturn\n}\n\n// Sum appends the current hash to b and returns the resulting slice.\nfunc (d *Digest) Sum(b []byte) []byte {\n\ts := d.Sum64()\n\treturn append(\n\t\tb,\n\t\tbyte(s>>56),\n\t\tbyte(s>>48),\n\t\tbyte(s>>40),\n\t\tbyte(s>>32),\n\t\tbyte(s>>24),\n\t\tbyte(s>>16),\n\t\tbyte(s>>8),\n\t\tbyte(s),\n\t)\n}\n\n// Sum64 returns the current hash.\nfunc (d *Digest) Sum64() uint64 {\n\tvar h uint64\n\n\tif d.total >= 32 {\n\t\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = d.v3 + prime5\n\t}\n\n\th += d.total\n\n\ti, end := 0, d.n\n\tfor ; i+8 <= end; i += 8 {\n\t\tk1 := round(0, u64(d.mem[i:i+8]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif i+4 <= end {\n\t\th ^= uint64(u32(d.mem[i:i+4])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\ti += 4\n\t}\n\tfor i < end {\n\t\th ^= uint64(d.mem[i]) * prime5\n\t\th = rol11(h) * prime1\n\t\ti++\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nconst (\n\tmagic         = \"xxh\\x06\"\n\tmarshaledSize = len(magic) + 8*5 + 32\n)\n\n// MarshalBinary implements the encoding.BinaryMarshaler interface.\nfunc (d *Digest) MarshalBinary() ([]byte, error) {\n\tb := make([]byte, 0, marshaledSize)\n\tb = append(b, magic...)\n\tb = appendUint64(b, d.v1)\n\tb = appendUint64(b, d.v2)\n\tb = appendUint64(b, d.v3)\n\tb = appendUint64(b, d.v4)\n\tb = appendUint64(b, d.total)\n\tb = append(b, d.mem[:d.n]...)\n\tb = b[:len(b)+len(d.mem)-d.n]\n\treturn b, nil\n}\n\n// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface.\nfunc (d *Digest) UnmarshalBinary(b []byte) error {\n\tif len(b) < len(magic) || string(b[:len(magic)]) != magic {\n\t\treturn errors.New(\"xxhash: invalid hash state identifier\")\n\t}\n\tif len(b) != marshaledSize {\n\t\treturn errors.New(\"xxhash: invalid hash state size\")\n\t}\n\tb = b[len(magic):]\n\tb, d.v1 = consumeUint64(b)\n\tb, d.v2 = consumeUint64(b)\n\tb, d.v3 = consumeUint64(b)\n\tb, d.v4 = consumeUint64(b)\n\tb, d.total = consumeUint64(b)\n\tcopy(d.mem[:], b)\n\td.n = int(d.total % uint64(len(d.mem)))\n\treturn nil\n}\n\nfunc appendUint64(b []byte, x uint64) []byte {\n\tvar a [8]byte\n\tbinary.LittleEndian.PutUint64(a[:], x)\n\treturn append(b, a[:]...)\n}\n\nfunc consumeUint64(b []byte) ([]byte, uint64) {\n\tx := u64(b)\n\treturn b[8:], x\n}\n\nfunc u64(b []byte) uint64 { return binary.LittleEndian.Uint64(b) }\nfunc u32(b []byte) uint32 { return binary.LittleEndian.Uint32(b) }\n\nfunc round(acc, input uint64) uint64 {\n\tacc += input * prime2\n\tacc = rol31(acc)\n\tacc *= prime1\n\treturn acc\n}\n\nfunc mergeRound(acc, val uint64) uint64 {\n\tval = round(0, val)\n\tacc ^= val\n\tacc = acc*prime1 + prime4\n\treturn acc\n}\n\nfunc rol1(x uint64) uint64  { return bits.RotateLeft64(x, 1) }\nfunc rol7(x uint64) uint64  { return bits.RotateLeft64(x, 7) }\nfunc rol11(x uint64) uint64 { return bits.RotateLeft64(x, 11) }\nfunc rol12(x uint64) uint64 { return bits.RotateLeft64(x, 12) }\nfunc rol18(x uint64) uint64 { return bits.RotateLeft64(x, 18) }\nfunc rol23(x uint64) uint64 { return bits.RotateLeft64(x, 23) }\nfunc rol27(x uint64) uint64 { return bits.RotateLeft64(x, 27) }\nfunc rol31(x uint64) uint64 { return bits.RotateLeft64(x, 31) }\n"
  },
  {
    "path": "internal/xxhash/xxhash_other.go",
    "content": "package xxhash\n\n// Sum64 computes the 64-bit xxHash digest of b.\nfunc Sum64(b []byte) uint64 {\n\t// A simpler version would be\n\t//   d := New()\n\t//   d.Write(b)\n\t//   return d.Sum64()\n\t// but this is faster, particularly for small inputs.\n\n\tn := len(b)\n\tvar h uint64\n\n\tif n >= 32 {\n\t\tv1 := prime1v + prime2\n\t\tv2 := prime2\n\t\tv3 := uint64(0)\n\t\tv4 := -prime1v\n\t\tfor len(b) >= 32 {\n\t\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\t\tb = b[32:len(b):len(b)]\n\t\t}\n\t\th = rol1(v1) + rol7(v2) + rol12(v3) + rol18(v4)\n\t\th = mergeRound(h, v1)\n\t\th = mergeRound(h, v2)\n\t\th = mergeRound(h, v3)\n\t\th = mergeRound(h, v4)\n\t} else {\n\t\th = prime5\n\t}\n\n\th += uint64(n)\n\n\ti, end := 0, len(b)\n\tfor ; i+8 <= end; i += 8 {\n\t\tk1 := round(0, u64(b[i:i+8:len(b)]))\n\t\th ^= k1\n\t\th = rol27(h)*prime1 + prime4\n\t}\n\tif i+4 <= end {\n\t\th ^= uint64(u32(b[i:i+4:len(b)])) * prime1\n\t\th = rol23(h)*prime2 + prime3\n\t\ti += 4\n\t}\n\tfor ; i < end; i++ {\n\t\th ^= uint64(b[i]) * prime5\n\t\th = rol11(h) * prime1\n\t}\n\n\th ^= h >> 33\n\th *= prime2\n\th ^= h >> 29\n\th *= prime3\n\th ^= h >> 32\n\n\treturn h\n}\n\nfunc writeBlocks(d *Digest, b []byte) int {\n\tv1, v2, v3, v4 := d.v1, d.v2, d.v3, d.v4\n\tn := len(b)\n\tfor len(b) >= 32 {\n\t\tv1 = round(v1, u64(b[0:8:len(b)]))\n\t\tv2 = round(v2, u64(b[8:16:len(b)]))\n\t\tv3 = round(v3, u64(b[16:24:len(b)]))\n\t\tv4 = round(v4, u64(b[24:32:len(b)]))\n\t\tb = b[32:len(b):len(b)]\n\t}\n\td.v1, d.v2, d.v3, d.v4 = v1, v2, v3, v4\n\treturn n - len(b)\n}\n"
  },
  {
    "path": "internal_wasm/utils/utils.go",
    "content": "//go:build js && wasm\n\npackage wasm_utils\n\nimport (\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"syscall/js\"\n\n\t\"github.com/norunners/vert\"\n\tastro \"github.com/withastro/compiler/internal\"\n\t\"github.com/withastro/compiler/internal/handler\"\n)\n\n// See https://stackoverflow.com/questions/68426700/how-to-wait-a-js-async-function-from-golang-wasm\nfunc Await(awaitable js.Value) ([]js.Value, []js.Value) {\n\tthen := make(chan []js.Value)\n\tthenFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {\n\t\tthen <- args\n\t\treturn nil\n\t})\n\t// defers are called LIFO!\n\t// This will `close` before `Release()`\n\tdefer thenFunc.Release()\n\tdefer close(then)\n\n\tcatch := make(chan []js.Value)\n\tcatchFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {\n\t\tcatch <- args\n\t\treturn nil\n\t})\n\t// defers are called LIFO!\n\t// This will `close` before `Release()`\n\tdefer catchFunc.Release()\n\tdefer close(catch)\n\n\tawaitable.Call(\"then\", thenFunc).Call(\"catch\", catchFunc)\n\n\tselect {\n\tcase result := <-then:\n\t\treturn result, nil\n\tcase err := <-catch:\n\t\treturn nil, err\n\t}\n}\n\nfunc GetAttrs(n *astro.Node) js.Value {\n\tattrs := js.Global().Get(\"Object\").New()\n\tfor _, attr := range n.Attr {\n\t\tswitch attr.Type {\n\t\tcase astro.QuotedAttribute:\n\t\t\tattrs.Set(attr.Key, attr.Val)\n\t\tcase astro.EmptyAttribute:\n\t\t\tattrs.Set(attr.Key, true)\n\t\t}\n\t}\n\treturn attrs\n}\n\ntype JSError struct {\n\tMessage string `js:\"message\"`\n\tStack   string `js:\"stack\"`\n}\n\nfunc (err *JSError) Value() js.Value {\n\treturn vert.ValueOf(err).Value\n}\n\nfunc ErrorToJSError(h *handler.Handler, err error) js.Value {\n\tstack := string(debug.Stack())\n\tmessage := strings.TrimSpace(err.Error())\n\tjsError := JSError{\n\t\tMessage: message,\n\t\tStack:   stack,\n\t}\n\treturn jsError.Value()\n}\n"
  },
  {
    "path": "lib/esbuild/LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2020 Evan Wallace\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 all\ncopies 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 THE\nSOFTWARE.\n"
  },
  {
    "path": "lib/esbuild/ast/ast.go",
    "content": "package ast\n\nimport \"github.com/withastro/compiler/lib/esbuild/logger\"\n\n// This file contains data structures that are used with the AST packages for\n// both JavaScript and CSS. This helps the bundler treat both AST formats in\n// a somewhat format-agnostic manner.\n\ntype ImportKind uint8\n\nconst (\n\t// An entry point provided by the user\n\tImportEntryPoint ImportKind = iota\n\n\t// An ES6 import or re-export statement\n\tImportStmt\n\n\t// A call to \"require()\"\n\tImportRequire\n\n\t// An \"import()\" expression with a string argument\n\tImportDynamic\n\n\t// A call to \"require.resolve()\"\n\tImportRequireResolve\n\n\t// A CSS \"@import\" rule\n\tImportAt\n\n\t// A CSS \"@import\" rule with import conditions\n\tImportAtConditional\n\n\t// A CSS \"url(...)\" token\n\tImportURL\n)\n\nfunc (kind ImportKind) StringForMetafile() string {\n\tswitch kind {\n\tcase ImportStmt:\n\t\treturn \"import-statement\"\n\tcase ImportRequire:\n\t\treturn \"require-call\"\n\tcase ImportDynamic:\n\t\treturn \"dynamic-import\"\n\tcase ImportRequireResolve:\n\t\treturn \"require-resolve\"\n\tcase ImportAt, ImportAtConditional:\n\t\treturn \"import-rule\"\n\tcase ImportURL:\n\t\treturn \"url-token\"\n\tcase ImportEntryPoint:\n\t\treturn \"entry-point\"\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (kind ImportKind) IsFromCSS() bool {\n\treturn kind == ImportAt || kind == ImportURL\n}\n\ntype ImportRecordFlags uint16\n\nconst (\n\t// Sometimes the parser creates an import record and decides it isn't needed.\n\t// For example, TypeScript code may have import statements that later turn\n\t// out to be type-only imports after analyzing the whole file.\n\tIsUnused ImportRecordFlags = 1 << iota\n\n\t// If this is true, the import contains syntax like \"* as ns\". This is used\n\t// to determine whether modules that have no exports need to be wrapped in a\n\t// CommonJS wrapper or not.\n\tContainsImportStar\n\n\t// If this is true, the import contains an import for the alias \"default\",\n\t// either via the \"import x from\" or \"import {default as x} from\" syntax.\n\tContainsDefaultAlias\n\n\t// If this is true, the import contains an import for the alias \"__esModule\",\n\t// via the \"import {__esModule} from\" syntax.\n\tContainsESModuleAlias\n\n\t// If true, this \"export * from 'path'\" statement is evaluated at run-time by\n\t// calling the \"__reExport()\" helper function\n\tCallsRunTimeReExportFn\n\n\t// Tell the printer to wrap this call to \"require()\" in \"__toESM(...)\"\n\tWrapWithToESM\n\n\t// Tell the printer to wrap this ESM exports object in \"__toCJS(...)\"\n\tWrapWithToCJS\n\n\t// Tell the printer to use the runtime \"__require()\" instead of \"require()\"\n\tCallRuntimeRequire\n\n\t// True for the following cases:\n\t//\n\t//   try { require('x') } catch { handle }\n\t//   try { await import('x') } catch { handle }\n\t//   try { require.resolve('x') } catch { handle }\n\t//   import('x').catch(handle)\n\t//   import('x').then(_, handle)\n\t//\n\t// In these cases we shouldn't generate an error if the path could not be\n\t// resolved.\n\tHandlesImportErrors\n\n\t// If true, this was originally written as a bare \"import 'file'\" statement\n\tWasOriginallyBareImport\n\n\t// If true, this import can be removed if it's unused\n\tIsExternalWithoutSideEffects\n)\n\nfunc (flags ImportRecordFlags) Has(flag ImportRecordFlags) bool {\n\treturn (flags & flag) != 0\n}\n\ntype ImportRecord struct {\n\tAssertions *[]AssertEntry\n\tPath       logger.Path\n\tRange      logger.Range\n\n\t// If the \"HandlesImportErrors\" flag is present, then this is the location\n\t// of the error handler. This is used for error reporting.\n\tErrorHandlerLoc logger.Loc\n\n\t// The resolved source index for an internal import (within the bundle) or\n\t// nil for an external import (not included in the bundle)\n\tSourceIndex Index32\n\n\tFlags ImportRecordFlags\n\tKind  ImportKind\n}\n\ntype AssertEntry struct {\n\tKey             []uint16 // An identifier or a string\n\tValue           []uint16 // Always a string\n\tKeyLoc          logger.Loc\n\tValueLoc        logger.Loc\n\tPreferQuotedKey bool\n}\n\n// This stores a 32-bit index where the zero value is an invalid index. This is\n// a better alternative to storing the index as a pointer since that has the\n// same properties but takes up more space and costs an extra pointer traversal.\ntype Index32 struct {\n\tflippedBits uint32\n}\n\nfunc MakeIndex32(index uint32) Index32 {\n\treturn Index32{flippedBits: ^index}\n}\n\nfunc (i Index32) IsValid() bool {\n\treturn i.flippedBits != 0\n}\n\nfunc (i Index32) GetIndex() uint32 {\n\treturn ^i.flippedBits\n}\n"
  },
  {
    "path": "lib/esbuild/compat/compat.go",
    "content": "package compat\n\ntype v struct {\n\tmajor uint16\n\tminor uint8\n\tpatch uint8\n}\n\n// Returns <0 if \"a < b\"\n// Returns 0 if \"a == b\"\n// Returns >0 if \"a > b\"\nfunc compareVersions(a v, b []int) int {\n\tdiff := int(a.major)\n\tif len(b) > 0 {\n\t\tdiff -= b[0]\n\t}\n\tif diff == 0 {\n\t\tdiff = int(a.minor)\n\t\tif len(b) > 1 {\n\t\t\tdiff -= b[1]\n\t\t}\n\t}\n\tif diff == 0 {\n\t\tdiff = int(a.patch)\n\t\tif len(b) > 2 {\n\t\t\tdiff -= b[2]\n\t\t}\n\t}\n\treturn diff\n}\n\n// The start is inclusive and the end is exclusive\ntype versionRange struct {\n\tstart v\n\tend   v // Use 0.0.0 for \"no end\"\n}\n\nfunc isVersionSupported(ranges []versionRange, version []int) bool {\n\tfor _, r := range ranges {\n\t\tif compareVersions(r.start, version) <= 0 && (r.end == (v{}) || compareVersions(r.end, version) > 0) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "lib/esbuild/compat/css_table.go",
    "content": "package compat\n\ntype CSSFeature uint32\n\nconst (\n\tHexRGBA CSSFeature = 1 << iota\n\n\tRebeccaPurple\n\n\t// This feature includes all of the following:\n\t// - Allow floats in rgb() and rgba()\n\t// - hsl() can accept alpha values\n\t// - rgb() can accept alpha values\n\t// - Space-separated functional color notations\n\tModern_RGB_HSL\n\n\tInsetProperty\n\tNesting\n)\n\nfunc (features CSSFeature) Has(feature CSSFeature) bool {\n\treturn (features & feature) != 0\n}\n\nvar cssTable = map[CSSFeature]map[Engine][]versionRange{\n\t// Data from: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value\n\tHexRGBA: {\n\t\tChrome:  {{start: v{62, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tFirefox: {{start: v{49, 0, 0}}},\n\t\tIOS:     {{start: v{9, 3, 0}}},\n\t\tSafari:  {{start: v{9, 1, 0}}},\n\t},\n\tRebeccaPurple: {\n\t\tChrome:  {{start: v{38, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tFirefox: {{start: v{33, 0, 0}}},\n\t\tIOS:     {{start: v{8, 0, 0}}},\n\t\tSafari:  {{start: v{9, 0, 0}}},\n\t},\n\tModern_RGB_HSL: {\n\t\tChrome:  {{start: v{66, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tFirefox: {{start: v{52, 0, 0}}},\n\t\tIOS:     {{start: v{12, 2, 0}}},\n\t\tSafari:  {{start: v{12, 1, 0}}},\n\t},\n\n\t// Data from: https://developer.mozilla.org/en-US/docs/Web/CSS/inset\n\tInsetProperty: {\n\t\tChrome:  {{start: v{87, 0, 0}}},\n\t\tEdge:    {{start: v{87, 0, 0}}},\n\t\tFirefox: {{start: v{66, 0, 0}}},\n\t\tIOS:     {{start: v{14, 5, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\n\t// This isn't supported anywhere right now: https://caniuse.com/css-nesting\n\tNesting: {},\n}\n\n// Return all features that are not available in at least one environment\nfunc UnsupportedCSSFeatures(constraints map[Engine][]int) (unsupported CSSFeature) {\n\tfor feature, engines := range cssTable {\n\t\tfor engine, version := range constraints {\n\t\t\tif engine == ES || engine == Node {\n\t\t\t\t// Specifying \"--target=es2020\" shouldn't affect CSS\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif versionRanges, ok := engines[engine]; !ok || !isVersionSupported(versionRanges, version) {\n\t\t\t\tunsupported |= feature\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "lib/esbuild/compat/js_table.go",
    "content": "// This file was automatically generated by \"compat-table.js\"\n\npackage compat\n\ntype Engine uint8\n\nconst (\n\tChrome Engine = iota\n\tEdge\n\tES\n\tFirefox\n\tIE\n\tIOS\n\tNode\n\tOpera\n\tSafari\n)\n\nfunc (e Engine) String() string {\n\tswitch e {\n\tcase Chrome:\n\t\treturn \"chrome\"\n\tcase Edge:\n\t\treturn \"edge\"\n\tcase ES:\n\t\treturn \"es\"\n\tcase Firefox:\n\t\treturn \"firefox\"\n\tcase IE:\n\t\treturn \"ie\"\n\tcase IOS:\n\t\treturn \"ios\"\n\tcase Node:\n\t\treturn \"node\"\n\tcase Opera:\n\t\treturn \"opera\"\n\tcase Safari:\n\t\treturn \"safari\"\n\t}\n\treturn \"\"\n}\n\ntype JSFeature uint64\n\nconst (\n\tArbitraryModuleNamespaceNames JSFeature = 1 << iota\n\tArraySpread\n\tArrow\n\tAsyncAwait\n\tAsyncGenerator\n\tBigInt\n\tClass\n\tClassField\n\tClassPrivateAccessor\n\tClassPrivateBrandCheck\n\tClassPrivateField\n\tClassPrivateMethod\n\tClassPrivateStaticAccessor\n\tClassPrivateStaticField\n\tClassPrivateStaticMethod\n\tClassStaticBlocks\n\tClassStaticField\n\tConst\n\tDefaultArgument\n\tDestructuring\n\tDynamicImport\n\tExponentOperator\n\tExportStarAs\n\tForAwait\n\tForOf\n\tGenerator\n\tHashbang\n\tImportAssertions\n\tImportMeta\n\tLet\n\tLogicalAssignment\n\tNestedRestBinding\n\tNewTarget\n\tNodeColonPrefixImport\n\tNodeColonPrefixRequire\n\tNullishCoalescing\n\tObjectAccessors\n\tObjectExtensions\n\tObjectRestSpread\n\tOptionalCatchBinding\n\tOptionalChain\n\tRestArgument\n\tTemplateLiteral\n\tTopLevelAwait\n\tTypeofExoticObjectIsObject\n\tUnicodeEscapes\n)\n\nfunc (features JSFeature) Has(feature JSFeature) bool {\n\treturn (features & feature) != 0\n}\n\nvar jsTable = map[JSFeature]map[Engine][]versionRange{\n\tArbitraryModuleNamespaceNames: {\n\t\tChrome:  {{start: v{90, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{87, 0, 0}}},\n\t\tNode:    {{start: v{16, 0, 0}}},\n\t},\n\tArraySpread: {\n\t\tChrome:  {{start: v{46, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{36, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{5, 0, 0}}},\n\t\tOpera:   {{start: v{33, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tArrow: {\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{45, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tAsyncAwait: {\n\t\tChrome:  {{start: v{55, 0, 0}}},\n\t\tEdge:    {{start: v{15, 0, 0}}},\n\t\tES:      {{start: v{2017, 0, 0}}},\n\t\tFirefox: {{start: v{52, 0, 0}}},\n\t\tIOS:     {{start: v{11, 0, 0}}},\n\t\tNode:    {{start: v{7, 6, 0}}},\n\t\tOpera:   {{start: v{42, 0, 0}}},\n\t\tSafari:  {{start: v{11, 0, 0}}},\n\t},\n\tAsyncGenerator: {\n\t\tChrome:  {{start: v{63, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{57, 0, 0}}},\n\t\tIOS:     {{start: v{12, 0, 0}}},\n\t\tNode:    {{start: v{10, 0, 0}}},\n\t\tOpera:   {{start: v{50, 0, 0}}},\n\t\tSafari:  {{start: v{12, 0, 0}}},\n\t},\n\tBigInt: {\n\t\tChrome:  {{start: v{67, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{68, 0, 0}}},\n\t\tIOS:     {{start: v{14, 0, 0}}},\n\t\tNode:    {{start: v{10, 4, 0}}},\n\t\tOpera:   {{start: v{54, 0, 0}}},\n\t\tSafari:  {{start: v{14, 0, 0}}},\n\t},\n\tClass: {\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{45, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tClassField: {\n\t\tChrome:  {{start: v{73, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{69, 0, 0}}},\n\t\tIOS:     {{start: v{14, 0, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{60, 0, 0}}},\n\t\tSafari:  {{start: v{14, 0, 0}}},\n\t},\n\tClassPrivateAccessor: {\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateBrandCheck: {\n\t\tChrome:  {{start: v{91, 0, 0}}},\n\t\tEdge:    {{start: v{91, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{16, 9, 0}}},\n\t\tOpera:   {{start: v{77, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateField: {\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tClassPrivateMethod: {\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateStaticAccessor: {\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassPrivateStaticField: {\n\t\tChrome:  {{start: v{74, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{62, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tClassPrivateStaticMethod: {\n\t\tChrome:  {{start: v{84, 0, 0}}},\n\t\tEdge:    {{start: v{84, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{90, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{14, 6, 0}}},\n\t\tOpera:   {{start: v{70, 0, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tClassStaticBlocks: {\n\t\tChrome: {{start: v{91, 0, 0}}},\n\t\tES:     {{start: v{2022, 0, 0}}},\n\t\tNode:   {{start: v{16, 11, 0}}},\n\t},\n\tClassStaticField: {\n\t\tChrome:  {{start: v{73, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{75, 0, 0}}},\n\t\tIOS:     {{start: v{15, 0, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{60, 0, 0}}},\n\t\tSafari:  {{start: v{14, 1, 0}}},\n\t},\n\tConst: {\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{51, 0, 0}}},\n\t\tIE:      {{start: v{11, 0, 0}}},\n\t\tIOS:     {{start: v{11, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{11, 0, 0}}},\n\t},\n\tDefaultArgument: {\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tDestructuring: {\n\t\tChrome:  {{start: v{51, 0, 0}}},\n\t\tEdge:    {{start: v{18, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 5, 0}}},\n\t\tOpera:   {{start: v{38, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tDynamicImport: {\n\t\tChrome:  {{start: v{63, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{67, 0, 0}}},\n\t\tIOS:     {{start: v{11, 0, 0}}},\n\t\tNode:    {{start: v{12, 20, 0}, end: v{13, 0, 0}}, {start: v{13, 2, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tExponentOperator: {\n\t\tChrome:  {{start: v{52, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2016, 0, 0}}},\n\t\tFirefox: {{start: v{52, 0, 0}}},\n\t\tIOS:     {{start: v{10, 3, 0}}},\n\t\tNode:    {{start: v{7, 0, 0}}},\n\t\tOpera:   {{start: v{39, 0, 0}}},\n\t\tSafari:  {{start: v{10, 1, 0}}},\n\t},\n\tExportStarAs: {\n\t\tChrome:  {{start: v{72, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{80, 0, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t},\n\tForAwait: {\n\t\tChrome:  {{start: v{63, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{57, 0, 0}}},\n\t\tIOS:     {{start: v{12, 0, 0}}},\n\t\tNode:    {{start: v{10, 0, 0}}},\n\t\tOpera:   {{start: v{50, 0, 0}}},\n\t\tSafari:  {{start: v{12, 0, 0}}},\n\t},\n\tForOf: {\n\t\tChrome:  {{start: v{51, 0, 0}}},\n\t\tEdge:    {{start: v{15, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 5, 0}}},\n\t\tOpera:   {{start: v{38, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tGenerator: {\n\t\tChrome:  {{start: v{50, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{37, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tHashbang: {\n\t\tChrome:  {{start: v{74, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tFirefox: {{start: v{67, 0, 0}}},\n\t\tIOS:     {{start: v{13, 4, 0}}},\n\t\tNode:    {{start: v{12, 0, 0}}},\n\t\tOpera:   {{start: v{62, 0, 0}}},\n\t\tSafari:  {{start: v{13, 1, 0}}},\n\t},\n\tImportAssertions: {\n\t\tChrome: {{start: v{91, 0, 0}}},\n\t\tNode:   {{start: v{16, 14, 0}}},\n\t},\n\tImportMeta: {\n\t\tChrome:  {{start: v{64, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{62, 0, 0}}},\n\t\tIOS:     {{start: v{12, 0, 0}}},\n\t\tNode:    {{start: v{10, 4, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tLet: {\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{51, 0, 0}}},\n\t\tIE:      {{start: v{11, 0, 0}}},\n\t\tIOS:     {{start: v{11, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{11, 0, 0}}},\n\t},\n\tLogicalAssignment: {\n\t\tChrome:  {{start: v{85, 0, 0}}},\n\t\tEdge:    {{start: v{85, 0, 0}}},\n\t\tES:      {{start: v{2021, 0, 0}}},\n\t\tFirefox: {{start: v{79, 0, 0}}},\n\t\tIOS:     {{start: v{14, 0, 0}}},\n\t\tNode:    {{start: v{15, 0, 0}}},\n\t\tOpera:   {{start: v{71, 0, 0}}},\n\t\tSafari:  {{start: v{14, 0, 0}}},\n\t},\n\tNestedRestBinding: {\n\t\tChrome:  {{start: v{49, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2016, 0, 0}}},\n\t\tFirefox: {{start: v{47, 0, 0}}},\n\t\tIOS:     {{start: v{10, 3, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{36, 0, 0}}},\n\t\tSafari:  {{start: v{10, 1, 0}}},\n\t},\n\tNewTarget: {\n\t\tChrome:  {{start: v{46, 0, 0}}},\n\t\tEdge:    {{start: v{14, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{41, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{5, 0, 0}}},\n\t\tOpera:   {{start: v{33, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tNodeColonPrefixImport: {\n\t\tNode: {{start: v{12, 20, 0}, end: v{13, 0, 0}}, {start: v{14, 13, 1}}},\n\t},\n\tNodeColonPrefixRequire: {\n\t\tNode: {{start: v{14, 18, 0}, end: v{15, 0, 0}}, {start: v{16, 0, 0}}},\n\t},\n\tNullishCoalescing: {\n\t\tChrome:  {{start: v{80, 0, 0}}},\n\t\tEdge:    {{start: v{80, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{72, 0, 0}}},\n\t\tIOS:     {{start: v{13, 4, 0}}},\n\t\tNode:    {{start: v{14, 0, 0}}},\n\t\tOpera:   {{start: v{67, 0, 0}}},\n\t\tSafari:  {{start: v{13, 1, 0}}},\n\t},\n\tObjectAccessors: {\n\t\tChrome:  {{start: v{5, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{5, 0, 0}}},\n\t\tFirefox: {{start: v{2, 0, 0}}},\n\t\tIE:      {{start: v{9, 0, 0}}},\n\t\tIOS:     {{start: v{6, 0, 0}}},\n\t\tNode:    {{start: v{0, 10, 0}}},\n\t\tOpera:   {{start: v{10, 10, 0}}},\n\t\tSafari:  {{start: v{3, 1, 0}}},\n\t},\n\tObjectExtensions: {\n\t\tChrome:  {{start: v{44, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{34, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{4, 0, 0}}},\n\t\tOpera:   {{start: v{31, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tObjectRestSpread: {\n\t\tES:      {{start: v{2018, 0, 0}}},\n\t\tFirefox: {{start: v{55, 0, 0}}},\n\t\tIOS:     {{start: v{11, 3, 0}}},\n\t\tOpera:   {{start: v{47, 0, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tOptionalCatchBinding: {\n\t\tChrome:  {{start: v{66, 0, 0}}},\n\t\tEdge:    {{start: v{79, 0, 0}}},\n\t\tES:      {{start: v{2019, 0, 0}}},\n\t\tFirefox: {{start: v{58, 0, 0}}},\n\t\tIOS:     {{start: v{11, 3, 0}}},\n\t\tNode:    {{start: v{10, 0, 0}}},\n\t\tOpera:   {{start: v{53, 0, 0}}},\n\t\tSafari:  {{start: v{11, 1, 0}}},\n\t},\n\tOptionalChain: {\n\t\tChrome:  {{start: v{91, 0, 0}}},\n\t\tEdge:    {{start: v{91, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{74, 0, 0}}},\n\t\tIOS:     {{start: v{13, 4, 0}}},\n\t\tNode:    {{start: v{16, 9, 0}}},\n\t\tOpera:   {{start: v{77, 0, 0}}},\n\t\tSafari:  {{start: v{13, 1, 0}}},\n\t},\n\tRestArgument: {\n\t\tChrome:  {{start: v{47, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{43, 0, 0}}},\n\t\tIOS:     {{start: v{10, 0, 0}}},\n\t\tNode:    {{start: v{6, 0, 0}}},\n\t\tOpera:   {{start: v{34, 0, 0}}},\n\t\tSafari:  {{start: v{10, 0, 0}}},\n\t},\n\tTemplateLiteral: {\n\t\tChrome:  {{start: v{41, 0, 0}}},\n\t\tEdge:    {{start: v{13, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{34, 0, 0}}},\n\t\tIOS:     {{start: v{9, 0, 0}}},\n\t\tNode:    {{start: v{4, 0, 0}}},\n\t\tOpera:   {{start: v{28, 0, 0}}},\n\t\tSafari:  {{start: v{9, 0, 0}}},\n\t},\n\tTopLevelAwait: {\n\t\tChrome:  {{start: v{89, 0, 0}}},\n\t\tEdge:    {{start: v{89, 0, 0}}},\n\t\tES:      {{start: v{2022, 0, 0}}},\n\t\tFirefox: {{start: v{89, 0, 0}}},\n\t\tNode:    {{start: v{14, 8, 0}}},\n\t\tSafari:  {{start: v{15, 0, 0}}},\n\t},\n\tTypeofExoticObjectIsObject: {\n\t\tChrome:  {{start: v{0, 0, 0}}},\n\t\tEdge:    {{start: v{0, 0, 0}}},\n\t\tES:      {{start: v{2020, 0, 0}}},\n\t\tFirefox: {{start: v{0, 0, 0}}},\n\t\tIOS:     {{start: v{0, 0, 0}}},\n\t\tNode:    {{start: v{0, 0, 0}}},\n\t\tOpera:   {{start: v{0, 0, 0}}},\n\t\tSafari:  {{start: v{0, 0, 0}}},\n\t},\n\tUnicodeEscapes: {\n\t\tChrome:  {{start: v{44, 0, 0}}},\n\t\tEdge:    {{start: v{12, 0, 0}}},\n\t\tES:      {{start: v{2015, 0, 0}}},\n\t\tFirefox: {{start: v{53, 0, 0}}},\n\t\tIOS:     {{start: v{9, 0, 0}}},\n\t\tNode:    {{start: v{4, 0, 0}}},\n\t\tOpera:   {{start: v{31, 0, 0}}},\n\t\tSafari:  {{start: v{9, 0, 0}}},\n\t},\n}\n\n// Return all features that are not available in at least one environment\nfunc UnsupportedJSFeatures(constraints map[Engine][]int) (unsupported JSFeature) {\n\tfor feature, engines := range jsTable {\n\t\tfor engine, version := range constraints {\n\t\t\tif versionRanges, ok := engines[engine]; !ok || !isVersionSupported(versionRanges, version) {\n\t\t\t\tunsupported |= feature\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n"
  },
  {
    "path": "lib/esbuild/config/config.go",
    "content": "package config\n\nimport (\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/compat\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\ntype JSXOptions struct {\n\tFactory  JSXExpr\n\tFragment JSXExpr\n\tParse    bool\n\tPreserve bool\n}\n\ntype JSXExpr struct {\n\tParts []string\n}\n\ntype TSOptions struct {\n\tParse               bool\n\tNoAmbiguousLessThan bool\n}\n\ntype Platform uint8\n\nconst (\n\tPlatformBrowser Platform = iota\n\tPlatformNode\n\tPlatformNeutral\n)\n\ntype SourceMap uint8\n\nconst (\n\tSourceMapNone SourceMap = iota\n\tSourceMapInline\n\tSourceMapLinkedWithComment\n\tSourceMapExternalWithoutComment\n\tSourceMapInlineAndExternal\n)\n\ntype LegalComments uint8\n\nconst (\n\tLegalCommentsInline LegalComments = iota\n\tLegalCommentsNone\n\tLegalCommentsEndOfFile\n\tLegalCommentsLinkedWithComment\n\tLegalCommentsExternalWithoutComment\n)\n\nfunc (lc LegalComments) HasExternalFile() bool {\n\treturn lc == LegalCommentsLinkedWithComment || lc == LegalCommentsExternalWithoutComment\n}\n\ntype Loader uint8\n\nconst (\n\tLoaderNone Loader = iota\n\tLoaderJS\n\tLoaderJSX\n\tLoaderTS\n\tLoaderTSNoAmbiguousLessThan // Used with \".mts\" and \".cts\"\n\tLoaderTSX\n\tLoaderJSON\n\tLoaderText\n\tLoaderBase64\n\tLoaderDataURL\n\tLoaderFile\n\tLoaderBinary\n\tLoaderCSS\n\tLoaderDefault\n)\n\nfunc (loader Loader) IsTypeScript() bool {\n\tswitch loader {\n\tcase LoaderTS, LoaderTSNoAmbiguousLessThan, LoaderTSX:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc (loader Loader) CanHaveSourceMap() bool {\n\tswitch loader {\n\tcase LoaderJS, LoaderJSX, LoaderTS, LoaderTSNoAmbiguousLessThan, LoaderTSX, LoaderCSS:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\ntype Format uint8\n\nconst (\n\t// This is used when not bundling. It means to preserve whatever form the\n\t// import or export was originally in. ES6 syntax stays ES6 syntax and\n\t// CommonJS syntax stays CommonJS syntax.\n\tFormatPreserve Format = iota\n\n\t// IIFE stands for immediately-invoked function expression. That looks like\n\t// this:\n\t//\n\t//   (() => {\n\t//     ... bundled code ...\n\t//   })();\n\t//\n\t// If the optional GlobalName is configured, then we'll write out this:\n\t//\n\t//   let globalName = (() => {\n\t//     ... bundled code ...\n\t//     return exports;\n\t//   })();\n\t//\n\tFormatIIFE\n\n\t// The CommonJS format looks like this:\n\t//\n\t//   ... bundled code ...\n\t//   module.exports = exports;\n\t//\n\tFormatCommonJS\n\n\t// The ES module format looks like this:\n\t//\n\t//   ... bundled code ...\n\t//   export {...};\n\t//\n\tFormatESModule\n)\n\nfunc (f Format) KeepES6ImportExportSyntax() bool {\n\treturn f == FormatPreserve || f == FormatESModule\n}\n\nfunc (f Format) String() string {\n\tswitch f {\n\tcase FormatIIFE:\n\t\treturn \"iife\"\n\tcase FormatCommonJS:\n\t\treturn \"cjs\"\n\tcase FormatESModule:\n\t\treturn \"esm\"\n\t}\n\treturn \"\"\n}\n\ntype StdinInfo struct {\n\tContents      string\n\tSourceFile    string\n\tAbsResolveDir string\n\tLoader        Loader\n}\n\ntype WildcardPattern struct {\n\tPrefix string\n\tSuffix string\n}\n\ntype ExternalMatchers struct {\n\tExact    map[string]bool\n\tPatterns []WildcardPattern\n}\n\nfunc (matchers ExternalMatchers) HasMatchers() bool {\n\treturn len(matchers.Exact) > 0 || len(matchers.Patterns) > 0\n}\n\ntype ExternalSettings struct {\n\tPreResolve  ExternalMatchers\n\tPostResolve ExternalMatchers\n}\n\ntype Mode uint8\n\nconst (\n\tModePassThrough Mode = iota\n\tModeConvertFormat\n\tModeBundle\n)\n\ntype MaybeBool uint8\n\nconst (\n\tUnspecified MaybeBool = iota\n\tTrue\n\tFalse\n)\n\ntype Options struct {\n\tTSTarget     *TSTarget\n\tMangleProps  *regexp.Regexp\n\tReserveProps *regexp.Regexp\n\n\t// When mangling property names, call this function with a callback and do\n\t// the property name mangling inside the callback. The callback takes an\n\t// argument which is the mangle cache map to mutate. These callbacks are\n\t// serialized so mutating the map does not require extra synchronization.\n\t//\n\t// This is a callback for determinism reasons. We may be building multiple\n\t// entry points in parallel that are supposed to share a single cache. We\n\t// don't want the order that each entry point mangles properties in to cause\n\t// the output to change, so we serialize the property mangling over all entry\n\t// points in entry point order. However, we still want to link everything in\n\t// parallel so only property mangling is serialized, which is implemented by\n\t// this function blocking until the previous entry point's property mangling\n\t// has finished.\n\tExclusiveMangleCacheUpdate func(cb func(mangleCache map[string]interface{}))\n\n\t// This is the original information that was used to generate the\n\t// unsupported feature sets above. It's used for error messages.\n\tOriginalTargetEnv string\n\n\tExtensionOrder   []string\n\tMainFields       []string\n\tConditions       []string\n\tAbsNodePaths     []string // The \"NODE_PATH\" variable from Node.js\n\tExternalSettings ExternalSettings\n\n\tAbsOutputFile      string\n\tAbsOutputDir       string\n\tAbsOutputBase      string\n\tOutputExtensionJS  string\n\tOutputExtensionCSS string\n\tGlobalName         []string\n\tTsConfigOverride   string\n\tExtensionToLoader  map[string]Loader\n\n\tPublicPath      string\n\tInjectAbsPaths  []string\n\tInjectedDefines []InjectedDefine\n\tInjectedFiles   []InjectedFile\n\n\tJSBanner  string\n\tJSFooter  string\n\tCSSBanner string\n\tCSSFooter string\n\n\tEntryPathTemplate []PathTemplate\n\tChunkPathTemplate []PathTemplate\n\tAssetPathTemplate []PathTemplate\n\n\tPlugins    []Plugin\n\tSourceRoot string\n\tStdin      *StdinInfo\n\tJSX        JSXOptions\n\n\tUnsupportedJSFeatures  compat.JSFeature\n\tUnsupportedCSSFeatures compat.CSSFeature\n\n\tTS                TSOptions\n\tMode              Mode\n\tPreserveSymlinks  bool\n\tMinifyWhitespace  bool\n\tMinifyIdentifiers bool\n\tMinifySyntax      bool\n\tProfilerNames     bool\n\tCodeSplitting     bool\n\tWatchMode         bool\n\tAllowOverwrite    bool\n\tLegalComments     LegalComments\n\n\t// If true, make sure to generate a single file that can be written to stdout\n\tWriteToStdout bool\n\n\tOmitRuntimeForTests     bool\n\tUnusedImportsTS         UnusedImportsTS\n\tUseDefineForClassFields MaybeBool\n\tASCIIOnly               bool\n\tKeepNames               bool\n\tIgnoreDCEAnnotations    bool\n\tTreeShaking             bool\n\tDropDebugger            bool\n\tMangleQuoted            bool\n\tPlatform                Platform\n\tTargetFromAPI           TargetFromAPI\n\tOutputFormat            Format\n\tNeedsMetafile           bool\n\tSourceMap               SourceMap\n\tExcludeSourcesContent   bool\n}\n\ntype TargetFromAPI uint8\n\nconst (\n\t// In this state, the \"target\" field in \"tsconfig.json\" is respected\n\tTargetWasUnconfigured TargetFromAPI = iota\n\n\t// In this state, the \"target\" field in \"tsconfig.json\" is overridden\n\tTargetWasConfigured\n\n\t// In this state, \"useDefineForClassFields\" is true unless overridden\n\tTargetWasConfiguredIncludingESNext\n)\n\ntype UnusedImportsTS uint8\n\nconst (\n\t// \"import { unused } from 'foo'\" => \"\" (TypeScript's default behavior)\n\tUnusedImportsRemoveStmt UnusedImportsTS = iota\n\n\t// \"import { unused } from 'foo'\" => \"import 'foo'\" (\"importsNotUsedAsValues\" != \"remove\")\n\tUnusedImportsKeepStmtRemoveValues\n\n\t// \"import { unused } from 'foo'\" => \"import { unused } from 'foo'\" (\"preserveValueImports\" == true)\n\tUnusedImportsKeepValues\n)\n\nfunc UnusedImportsFromTsconfigValues(preserveImportsNotUsedAsValues bool, preserveValueImports bool) UnusedImportsTS {\n\tif preserveValueImports {\n\t\treturn UnusedImportsKeepValues\n\t}\n\tif preserveImportsNotUsedAsValues {\n\t\treturn UnusedImportsKeepStmtRemoveValues\n\t}\n\treturn UnusedImportsRemoveStmt\n}\n\ntype TSTarget struct {\n\tTarget                string\n\tSource                logger.Source\n\tRange                 logger.Range\n\tUnsupportedJSFeatures compat.JSFeature\n}\n\ntype PathPlaceholder uint8\n\nconst (\n\tNoPlaceholder PathPlaceholder = iota\n\n\t// The relative path from the original parent directory to the configured\n\t// \"outbase\" directory, or to the lowest common ancestor directory\n\tDirPlaceholder\n\n\t// The original name of the file, or the manual chunk name, or the name of\n\t// the type of output file (\"entry\" or \"chunk\" or \"asset\")\n\tNamePlaceholder\n\n\t// A hash of the contents of this file, and the contents and output paths of\n\t// all dependencies (except for their hash placeholders)\n\tHashPlaceholder\n\n\t// The original extension of the file, or the name of the output file\n\t// (e.g. \"css\", \"svg\", \"png\")\n\tExtPlaceholder\n)\n\ntype PathTemplate struct {\n\tData        string\n\tPlaceholder PathPlaceholder\n}\n\ntype PathPlaceholders struct {\n\tDir  *string\n\tName *string\n\tHash *string\n\tExt  *string\n}\n\nfunc (placeholders PathPlaceholders) Get(placeholder PathPlaceholder) *string {\n\tswitch placeholder {\n\tcase DirPlaceholder:\n\t\treturn placeholders.Dir\n\tcase NamePlaceholder:\n\t\treturn placeholders.Name\n\tcase HashPlaceholder:\n\t\treturn placeholders.Hash\n\tcase ExtPlaceholder:\n\t\treturn placeholders.Ext\n\t}\n\treturn nil\n}\n\nfunc TemplateToString(template []PathTemplate) string {\n\tif len(template) == 1 && template[0].Placeholder == NoPlaceholder {\n\t\t// Avoid allocations in this case\n\t\treturn template[0].Data\n\t}\n\tsb := strings.Builder{}\n\tfor _, part := range template {\n\t\tsb.WriteString(part.Data)\n\t\tswitch part.Placeholder {\n\t\tcase DirPlaceholder:\n\t\t\tsb.WriteString(\"[dir]\")\n\t\tcase NamePlaceholder:\n\t\t\tsb.WriteString(\"[name]\")\n\t\tcase HashPlaceholder:\n\t\t\tsb.WriteString(\"[hash]\")\n\t\tcase ExtPlaceholder:\n\t\t\tsb.WriteString(\"[ext]\")\n\t\t}\n\t}\n\treturn sb.String()\n}\n\nfunc HasPlaceholder(template []PathTemplate, placeholder PathPlaceholder) bool {\n\tfor _, part := range template {\n\t\tif part.Placeholder == placeholder {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc SubstituteTemplate(template []PathTemplate, placeholders PathPlaceholders) []PathTemplate {\n\t// Don't allocate if no substitution is possible and the template is already minimal\n\tshouldSubstitute := false\n\tfor i, part := range template {\n\t\tif placeholders.Get(part.Placeholder) != nil || (part.Placeholder == NoPlaceholder && i+1 < len(template)) {\n\t\t\tshouldSubstitute = true\n\t\t\tbreak\n\t\t}\n\t}\n\tif !shouldSubstitute {\n\t\treturn template\n\t}\n\n\t// Otherwise, substitute and merge as appropriate\n\tresult := make([]PathTemplate, 0, len(template))\n\tfor _, part := range template {\n\t\tif sub := placeholders.Get(part.Placeholder); sub != nil {\n\t\t\tpart.Data += *sub\n\t\t\tpart.Placeholder = NoPlaceholder\n\t\t}\n\t\tif last := len(result) - 1; last >= 0 && result[last].Placeholder == NoPlaceholder {\n\t\t\tlast := &result[last]\n\t\t\tlast.Data += part.Data\n\t\t\tlast.Placeholder = part.Placeholder\n\t\t} else {\n\t\t\tresult = append(result, part)\n\t\t}\n\t}\n\treturn result\n}\n\nfunc ShouldCallRuntimeRequire(mode Mode, outputFormat Format) bool {\n\treturn mode == ModeBundle && outputFormat != FormatCommonJS\n}\n\ntype InjectedDefine struct {\n\tName   string\n\tSource logger.Source\n}\n\ntype InjectedFile struct {\n\tExports    []InjectableExport\n\tDefineName string\n\tSource     logger.Source\n}\n\ntype InjectableExport struct {\n\tAlias string\n\tLoc   logger.Loc\n}\n\nvar filterMutex sync.Mutex\nvar filterCache map[string]*regexp.Regexp\n\nfunc compileFilter(filter string) (result *regexp.Regexp) {\n\tif filter == \"\" {\n\t\t// Must provide a filter\n\t\treturn nil\n\t}\n\tok := false\n\n\t// Cache hit?\n\t(func() {\n\t\tfilterMutex.Lock()\n\t\tdefer filterMutex.Unlock()\n\t\tif filterCache != nil {\n\t\t\tresult, ok = filterCache[filter]\n\t\t}\n\t})()\n\tif ok {\n\t\treturn\n\t}\n\n\t// Cache miss\n\tresult, err := regexp.Compile(filter)\n\tif err != nil {\n\t\treturn nil\n\t}\n\n\t// Cache for next time\n\tfilterMutex.Lock()\n\tdefer filterMutex.Unlock()\n\tif filterCache == nil {\n\t\tfilterCache = make(map[string]*regexp.Regexp)\n\t}\n\tfilterCache[filter] = result\n\treturn\n}\n\nfunc CompileFilterForPlugin(pluginName string, kind string, filter string) (*regexp.Regexp, error) {\n\tif filter == \"\" {\n\t\treturn nil, fmt.Errorf(\"[%s] %q is missing a filter\", pluginName, kind)\n\t}\n\n\tresult := compileFilter(filter)\n\tif result == nil {\n\t\treturn nil, fmt.Errorf(\"[%s] %q filter is not a valid Go regular expression: %q\", pluginName, kind, filter)\n\t}\n\n\treturn result, nil\n}\n\nfunc PluginAppliesToPath(path logger.Path, filter *regexp.Regexp, namespace string) bool {\n\treturn (namespace == \"\" || path.Namespace == namespace) && filter.MatchString(path.Text)\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Plugin API\n\ntype Plugin struct {\n\tName      string\n\tOnStart   []OnStart\n\tOnResolve []OnResolve\n\tOnLoad    []OnLoad\n}\n\ntype OnStart struct {\n\tCallback func() OnStartResult\n\tName     string\n}\n\ntype OnStartResult struct {\n\tThrownError error\n\tMsgs        []logger.Msg\n}\n\ntype OnResolve struct {\n\tFilter    *regexp.Regexp\n\tCallback  func(OnResolveArgs) OnResolveResult\n\tName      string\n\tNamespace string\n}\n\ntype OnResolveArgs struct {\n\tPath       string\n\tResolveDir string\n\tPluginData interface{}\n\tImporter   logger.Path\n\tKind       ast.ImportKind\n}\n\ntype OnResolveResult struct {\n\tPluginName string\n\n\tMsgs        []logger.Msg\n\tThrownError error\n\n\tAbsWatchFiles []string\n\tAbsWatchDirs  []string\n\n\tPluginData       interface{}\n\tPath             logger.Path\n\tExternal         bool\n\tIsSideEffectFree bool\n}\n\ntype OnLoad struct {\n\tFilter    *regexp.Regexp\n\tCallback  func(OnLoadArgs) OnLoadResult\n\tName      string\n\tNamespace string\n}\n\ntype OnLoadArgs struct {\n\tPluginData interface{}\n\tPath       logger.Path\n}\n\ntype OnLoadResult struct {\n\tPluginName string\n\n\tContents      *string\n\tAbsResolveDir string\n\tPluginData    interface{}\n\n\tMsgs        []logger.Msg\n\tThrownError error\n\n\tAbsWatchFiles []string\n\tAbsWatchDirs  []string\n\n\tLoader Loader\n}\n"
  },
  {
    "path": "lib/esbuild/config/globals.go",
    "content": "package config\n\nimport (\n\t\"sync\"\n)\n\nvar processedGlobalsMutex sync.Mutex\n\n// If something is in this list, then a direct identifier expression or property\n// access chain matching this will be assumed to have no side effects and will\n// be removed.\n//\n// This also means code is allowed to be reordered past things in this list. For\n// example, if \"console.log\" is in this list, permitting reordering allows for\n// \"if (a) console.log(b); else console.log(c)\" to be reordered and transformed\n// into \"console.log(a ? b : c)\". Notice that \"a\" and \"console.log\" are in a\n// different order, which can only happen if evaluating the \"console.log\"\n// property access can be assumed to not change the value of \"a\".\n//\n// Note that membership in this list says nothing about whether calling any of\n// these functions has any side effects. It only says something about\n// referencing these function without calling them.\nvar knownGlobals = [][]string{\n\t// These global identifiers should exist in all JavaScript environments. This\n\t// deliberately omits \"NaN\", \"Infinity\", and \"undefined\" because these are\n\t// treated as automatically-inlined constants instead of identifiers.\n\t{\"Array\"},\n\t{\"Boolean\"},\n\t{\"Function\"},\n\t{\"Math\"},\n\t{\"Number\"},\n\t{\"Object\"},\n\t{\"RegExp\"},\n\t{\"String\"},\n\n\t// Object: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Static_methods\n\t{\"Object\", \"assign\"},\n\t{\"Object\", \"create\"},\n\t{\"Object\", \"defineProperties\"},\n\t{\"Object\", \"defineProperty\"},\n\t{\"Object\", \"entries\"},\n\t{\"Object\", \"freeze\"},\n\t{\"Object\", \"fromEntries\"},\n\t{\"Object\", \"getOwnPropertyDescriptor\"},\n\t{\"Object\", \"getOwnPropertyDescriptors\"},\n\t{\"Object\", \"getOwnPropertyNames\"},\n\t{\"Object\", \"getOwnPropertySymbols\"},\n\t{\"Object\", \"getPrototypeOf\"},\n\t{\"Object\", \"is\"},\n\t{\"Object\", \"isExtensible\"},\n\t{\"Object\", \"isFrozen\"},\n\t{\"Object\", \"isSealed\"},\n\t{\"Object\", \"keys\"},\n\t{\"Object\", \"preventExtensions\"},\n\t{\"Object\", \"seal\"},\n\t{\"Object\", \"setPrototypeOf\"},\n\t{\"Object\", \"values\"},\n\n\t// Object: Instance methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object#Instance_methods\n\t{\"Object\", \"prototype\", \"__defineGetter__\"},\n\t{\"Object\", \"prototype\", \"__defineSetter__\"},\n\t{\"Object\", \"prototype\", \"__lookupGetter__\"},\n\t{\"Object\", \"prototype\", \"__lookupSetter__\"},\n\t{\"Object\", \"prototype\", \"hasOwnProperty\"},\n\t{\"Object\", \"prototype\", \"isPrototypeOf\"},\n\t{\"Object\", \"prototype\", \"propertyIsEnumerable\"},\n\t{\"Object\", \"prototype\", \"toLocaleString\"},\n\t{\"Object\", \"prototype\", \"toString\"},\n\t{\"Object\", \"prototype\", \"unwatch\"},\n\t{\"Object\", \"prototype\", \"valueOf\"},\n\t{\"Object\", \"prototype\", \"watch\"},\n\n\t// Math: Static properties\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#Static_properties\n\t{\"Math\", \"E\"},\n\t{\"Math\", \"LN10\"},\n\t{\"Math\", \"LN2\"},\n\t{\"Math\", \"LOG10E\"},\n\t{\"Math\", \"LOG2E\"},\n\t{\"Math\", \"PI\"},\n\t{\"Math\", \"SQRT1_2\"},\n\t{\"Math\", \"SQRT2\"},\n\n\t// Math: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#Static_methods\n\t{\"Math\", \"abs\"},\n\t{\"Math\", \"acos\"},\n\t{\"Math\", \"acosh\"},\n\t{\"Math\", \"asin\"},\n\t{\"Math\", \"asinh\"},\n\t{\"Math\", \"atan\"},\n\t{\"Math\", \"atan2\"},\n\t{\"Math\", \"atanh\"},\n\t{\"Math\", \"cbrt\"},\n\t{\"Math\", \"ceil\"},\n\t{\"Math\", \"clz32\"},\n\t{\"Math\", \"cos\"},\n\t{\"Math\", \"cosh\"},\n\t{\"Math\", \"exp\"},\n\t{\"Math\", \"expm1\"},\n\t{\"Math\", \"floor\"},\n\t{\"Math\", \"fround\"},\n\t{\"Math\", \"hypot\"},\n\t{\"Math\", \"imul\"},\n\t{\"Math\", \"log\"},\n\t{\"Math\", \"log10\"},\n\t{\"Math\", \"log1p\"},\n\t{\"Math\", \"log2\"},\n\t{\"Math\", \"max\"},\n\t{\"Math\", \"min\"},\n\t{\"Math\", \"pow\"},\n\t{\"Math\", \"random\"},\n\t{\"Math\", \"round\"},\n\t{\"Math\", \"sign\"},\n\t{\"Math\", \"sin\"},\n\t{\"Math\", \"sinh\"},\n\t{\"Math\", \"sqrt\"},\n\t{\"Math\", \"tan\"},\n\t{\"Math\", \"tanh\"},\n\t{\"Math\", \"trunc\"},\n\n\t// Reflect: Static methods\n\t// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect#static_methods\n\t{\"Reflect\", \"apply\"},\n\t{\"Reflect\", \"construct\"},\n\t{\"Reflect\", \"defineProperty\"},\n\t{\"Reflect\", \"deleteProperty\"},\n\t{\"Reflect\", \"get\"},\n\t{\"Reflect\", \"getOwnPropertyDescriptor\"},\n\t{\"Reflect\", \"getPrototypeOf\"},\n\t{\"Reflect\", \"has\"},\n\t{\"Reflect\", \"isExtensible\"},\n\t{\"Reflect\", \"ownKeys\"},\n\t{\"Reflect\", \"preventExtensions\"},\n\t{\"Reflect\", \"set\"},\n\t{\"Reflect\", \"setPrototypeOf\"},\n\n\t// Other globals present in both the browser and node (except \"eval\" because\n\t// it has special behavior)\n\t{\"AbortController\"},\n\t{\"AbortSignal\"},\n\t{\"AggregateError\"},\n\t{\"ArrayBuffer\"},\n\t{\"BigInt\"},\n\t{\"DataView\"},\n\t{\"Date\"},\n\t{\"Error\"},\n\t{\"EvalError\"},\n\t{\"Event\"},\n\t{\"EventTarget\"},\n\t{\"Float32Array\"},\n\t{\"Float64Array\"},\n\t{\"Int16Array\"},\n\t{\"Int32Array\"},\n\t{\"Int8Array\"},\n\t{\"Intl\"},\n\t{\"JSON\"},\n\t{\"Map\"},\n\t{\"MessageChannel\"},\n\t{\"MessageEvent\"},\n\t{\"MessagePort\"},\n\t{\"Promise\"},\n\t{\"Proxy\"},\n\t{\"RangeError\"},\n\t{\"ReferenceError\"},\n\t{\"Reflect\"},\n\t{\"Set\"},\n\t{\"Symbol\"},\n\t{\"SyntaxError\"},\n\t{\"TextDecoder\"},\n\t{\"TextEncoder\"},\n\t{\"TypeError\"},\n\t{\"URIError\"},\n\t{\"URL\"},\n\t{\"URLSearchParams\"},\n\t{\"Uint16Array\"},\n\t{\"Uint32Array\"},\n\t{\"Uint8Array\"},\n\t{\"Uint8ClampedArray\"},\n\t{\"WeakMap\"},\n\t{\"WeakSet\"},\n\t{\"WebAssembly\"},\n\t{\"clearInterval\"},\n\t{\"clearTimeout\"},\n\t{\"console\"},\n\t{\"decodeURI\"},\n\t{\"decodeURIComponent\"},\n\t{\"encodeURI\"},\n\t{\"encodeURIComponent\"},\n\t{\"escape\"},\n\t{\"globalThis\"},\n\t{\"isFinite\"},\n\t{\"isNaN\"},\n\t{\"parseFloat\"},\n\t{\"parseInt\"},\n\t{\"queueMicrotask\"},\n\t{\"setInterval\"},\n\t{\"setTimeout\"},\n\t{\"unescape\"},\n\n\t// Console method references are assumed to have no side effects\n\t// https://developer.mozilla.org/en-US/docs/Web/API/console\n\t{\"console\", \"assert\"},\n\t{\"console\", \"clear\"},\n\t{\"console\", \"count\"},\n\t{\"console\", \"countReset\"},\n\t{\"console\", \"debug\"},\n\t{\"console\", \"dir\"},\n\t{\"console\", \"dirxml\"},\n\t{\"console\", \"error\"},\n\t{\"console\", \"group\"},\n\t{\"console\", \"groupCollapsed\"},\n\t{\"console\", \"groupEnd\"},\n\t{\"console\", \"info\"},\n\t{\"console\", \"log\"},\n\t{\"console\", \"table\"},\n\t{\"console\", \"time\"},\n\t{\"console\", \"timeEnd\"},\n\t{\"console\", \"timeLog\"},\n\t{\"console\", \"trace\"},\n\t{\"console\", \"warn\"},\n\n\t// CSSOM APIs\n\t{\"CSSAnimation\"},\n\t{\"CSSFontFaceRule\"},\n\t{\"CSSImportRule\"},\n\t{\"CSSKeyframeRule\"},\n\t{\"CSSKeyframesRule\"},\n\t{\"CSSMediaRule\"},\n\t{\"CSSNamespaceRule\"},\n\t{\"CSSPageRule\"},\n\t{\"CSSRule\"},\n\t{\"CSSRuleList\"},\n\t{\"CSSStyleDeclaration\"},\n\t{\"CSSStyleRule\"},\n\t{\"CSSStyleSheet\"},\n\t{\"CSSSupportsRule\"},\n\t{\"CSSTransition\"},\n\n\t// SVG DOM\n\t{\"SVGAElement\"},\n\t{\"SVGAngle\"},\n\t{\"SVGAnimateElement\"},\n\t{\"SVGAnimateMotionElement\"},\n\t{\"SVGAnimateTransformElement\"},\n\t{\"SVGAnimatedAngle\"},\n\t{\"SVGAnimatedBoolean\"},\n\t{\"SVGAnimatedEnumeration\"},\n\t{\"SVGAnimatedInteger\"},\n\t{\"SVGAnimatedLength\"},\n\t{\"SVGAnimatedLengthList\"},\n\t{\"SVGAnimatedNumber\"},\n\t{\"SVGAnimatedNumberList\"},\n\t{\"SVGAnimatedPreserveAspectRatio\"},\n\t{\"SVGAnimatedRect\"},\n\t{\"SVGAnimatedString\"},\n\t{\"SVGAnimatedTransformList\"},\n\t{\"SVGAnimationElement\"},\n\t{\"SVGCircleElement\"},\n\t{\"SVGClipPathElement\"},\n\t{\"SVGComponentTransferFunctionElement\"},\n\t{\"SVGDefsElement\"},\n\t{\"SVGDescElement\"},\n\t{\"SVGElement\"},\n\t{\"SVGEllipseElement\"},\n\t{\"SVGFEBlendElement\"},\n\t{\"SVGFEColorMatrixElement\"},\n\t{\"SVGFEComponentTransferElement\"},\n\t{\"SVGFECompositeElement\"},\n\t{\"SVGFEConvolveMatrixElement\"},\n\t{\"SVGFEDiffuseLightingElement\"},\n\t{\"SVGFEDisplacementMapElement\"},\n\t{\"SVGFEDistantLightElement\"},\n\t{\"SVGFEDropShadowElement\"},\n\t{\"SVGFEFloodElement\"},\n\t{\"SVGFEFuncAElement\"},\n\t{\"SVGFEFuncBElement\"},\n\t{\"SVGFEFuncGElement\"},\n\t{\"SVGFEFuncRElement\"},\n\t{\"SVGFEGaussianBlurElement\"},\n\t{\"SVGFEImageElement\"},\n\t{\"SVGFEMergeElement\"},\n\t{\"SVGFEMergeNodeElement\"},\n\t{\"SVGFEMorphologyElement\"},\n\t{\"SVGFEOffsetElement\"},\n\t{\"SVGFEPointLightElement\"},\n\t{\"SVGFESpecularLightingElement\"},\n\t{\"SVGFESpotLightElement\"},\n\t{\"SVGFETileElement\"},\n\t{\"SVGFETurbulenceElement\"},\n\t{\"SVGFilterElement\"},\n\t{\"SVGForeignObjectElement\"},\n\t{\"SVGGElement\"},\n\t{\"SVGGeometryElement\"},\n\t{\"SVGGradientElement\"},\n\t{\"SVGGraphicsElement\"},\n\t{\"SVGImageElement\"},\n\t{\"SVGLength\"},\n\t{\"SVGLengthList\"},\n\t{\"SVGLineElement\"},\n\t{\"SVGLinearGradientElement\"},\n\t{\"SVGMPathElement\"},\n\t{\"SVGMarkerElement\"},\n\t{\"SVGMaskElement\"},\n\t{\"SVGMatrix\"},\n\t{\"SVGMetadataElement\"},\n\t{\"SVGNumber\"},\n\t{\"SVGNumberList\"},\n\t{\"SVGPathElement\"},\n\t{\"SVGPatternElement\"},\n\t{\"SVGPoint\"},\n\t{\"SVGPointList\"},\n\t{\"SVGPolygonElement\"},\n\t{\"SVGPolylineElement\"},\n\t{\"SVGPreserveAspectRatio\"},\n\t{\"SVGRadialGradientElement\"},\n\t{\"SVGRect\"},\n\t{\"SVGRectElement\"},\n\t{\"SVGSVGElement\"},\n\t{\"SVGScriptElement\"},\n\t{\"SVGSetElement\"},\n\t{\"SVGStopElement\"},\n\t{\"SVGStringList\"},\n\t{\"SVGStyleElement\"},\n\t{\"SVGSwitchElement\"},\n\t{\"SVGSymbolElement\"},\n\t{\"SVGTSpanElement\"},\n\t{\"SVGTextContentElement\"},\n\t{\"SVGTextElement\"},\n\t{\"SVGTextPathElement\"},\n\t{\"SVGTextPositioningElement\"},\n\t{\"SVGTitleElement\"},\n\t{\"SVGTransform\"},\n\t{\"SVGTransformList\"},\n\t{\"SVGUnitTypes\"},\n\t{\"SVGUseElement\"},\n\t{\"SVGViewElement\"},\n\n\t// Other browser APIs\n\t//\n\t// This list contains all globals present in modern versions of Chrome, Safari,\n\t// and Firefox except for the following properties, since they have a side effect\n\t// of triggering layout (https://gist.github.com/paulirish/5d52fb081b3570c81e3a):\n\t//\n\t//   - scrollX\n\t//   - scrollY\n\t//   - innerWidth\n\t//   - innerHeight\n\t//   - pageXOffset\n\t//   - pageYOffset\n\t//\n\t// The following globals have also been removed since they sometimes throw an\n\t// exception when accessed, which is a side effect (for more information see\n\t// https://stackoverflow.com/a/33047477):\n\t//\n\t//   - localStorage\n\t//   - sessionStorage\n\t//\n\t{\"AnalyserNode\"},\n\t{\"Animation\"},\n\t{\"AnimationEffect\"},\n\t{\"AnimationEvent\"},\n\t{\"AnimationPlaybackEvent\"},\n\t{\"AnimationTimeline\"},\n\t{\"Attr\"},\n\t{\"Audio\"},\n\t{\"AudioBuffer\"},\n\t{\"AudioBufferSourceNode\"},\n\t{\"AudioDestinationNode\"},\n\t{\"AudioListener\"},\n\t{\"AudioNode\"},\n\t{\"AudioParam\"},\n\t{\"AudioProcessingEvent\"},\n\t{\"AudioScheduledSourceNode\"},\n\t{\"BarProp\"},\n\t{\"BeforeUnloadEvent\"},\n\t{\"BiquadFilterNode\"},\n\t{\"Blob\"},\n\t{\"BlobEvent\"},\n\t{\"ByteLengthQueuingStrategy\"},\n\t{\"CDATASection\"},\n\t{\"CSS\"},\n\t{\"CanvasGradient\"},\n\t{\"CanvasPattern\"},\n\t{\"CanvasRenderingContext2D\"},\n\t{\"ChannelMergerNode\"},\n\t{\"ChannelSplitterNode\"},\n\t{\"CharacterData\"},\n\t{\"ClipboardEvent\"},\n\t{\"CloseEvent\"},\n\t{\"Comment\"},\n\t{\"CompositionEvent\"},\n\t{\"ConvolverNode\"},\n\t{\"CountQueuingStrategy\"},\n\t{\"Crypto\"},\n\t{\"CustomElementRegistry\"},\n\t{\"CustomEvent\"},\n\t{\"DOMException\"},\n\t{\"DOMImplementation\"},\n\t{\"DOMMatrix\"},\n\t{\"DOMMatrixReadOnly\"},\n\t{\"DOMParser\"},\n\t{\"DOMPoint\"},\n\t{\"DOMPointReadOnly\"},\n\t{\"DOMQuad\"},\n\t{\"DOMRect\"},\n\t{\"DOMRectList\"},\n\t{\"DOMRectReadOnly\"},\n\t{\"DOMStringList\"},\n\t{\"DOMStringMap\"},\n\t{\"DOMTokenList\"},\n\t{\"DataTransfer\"},\n\t{\"DataTransferItem\"},\n\t{\"DataTransferItemList\"},\n\t{\"DelayNode\"},\n\t{\"Document\"},\n\t{\"DocumentFragment\"},\n\t{\"DocumentTimeline\"},\n\t{\"DocumentType\"},\n\t{\"DragEvent\"},\n\t{\"DynamicsCompressorNode\"},\n\t{\"Element\"},\n\t{\"ErrorEvent\"},\n\t{\"EventSource\"},\n\t{\"File\"},\n\t{\"FileList\"},\n\t{\"FileReader\"},\n\t{\"FocusEvent\"},\n\t{\"FontFace\"},\n\t{\"FormData\"},\n\t{\"GainNode\"},\n\t{\"Gamepad\"},\n\t{\"GamepadButton\"},\n\t{\"GamepadEvent\"},\n\t{\"Geolocation\"},\n\t{\"GeolocationPositionError\"},\n\t{\"HTMLAllCollection\"},\n\t{\"HTMLAnchorElement\"},\n\t{\"HTMLAreaElement\"},\n\t{\"HTMLAudioElement\"},\n\t{\"HTMLBRElement\"},\n\t{\"HTMLBaseElement\"},\n\t{\"HTMLBodyElement\"},\n\t{\"HTMLButtonElement\"},\n\t{\"HTMLCanvasElement\"},\n\t{\"HTMLCollection\"},\n\t{\"HTMLDListElement\"},\n\t{\"HTMLDataElement\"},\n\t{\"HTMLDataListElement\"},\n\t{\"HTMLDetailsElement\"},\n\t{\"HTMLDirectoryElement\"},\n\t{\"HTMLDivElement\"},\n\t{\"HTMLDocument\"},\n\t{\"HTMLElement\"},\n\t{\"HTMLEmbedElement\"},\n\t{\"HTMLFieldSetElement\"},\n\t{\"HTMLFontElement\"},\n\t{\"HTMLFormControlsCollection\"},\n\t{\"HTMLFormElement\"},\n\t{\"HTMLFrameElement\"},\n\t{\"HTMLFrameSetElement\"},\n\t{\"HTMLHRElement\"},\n\t{\"HTMLHeadElement\"},\n\t{\"HTMLHeadingElement\"},\n\t{\"HTMLHtmlElement\"},\n\t{\"HTMLIFrameElement\"},\n\t{\"HTMLImageElement\"},\n\t{\"HTMLInputElement\"},\n\t{\"HTMLLIElement\"},\n\t{\"HTMLLabelElement\"},\n\t{\"HTMLLegendElement\"},\n\t{\"HTMLLinkElement\"},\n\t{\"HTMLMapElement\"},\n\t{\"HTMLMarqueeElement\"},\n\t{\"HTMLMediaElement\"},\n\t{\"HTMLMenuElement\"},\n\t{\"HTMLMetaElement\"},\n\t{\"HTMLMeterElement\"},\n\t{\"HTMLModElement\"},\n\t{\"HTMLOListElement\"},\n\t{\"HTMLObjectElement\"},\n\t{\"HTMLOptGroupElement\"},\n\t{\"HTMLOptionElement\"},\n\t{\"HTMLOptionsCollection\"},\n\t{\"HTMLOutputElement\"},\n\t{\"HTMLParagraphElement\"},\n\t{\"HTMLParamElement\"},\n\t{\"HTMLPictureElement\"},\n\t{\"HTMLPreElement\"},\n\t{\"HTMLProgressElement\"},\n\t{\"HTMLQuoteElement\"},\n\t{\"HTMLScriptElement\"},\n\t{\"HTMLSelectElement\"},\n\t{\"HTMLSlotElement\"},\n\t{\"HTMLSourceElement\"},\n\t{\"HTMLSpanElement\"},\n\t{\"HTMLStyleElement\"},\n\t{\"HTMLTableCaptionElement\"},\n\t{\"HTMLTableCellElement\"},\n\t{\"HTMLTableColElement\"},\n\t{\"HTMLTableElement\"},\n\t{\"HTMLTableRowElement\"},\n\t{\"HTMLTableSectionElement\"},\n\t{\"HTMLTemplateElement\"},\n\t{\"HTMLTextAreaElement\"},\n\t{\"HTMLTimeElement\"},\n\t{\"HTMLTitleElement\"},\n\t{\"HTMLTrackElement\"},\n\t{\"HTMLUListElement\"},\n\t{\"HTMLUnknownElement\"},\n\t{\"HTMLVideoElement\"},\n\t{\"HashChangeEvent\"},\n\t{\"Headers\"},\n\t{\"History\"},\n\t{\"IDBCursor\"},\n\t{\"IDBCursorWithValue\"},\n\t{\"IDBDatabase\"},\n\t{\"IDBFactory\"},\n\t{\"IDBIndex\"},\n\t{\"IDBKeyRange\"},\n\t{\"IDBObjectStore\"},\n\t{\"IDBOpenDBRequest\"},\n\t{\"IDBRequest\"},\n\t{\"IDBTransaction\"},\n\t{\"IDBVersionChangeEvent\"},\n\t{\"Image\"},\n\t{\"ImageData\"},\n\t{\"InputEvent\"},\n\t{\"IntersectionObserver\"},\n\t{\"IntersectionObserverEntry\"},\n\t{\"KeyboardEvent\"},\n\t{\"KeyframeEffect\"},\n\t{\"Location\"},\n\t{\"MediaCapabilities\"},\n\t{\"MediaElementAudioSourceNode\"},\n\t{\"MediaEncryptedEvent\"},\n\t{\"MediaError\"},\n\t{\"MediaList\"},\n\t{\"MediaQueryList\"},\n\t{\"MediaQueryListEvent\"},\n\t{\"MediaRecorder\"},\n\t{\"MediaSource\"},\n\t{\"MediaStream\"},\n\t{\"MediaStreamAudioDestinationNode\"},\n\t{\"MediaStreamAudioSourceNode\"},\n\t{\"MediaStreamTrack\"},\n\t{\"MediaStreamTrackEvent\"},\n\t{\"MimeType\"},\n\t{\"MimeTypeArray\"},\n\t{\"MouseEvent\"},\n\t{\"MutationEvent\"},\n\t{\"MutationObserver\"},\n\t{\"MutationRecord\"},\n\t{\"NamedNodeMap\"},\n\t{\"Navigator\"},\n\t{\"Node\"},\n\t{\"NodeFilter\"},\n\t{\"NodeIterator\"},\n\t{\"NodeList\"},\n\t{\"Notification\"},\n\t{\"OfflineAudioCompletionEvent\"},\n\t{\"Option\"},\n\t{\"OscillatorNode\"},\n\t{\"PageTransitionEvent\"},\n\t{\"Path2D\"},\n\t{\"Performance\"},\n\t{\"PerformanceEntry\"},\n\t{\"PerformanceMark\"},\n\t{\"PerformanceMeasure\"},\n\t{\"PerformanceNavigation\"},\n\t{\"PerformanceObserver\"},\n\t{\"PerformanceObserverEntryList\"},\n\t{\"PerformanceResourceTiming\"},\n\t{\"PerformanceTiming\"},\n\t{\"PeriodicWave\"},\n\t{\"Plugin\"},\n\t{\"PluginArray\"},\n\t{\"PointerEvent\"},\n\t{\"PopStateEvent\"},\n\t{\"ProcessingInstruction\"},\n\t{\"ProgressEvent\"},\n\t{\"PromiseRejectionEvent\"},\n\t{\"RTCCertificate\"},\n\t{\"RTCDTMFSender\"},\n\t{\"RTCDTMFToneChangeEvent\"},\n\t{\"RTCDataChannel\"},\n\t{\"RTCDataChannelEvent\"},\n\t{\"RTCIceCandidate\"},\n\t{\"RTCPeerConnection\"},\n\t{\"RTCPeerConnectionIceEvent\"},\n\t{\"RTCRtpReceiver\"},\n\t{\"RTCRtpSender\"},\n\t{\"RTCRtpTransceiver\"},\n\t{\"RTCSessionDescription\"},\n\t{\"RTCStatsReport\"},\n\t{\"RTCTrackEvent\"},\n\t{\"RadioNodeList\"},\n\t{\"Range\"},\n\t{\"ReadableStream\"},\n\t{\"Request\"},\n\t{\"ResizeObserver\"},\n\t{\"ResizeObserverEntry\"},\n\t{\"Response\"},\n\t{\"Screen\"},\n\t{\"ScriptProcessorNode\"},\n\t{\"SecurityPolicyViolationEvent\"},\n\t{\"Selection\"},\n\t{\"ShadowRoot\"},\n\t{\"SourceBuffer\"},\n\t{\"SourceBufferList\"},\n\t{\"SpeechSynthesisEvent\"},\n\t{\"SpeechSynthesisUtterance\"},\n\t{\"StaticRange\"},\n\t{\"Storage\"},\n\t{\"StorageEvent\"},\n\t{\"StyleSheet\"},\n\t{\"StyleSheetList\"},\n\t{\"Text\"},\n\t{\"TextMetrics\"},\n\t{\"TextTrack\"},\n\t{\"TextTrackCue\"},\n\t{\"TextTrackCueList\"},\n\t{\"TextTrackList\"},\n\t{\"TimeRanges\"},\n\t{\"TrackEvent\"},\n\t{\"TransitionEvent\"},\n\t{\"TreeWalker\"},\n\t{\"UIEvent\"},\n\t{\"VTTCue\"},\n\t{\"ValidityState\"},\n\t{\"VisualViewport\"},\n\t{\"WaveShaperNode\"},\n\t{\"WebGLActiveInfo\"},\n\t{\"WebGLBuffer\"},\n\t{\"WebGLContextEvent\"},\n\t{\"WebGLFramebuffer\"},\n\t{\"WebGLProgram\"},\n\t{\"WebGLQuery\"},\n\t{\"WebGLRenderbuffer\"},\n\t{\"WebGLRenderingContext\"},\n\t{\"WebGLSampler\"},\n\t{\"WebGLShader\"},\n\t{\"WebGLShaderPrecisionFormat\"},\n\t{\"WebGLSync\"},\n\t{\"WebGLTexture\"},\n\t{\"WebGLUniformLocation\"},\n\t{\"WebKitCSSMatrix\"},\n\t{\"WebSocket\"},\n\t{\"WheelEvent\"},\n\t{\"Window\"},\n\t{\"Worker\"},\n\t{\"XMLDocument\"},\n\t{\"XMLHttpRequest\"},\n\t{\"XMLHttpRequestEventTarget\"},\n\t{\"XMLHttpRequestUpload\"},\n\t{\"XMLSerializer\"},\n\t{\"XPathEvaluator\"},\n\t{\"XPathExpression\"},\n\t{\"XPathResult\"},\n\t{\"XSLTProcessor\"},\n\t{\"alert\"},\n\t{\"atob\"},\n\t{\"blur\"},\n\t{\"btoa\"},\n\t{\"cancelAnimationFrame\"},\n\t{\"captureEvents\"},\n\t{\"close\"},\n\t{\"closed\"},\n\t{\"confirm\"},\n\t{\"customElements\"},\n\t{\"devicePixelRatio\"},\n\t{\"document\"},\n\t{\"event\"},\n\t{\"fetch\"},\n\t{\"find\"},\n\t{\"focus\"},\n\t{\"frameElement\"},\n\t{\"frames\"},\n\t{\"getComputedStyle\"},\n\t{\"getSelection\"},\n\t{\"history\"},\n\t{\"indexedDB\"},\n\t{\"isSecureContext\"},\n\t{\"length\"},\n\t{\"location\"},\n\t{\"locationbar\"},\n\t{\"matchMedia\"},\n\t{\"menubar\"},\n\t{\"moveBy\"},\n\t{\"moveTo\"},\n\t{\"name\"},\n\t{\"navigator\"},\n\t{\"onabort\"},\n\t{\"onafterprint\"},\n\t{\"onanimationend\"},\n\t{\"onanimationiteration\"},\n\t{\"onanimationstart\"},\n\t{\"onbeforeprint\"},\n\t{\"onbeforeunload\"},\n\t{\"onblur\"},\n\t{\"oncanplay\"},\n\t{\"oncanplaythrough\"},\n\t{\"onchange\"},\n\t{\"onclick\"},\n\t{\"oncontextmenu\"},\n\t{\"oncuechange\"},\n\t{\"ondblclick\"},\n\t{\"ondrag\"},\n\t{\"ondragend\"},\n\t{\"ondragenter\"},\n\t{\"ondragleave\"},\n\t{\"ondragover\"},\n\t{\"ondragstart\"},\n\t{\"ondrop\"},\n\t{\"ondurationchange\"},\n\t{\"onemptied\"},\n\t{\"onended\"},\n\t{\"onerror\"},\n\t{\"onfocus\"},\n\t{\"ongotpointercapture\"},\n\t{\"onhashchange\"},\n\t{\"oninput\"},\n\t{\"oninvalid\"},\n\t{\"onkeydown\"},\n\t{\"onkeypress\"},\n\t{\"onkeyup\"},\n\t{\"onlanguagechange\"},\n\t{\"onload\"},\n\t{\"onloadeddata\"},\n\t{\"onloadedmetadata\"},\n\t{\"onloadstart\"},\n\t{\"onlostpointercapture\"},\n\t{\"onmessage\"},\n\t{\"onmousedown\"},\n\t{\"onmouseenter\"},\n\t{\"onmouseleave\"},\n\t{\"onmousemove\"},\n\t{\"onmouseout\"},\n\t{\"onmouseover\"},\n\t{\"onmouseup\"},\n\t{\"onoffline\"},\n\t{\"ononline\"},\n\t{\"onpagehide\"},\n\t{\"onpageshow\"},\n\t{\"onpause\"},\n\t{\"onplay\"},\n\t{\"onplaying\"},\n\t{\"onpointercancel\"},\n\t{\"onpointerdown\"},\n\t{\"onpointerenter\"},\n\t{\"onpointerleave\"},\n\t{\"onpointermove\"},\n\t{\"onpointerout\"},\n\t{\"onpointerover\"},\n\t{\"onpointerup\"},\n\t{\"onpopstate\"},\n\t{\"onprogress\"},\n\t{\"onratechange\"},\n\t{\"onrejectionhandled\"},\n\t{\"onreset\"},\n\t{\"onresize\"},\n\t{\"onscroll\"},\n\t{\"onseeked\"},\n\t{\"onseeking\"},\n\t{\"onselect\"},\n\t{\"onstalled\"},\n\t{\"onstorage\"},\n\t{\"onsubmit\"},\n\t{\"onsuspend\"},\n\t{\"ontimeupdate\"},\n\t{\"ontoggle\"},\n\t{\"ontransitioncancel\"},\n\t{\"ontransitionend\"},\n\t{\"ontransitionrun\"},\n\t{\"ontransitionstart\"},\n\t{\"onunhandledrejection\"},\n\t{\"onunload\"},\n\t{\"onvolumechange\"},\n\t{\"onwaiting\"},\n\t{\"onwebkitanimationend\"},\n\t{\"onwebkitanimationiteration\"},\n\t{\"onwebkitanimationstart\"},\n\t{\"onwebkittransitionend\"},\n\t{\"onwheel\"},\n\t{\"open\"},\n\t{\"opener\"},\n\t{\"origin\"},\n\t{\"outerHeight\"},\n\t{\"outerWidth\"},\n\t{\"parent\"},\n\t{\"performance\"},\n\t{\"personalbar\"},\n\t{\"postMessage\"},\n\t{\"print\"},\n\t{\"prompt\"},\n\t{\"releaseEvents\"},\n\t{\"requestAnimationFrame\"},\n\t{\"resizeBy\"},\n\t{\"resizeTo\"},\n\t{\"screen\"},\n\t{\"screenLeft\"},\n\t{\"screenTop\"},\n\t{\"screenX\"},\n\t{\"screenY\"},\n\t{\"scroll\"},\n\t{\"scrollBy\"},\n\t{\"scrollTo\"},\n\t{\"scrollbars\"},\n\t{\"self\"},\n\t{\"speechSynthesis\"},\n\t{\"status\"},\n\t{\"statusbar\"},\n\t{\"stop\"},\n\t{\"toolbar\"},\n\t{\"top\"},\n\t{\"webkitURL\"},\n\t{\"window\"},\n}\n\ntype DefineData struct {\n\n\t// True if accessing this value is known to not have any side effects. For\n\t// example, a bare reference to \"Object.create\" can be removed because it\n\t// does not have any observable side effects.\n\tCanBeRemovedIfUnused bool\n\n\t// True if a call to this value is known to not have any side effects. For\n\t// example, a bare call to \"Object()\" can be removed because it does not\n\t// have any observable side effects.\n\tCallCanBeUnwrappedIfUnused bool\n\n\t// If true, the user has indicated that every direct calls to a property on\n\t// this object and all of that call's arguments are to be removed from the\n\t// output, even when the arguments have side effects. This is used to\n\t// implement the \"--drop:console\" flag.\n\tMethodCallsMustBeReplacedWithUndefined bool\n}\n\nfunc mergeDefineData(old DefineData, new DefineData) DefineData {\n\tif old.CanBeRemovedIfUnused {\n\t\tnew.CanBeRemovedIfUnused = true\n\t}\n\tif old.CallCanBeUnwrappedIfUnused {\n\t\tnew.CallCanBeUnwrappedIfUnused = true\n\t}\n\treturn new\n}\n\ntype DotDefine struct {\n\tData  DefineData\n\tParts []string\n}\n\nfunc arePartsEqual(a []string, b []string) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i := range a {\n\t\tif a[i] != b[i] {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n"
  },
  {
    "path": "lib/esbuild/css_ast/css_ast.go",
    "content": "package css_ast\n\nimport (\n\t\"strconv\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n\t\"github.com/withastro/compiler/lib/esbuild/helpers\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\n// CSS syntax comes in two layers: a minimal syntax that generally accepts\n// anything that looks vaguely like CSS, and a large set of built-in rules\n// (the things browsers actually interpret). That way CSS parsers can read\n// unknown rules and skip over them without having to stop due to errors.\n//\n// This AST format is mostly just the minimal syntax. It parses unknown rules\n// into a tree with enough information that it can write them back out again.\n// There are some additional layers of syntax including selectors and @-rules\n// which allow for better pretty-printing and minification.\n//\n// Most of the AST just references ranges of the original file by keeping the\n// original \"Token\" values around from the lexer. This is a memory-efficient\n// representation that helps provide good parsing and printing performance.\n\ntype AST struct {\n\tImportRecords        []ast.ImportRecord\n\tRules                []Rule\n\tSourceMapComment     logger.Span\n\tApproximateLineCount int32\n}\n\n// We create a lot of tokens, so make sure this layout is memory-efficient.\n// The layout here isn't optimal because it biases for convenience (e.g.\n// \"string\" could be shorter) but at least the ordering of fields was\n// deliberately chosen to minimize size.\ntype Token struct {\n\t// Contains the child tokens for component values that are simple blocks.\n\t// These are either \"(\", \"{\", \"[\", or function tokens. The closing token is\n\t// implicit and is not stored.\n\tChildren *[]Token // 8 bytes\n\n\t// This is the raw contents of the token most of the time. However, it\n\t// contains the decoded string contents for \"TString\" tokens.\n\tText string // 16 bytes\n\n\t// URL tokens have an associated import record at the top-level of the AST.\n\t// This index points to that import record.\n\tImportRecordIndex uint32 // 4 bytes\n\n\t// The division between the number and the unit for \"TDimension\" tokens.\n\tUnitOffset uint16 // 2 bytes\n\n\t// This will never be \"TWhitespace\" because whitespace isn't stored as a\n\t// token directly. Instead it is stored in \"HasWhitespaceAfter\" on the\n\t// previous token. This is to make it easier to pattern-match against\n\t// tokens when handling CSS rules, since whitespace almost always doesn't\n\t// matter. That way you can pattern match against e.g. \"rgb(r, g, b)\" and\n\t// not have to handle all possible combinations of embedded whitespace\n\t// tokens.\n\t//\n\t// There is one exception to this: when in verbatim whitespace mode and\n\t// the token list is non-empty and is only whitespace tokens. In that case\n\t// a single whitespace token is emitted. This is because otherwise there\n\t// would be no tokens to attach the whitespace before/after flags to.\n\tKind css_lexer.T // 1 byte\n\n\t// These flags indicate the presence of a \"TWhitespace\" token before or after\n\t// this token. There should be whitespace printed between two tokens if either\n\t// token indicates that there should be whitespace. Note that whitespace may\n\t// be altered by processing in certain situations (e.g. minification).\n\tWhitespace WhitespaceFlags // 1 byte\n}\n\ntype WhitespaceFlags uint8\n\nconst (\n\tWhitespaceBefore WhitespaceFlags = 1 << iota\n\tWhitespaceAfter\n)\n\nfunc (a Token) Equal(b Token) bool {\n\tif a.Kind == b.Kind && a.Text == b.Text && a.ImportRecordIndex == b.ImportRecordIndex && a.Whitespace == b.Whitespace {\n\t\tif a.Children == nil && b.Children == nil {\n\t\t\treturn true\n\t\t}\n\n\t\tif a.Children != nil && b.Children != nil && TokensEqual(*a.Children, *b.Children) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc TokensEqual(a []Token, b []Token) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, c := range a {\n\t\tif !c.Equal(b[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc HashTokens(hash uint32, tokens []Token) uint32 {\n\thash = helpers.HashCombine(hash, uint32(len(tokens)))\n\n\tfor _, t := range tokens {\n\t\thash = helpers.HashCombine(hash, uint32(t.Kind))\n\t\thash = helpers.HashCombineString(hash, t.Text)\n\t\tif t.Children != nil {\n\t\t\thash = HashTokens(hash, *t.Children)\n\t\t}\n\t}\n\n\treturn hash\n}\n\nfunc (a Token) EqualIgnoringWhitespace(b Token) bool {\n\tif a.Kind == b.Kind && a.Text == b.Text && a.ImportRecordIndex == b.ImportRecordIndex {\n\t\tif a.Children == nil && b.Children == nil {\n\t\t\treturn true\n\t\t}\n\n\t\tif a.Children != nil && b.Children != nil && TokensEqualIgnoringWhitespace(*a.Children, *b.Children) {\n\t\t\treturn true\n\t\t}\n\t}\n\n\treturn false\n}\n\nfunc TokensEqualIgnoringWhitespace(a []Token, b []Token) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, c := range a {\n\t\tif !c.EqualIgnoringWhitespace(b[i]) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc TokensAreCommaSeparated(tokens []Token) bool {\n\tif n := len(tokens); (n & 1) != 0 {\n\t\tfor i := 1; i < n; i += 2 {\n\t\t\tif tokens[i].Kind != css_lexer.TComma {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (t Token) FractionForPercentage() (float64, bool) {\n\tif t.Kind == css_lexer.TPercentage {\n\t\tif f, err := strconv.ParseFloat(t.PercentageValue(), 64); err == nil {\n\t\t\tif f < 0 {\n\t\t\t\treturn 0, true\n\t\t\t}\n\t\t\tif f > 100 {\n\t\t\t\treturn 1, true\n\t\t\t}\n\t\t\treturn f / 100.0, true\n\t\t}\n\t}\n\treturn 0, false\n}\n\n// https://drafts.csswg.org/css-values-3/#lengths\n// For zero lengths the unit identifier is optional\n// (i.e. can be syntactically represented as the <number> 0).\nfunc (t *Token) TurnLengthIntoNumberIfZero() bool {\n\tif t.Kind == css_lexer.TDimension && t.DimensionValue() == \"0\" {\n\t\tt.Kind = css_lexer.TNumber\n\t\tt.Text = \"0\"\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (t *Token) TurnLengthOrPercentageIntoNumberIfZero() bool {\n\tif t.Kind == css_lexer.TPercentage && t.PercentageValue() == \"0\" {\n\t\tt.Kind = css_lexer.TNumber\n\t\tt.Text = \"0\"\n\t\treturn true\n\t}\n\treturn t.TurnLengthIntoNumberIfZero()\n}\n\nfunc (t Token) PercentageValue() string {\n\treturn t.Text[:len(t.Text)-1]\n}\n\nfunc (t Token) DimensionValue() string {\n\treturn t.Text[:t.UnitOffset]\n}\n\nfunc (t Token) DimensionUnit() string {\n\treturn t.Text[t.UnitOffset:]\n}\n\nfunc (t Token) DimensionUnitIsSafeLength() bool {\n\tswitch t.DimensionUnit() {\n\t// These units can be reasonably expected to be supported everywhere.\n\t// Information used: https://developer.mozilla.org/en-US/docs/Web/CSS/length\n\tcase \"cm\", \"em\", \"in\", \"mm\", \"pc\", \"pt\", \"px\":\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (t Token) IsZero() bool {\n\treturn t.Kind == css_lexer.TNumber && t.Text == \"0\"\n}\n\nfunc (t Token) IsOne() bool {\n\treturn t.Kind == css_lexer.TNumber && t.Text == \"1\"\n}\n\nfunc (t Token) IsAngle() bool {\n\tif t.Kind == css_lexer.TDimension {\n\t\tunit := t.DimensionUnit()\n\t\treturn unit == \"deg\" || unit == \"grad\" || unit == \"rad\" || unit == \"turn\"\n\t}\n\treturn false\n}\n\nfunc CloneTokensWithImportRecords(\n\ttokensIn []Token, importRecordsIn []ast.ImportRecord,\n\ttokensOut []Token, importRecordsOut []ast.ImportRecord,\n) ([]Token, []ast.ImportRecord) {\n\tfor _, t := range tokensIn {\n\t\t// If this is a URL token, also clone the import record\n\t\tif t.Kind == css_lexer.TURL {\n\t\t\timportRecordIndex := uint32(len(importRecordsOut))\n\t\t\timportRecordsOut = append(importRecordsOut, importRecordsIn[t.ImportRecordIndex])\n\t\t\tt.ImportRecordIndex = importRecordIndex\n\t\t}\n\n\t\t// Also search for URL tokens in this token's children\n\t\tif t.Children != nil {\n\t\t\tvar children []Token\n\t\t\tchildren, importRecordsOut = CloneTokensWithImportRecords(*t.Children, importRecordsIn, children, importRecordsOut)\n\t\t\tt.Children = &children\n\t\t}\n\n\t\ttokensOut = append(tokensOut, t)\n\t}\n\n\treturn tokensOut, importRecordsOut\n}\n\ntype Rule struct {\n\tData R\n\tLoc  logger.Loc\n}\n\ntype R interface {\n\tEqual(rule R) bool\n\tHash() (uint32, bool)\n}\n\nfunc RulesEqual(a []Rule, b []Rule) bool {\n\tif len(a) != len(b) {\n\t\treturn false\n\t}\n\tfor i, c := range a {\n\t\tif !c.Data.Equal(b[i].Data) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}\n\nfunc HashRules(hash uint32, rules []Rule) uint32 {\n\thash = helpers.HashCombine(hash, uint32(len(rules)))\n\tfor _, child := range rules {\n\t\tif childHash, ok := child.Data.Hash(); ok {\n\t\t\thash = helpers.HashCombine(hash, childHash)\n\t\t} else {\n\t\t\thash = helpers.HashCombine(hash, 0)\n\t\t}\n\t}\n\treturn hash\n}\n\ntype RAtCharset struct {\n\tEncoding string\n}\n\nfunc (a *RAtCharset) Equal(rule R) bool {\n\tb, ok := rule.(*RAtCharset)\n\treturn ok && a.Encoding == b.Encoding\n}\n\nfunc (r *RAtCharset) Hash() (uint32, bool) {\n\thash := uint32(1)\n\thash = helpers.HashCombineString(hash, r.Encoding)\n\treturn hash, true\n}\n\ntype RAtImport struct {\n\tImportConditions  []Token\n\tImportRecordIndex uint32\n}\n\nfunc (*RAtImport) Equal(rule R) bool {\n\treturn false\n}\n\nfunc (r *RAtImport) Hash() (uint32, bool) {\n\treturn 0, false\n}\n\ntype RAtKeyframes struct {\n\tAtToken string\n\tName    string\n\tBlocks  []KeyframeBlock\n}\n\ntype KeyframeBlock struct {\n\tSelectors []string\n\tRules     []Rule\n}\n\nfunc (a *RAtKeyframes) Equal(rule R) bool {\n\tif b, ok := rule.(*RAtKeyframes); ok && a.AtToken == b.AtToken && a.Name == b.Name && len(a.Blocks) == len(b.Blocks) {\n\t\tfor i, ai := range a.Blocks {\n\t\t\tbi := b.Blocks[i]\n\t\t\tif len(ai.Selectors) != len(bi.Selectors) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor j, aj := range ai.Selectors {\n\t\t\t\tif aj != bi.Selectors[j] {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t\tif !RulesEqual(ai.Rules, bi.Rules) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (r *RAtKeyframes) Hash() (uint32, bool) {\n\thash := uint32(2)\n\thash = helpers.HashCombineString(hash, r.AtToken)\n\thash = helpers.HashCombineString(hash, r.Name)\n\thash = helpers.HashCombine(hash, uint32(len(r.Blocks)))\n\tfor _, block := range r.Blocks {\n\t\thash = helpers.HashCombine(hash, uint32(len(block.Selectors)))\n\t\tfor _, sel := range block.Selectors {\n\t\t\thash = helpers.HashCombineString(hash, sel)\n\t\t}\n\t\thash = HashRules(hash, block.Rules)\n\t}\n\treturn hash, true\n}\n\ntype RKnownAt struct {\n\tAtToken string\n\tPrelude []Token\n\tRules   []Rule\n}\n\nfunc (a *RKnownAt) Equal(rule R) bool {\n\tb, ok := rule.(*RKnownAt)\n\treturn ok && a.AtToken == b.AtToken && TokensEqual(a.Prelude, b.Prelude) && RulesEqual(a.Rules, a.Rules)\n}\n\nfunc (r *RKnownAt) Hash() (uint32, bool) {\n\thash := uint32(3)\n\thash = helpers.HashCombineString(hash, r.AtToken)\n\thash = HashTokens(hash, r.Prelude)\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype RUnknownAt struct {\n\tAtToken string\n\tPrelude []Token\n\tBlock   []Token\n}\n\nfunc (a *RUnknownAt) Equal(rule R) bool {\n\tb, ok := rule.(*RUnknownAt)\n\treturn ok && a.AtToken == b.AtToken && TokensEqual(a.Prelude, b.Prelude) && TokensEqual(a.Block, a.Block)\n}\n\nfunc (r *RUnknownAt) Hash() (uint32, bool) {\n\thash := uint32(4)\n\thash = helpers.HashCombineString(hash, r.AtToken)\n\thash = HashTokens(hash, r.Prelude)\n\thash = HashTokens(hash, r.Block)\n\treturn hash, true\n}\n\ntype RSelector struct {\n\tSelectors []ComplexSelector\n\tRules     []Rule\n\tHasAtNest bool\n}\n\nfunc (a *RSelector) Equal(rule R) bool {\n\tb, ok := rule.(*RSelector)\n\tif ok && len(a.Selectors) == len(b.Selectors) && a.HasAtNest == b.HasAtNest {\n\t\tfor i, sel := range a.Selectors {\n\t\t\tif !sel.Equal(b.Selectors[i]) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn RulesEqual(a.Rules, b.Rules)\n\t}\n\n\treturn false\n}\n\nfunc (r *RSelector) Hash() (uint32, bool) {\n\thash := uint32(5)\n\thash = helpers.HashCombine(hash, uint32(len(r.Selectors)))\n\tfor _, complex := range r.Selectors {\n\t\thash = helpers.HashCombine(hash, uint32(len(complex.Selectors)))\n\t\tfor _, sel := range complex.Selectors {\n\t\t\tif sel.TypeSelector != nil {\n\t\t\t\thash = helpers.HashCombineString(hash, sel.TypeSelector.Name.Text)\n\t\t\t} else {\n\t\t\t\thash = helpers.HashCombine(hash, 0)\n\t\t\t}\n\t\t\thash = helpers.HashCombine(hash, uint32(len(sel.SubclassSelectors)))\n\t\t\tfor _, sub := range sel.SubclassSelectors {\n\t\t\t\thash = helpers.HashCombine(hash, sub.Hash())\n\t\t\t}\n\t\t\thash = helpers.HashCombineString(hash, sel.Combinator)\n\t\t}\n\t}\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype RQualified struct {\n\tPrelude []Token\n\tRules   []Rule\n}\n\nfunc (a *RQualified) Equal(rule R) bool {\n\tb, ok := rule.(*RQualified)\n\treturn ok && TokensEqual(a.Prelude, b.Prelude) && RulesEqual(a.Rules, b.Rules)\n}\n\nfunc (r *RQualified) Hash() (uint32, bool) {\n\thash := uint32(6)\n\thash = HashTokens(hash, r.Prelude)\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype RDeclaration struct {\n\tKeyText   string\n\tValue     []Token\n\tKeyRange  logger.Range\n\tKey       D // Compare using this instead of \"Key\" for speed\n\tImportant bool\n}\n\nfunc (a *RDeclaration) Equal(rule R) bool {\n\tb, ok := rule.(*RDeclaration)\n\treturn ok && a.KeyText == b.KeyText && TokensEqual(a.Value, b.Value) && a.Important == b.Important\n}\n\nfunc (r *RDeclaration) Hash() (uint32, bool) {\n\thash := uint32(7)\n\thash = helpers.HashCombine(hash, uint32(r.Key))\n\thash = HashTokens(hash, r.Value)\n\treturn hash, true\n}\n\ntype RBadDeclaration struct {\n\tTokens []Token\n}\n\nfunc (a *RBadDeclaration) Equal(rule R) bool {\n\tb, ok := rule.(*RBadDeclaration)\n\treturn ok && TokensEqual(a.Tokens, b.Tokens)\n}\n\nfunc (r *RBadDeclaration) Hash() (uint32, bool) {\n\thash := uint32(8)\n\thash = HashTokens(hash, r.Tokens)\n\treturn hash, true\n}\n\ntype RComment struct {\n\tText string\n}\n\nfunc (a *RComment) Equal(rule R) bool {\n\tb, ok := rule.(*RComment)\n\treturn ok && a.Text == b.Text\n}\n\nfunc (r *RComment) Hash() (uint32, bool) {\n\thash := uint32(9)\n\thash = helpers.HashCombineString(hash, r.Text)\n\treturn hash, true\n}\n\ntype RAtLayer struct {\n\tNames [][]string\n\tRules []Rule\n}\n\nfunc (a *RAtLayer) Equal(rule R) bool {\n\tif b, ok := rule.(*RAtLayer); ok && len(a.Names) == len(b.Names) && len(a.Rules) == len(b.Rules) {\n\t\tfor i, ai := range a.Names {\n\t\t\tbi := b.Names[i]\n\t\t\tif len(ai) != len(bi) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tfor j, aj := range ai {\n\t\t\t\tif aj != bi[j] {\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif !RulesEqual(a.Rules, b.Rules) {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (r *RAtLayer) Hash() (uint32, bool) {\n\thash := uint32(10)\n\thash = helpers.HashCombine(hash, uint32(len(r.Names)))\n\tfor _, parts := range r.Names {\n\t\thash = helpers.HashCombine(hash, uint32(len(parts)))\n\t\tfor _, part := range parts {\n\t\t\thash = helpers.HashCombineString(hash, part)\n\t\t}\n\t}\n\thash = HashRules(hash, r.Rules)\n\treturn hash, true\n}\n\ntype ComplexSelector struct {\n\tSelectors []CompoundSelector\n}\n\nfunc (a ComplexSelector) Equal(b ComplexSelector) bool {\n\tif len(a.Selectors) != len(b.Selectors) {\n\t\treturn false\n\t}\n\n\tfor i, ai := range a.Selectors {\n\t\tbi := b.Selectors[i]\n\t\tif ai.NestingSelector != bi.NestingSelector || ai.Combinator != bi.Combinator {\n\t\t\treturn false\n\t\t}\n\n\t\tif ats, bts := ai.TypeSelector, bi.TypeSelector; (ats == nil) != (bts == nil) {\n\t\t\treturn false\n\t\t} else if ats != nil && bts != nil && !ats.Equal(*bts) {\n\t\t\treturn false\n\t\t}\n\n\t\tif len(ai.SubclassSelectors) != len(bi.SubclassSelectors) {\n\t\t\treturn false\n\t\t}\n\t\tfor j, aj := range ai.SubclassSelectors {\n\t\t\tif !aj.Equal(bi.SubclassSelectors[j]) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t}\n\n\treturn true\n}\n\ntype NestingSelector uint8\n\nconst (\n\tNestingSelectorNone                NestingSelector = iota\n\tNestingSelectorPrefix                              // \"&a {}\"\n\tNestingSelectorPresentButNotPrefix                 // \"a& {}\"\n)\n\ntype CompoundSelector struct {\n\tCombinator        string // Optional, may be \"\"\n\tTypeSelector      *NamespacedName\n\tSubclassSelectors []SS\n\tNestingSelector   NestingSelector // \"&\"\n}\n\ntype NameToken struct {\n\tText string\n\tKind css_lexer.T\n}\n\ntype NamespacedName struct {\n\t// If present, this is an identifier or \"*\" and is followed by a \"|\" character\n\tNamespacePrefix *NameToken\n\n\t// This is an identifier or \"*\"\n\tName NameToken\n}\n\nfunc (a NamespacedName) Equal(b NamespacedName) bool {\n\treturn a.Name == b.Name && (a.NamespacePrefix == nil) == (b.NamespacePrefix == nil) &&\n\t\t(a.NamespacePrefix == nil || b.NamespacePrefix == nil || *a.NamespacePrefix == *b.NamespacePrefix)\n}\n\ntype SS interface {\n\tEqual(ss SS) bool\n\tHash() uint32\n}\n\ntype SSHash struct {\n\tName string\n}\n\nfunc (a *SSHash) Equal(ss SS) bool {\n\tb, ok := ss.(*SSHash)\n\treturn ok && a.Name == b.Name\n}\n\nfunc (ss *SSHash) Hash() uint32 {\n\thash := uint32(1)\n\thash = helpers.HashCombineString(hash, ss.Name)\n\treturn hash\n}\n\ntype SSClass struct {\n\tName string\n}\n\nfunc (a *SSClass) Equal(ss SS) bool {\n\tb, ok := ss.(*SSClass)\n\treturn ok && a.Name == b.Name\n}\n\nfunc (ss *SSClass) Hash() uint32 {\n\thash := uint32(2)\n\thash = helpers.HashCombineString(hash, ss.Name)\n\treturn hash\n}\n\ntype SSAttribute struct {\n\tMatcherOp       string // Either \"\" or one of: \"=\" \"~=\" \"|=\" \"^=\" \"$=\" \"*=\"\n\tMatcherValue    string\n\tNamespacedName  NamespacedName\n\tMatcherModifier byte // Either 0 or one of: 'i' 'I' 's' 'S'\n}\n\nfunc (a *SSAttribute) Equal(ss SS) bool {\n\tb, ok := ss.(*SSAttribute)\n\treturn ok && a.NamespacedName.Equal(b.NamespacedName) && a.MatcherOp == b.MatcherOp &&\n\t\ta.MatcherValue == b.MatcherValue && a.MatcherModifier == b.MatcherModifier\n}\n\nfunc (ss *SSAttribute) Hash() uint32 {\n\thash := uint32(3)\n\thash = helpers.HashCombineString(hash, ss.NamespacedName.Name.Text)\n\thash = helpers.HashCombineString(hash, ss.MatcherOp)\n\thash = helpers.HashCombineString(hash, ss.MatcherValue)\n\treturn hash\n}\n\ntype SSPseudoClass struct {\n\tName      string\n\tArgs      []Token\n\tIsElement bool // If true, this is prefixed by \"::\" instead of \":\"\n}\n\nfunc (a *SSPseudoClass) Equal(ss SS) bool {\n\tb, ok := ss.(*SSPseudoClass)\n\treturn ok && a.Name == b.Name && TokensEqual(a.Args, b.Args) && a.IsElement == b.IsElement\n}\n\nfunc (ss *SSPseudoClass) Hash() uint32 {\n\thash := uint32(4)\n\thash = helpers.HashCombineString(hash, ss.Name)\n\thash = HashTokens(hash, ss.Args)\n\treturn hash\n}\n"
  },
  {
    "path": "lib/esbuild/css_ast/css_decl_table.go",
    "content": "package css_ast\n\nimport (\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/helpers\"\n)\n\ntype D uint16\n\nconst (\n\tDUnknown D = iota\n\tDAlignContent\n\tDAlignItems\n\tDAlignSelf\n\tDAlignmentBaseline\n\tDAll\n\tDAnimation\n\tDAnimationDelay\n\tDAnimationDirection\n\tDAnimationDuration\n\tDAnimationFillMode\n\tDAnimationIterationCount\n\tDAnimationName\n\tDAnimationPlayState\n\tDAnimationTimingFunction\n\tDBackfaceVisibility\n\tDBackground\n\tDBackgroundAttachment\n\tDBackgroundClip\n\tDBackgroundColor\n\tDBackgroundImage\n\tDBackgroundOrigin\n\tDBackgroundPosition\n\tDBackgroundPositionX\n\tDBackgroundPositionY\n\tDBackgroundRepeat\n\tDBackgroundSize\n\tDBaselineShift\n\tDBlockSize\n\tDBorder\n\tDBorderBlockEnd\n\tDBorderBlockEndColor\n\tDBorderBlockEndStyle\n\tDBorderBlockEndWidth\n\tDBorderBlockStart\n\tDBorderBlockStartColor\n\tDBorderBlockStartStyle\n\tDBorderBlockStartWidth\n\tDBorderBottom\n\tDBorderBottomColor\n\tDBorderBottomLeftRadius\n\tDBorderBottomRightRadius\n\tDBorderBottomStyle\n\tDBorderBottomWidth\n\tDBorderCollapse\n\tDBorderColor\n\tDBorderImage\n\tDBorderImageOutset\n\tDBorderImageRepeat\n\tDBorderImageSlice\n\tDBorderImageSource\n\tDBorderImageWidth\n\tDBorderInlineEnd\n\tDBorderInlineEndColor\n\tDBorderInlineEndStyle\n\tDBorderInlineEndWidth\n\tDBorderInlineStart\n\tDBorderInlineStartColor\n\tDBorderInlineStartStyle\n\tDBorderInlineStartWidth\n\tDBorderLeft\n\tDBorderLeftColor\n\tDBorderLeftStyle\n\tDBorderLeftWidth\n\tDBorderRadius\n\tDBorderRight\n\tDBorderRightColor\n\tDBorderRightStyle\n\tDBorderRightWidth\n\tDBorderSpacing\n\tDBorderStyle\n\tDBorderTop\n\tDBorderTopColor\n\tDBorderTopLeftRadius\n\tDBorderTopRightRadius\n\tDBorderTopStyle\n\tDBorderTopWidth\n\tDBorderWidth\n\tDBottom\n\tDBoxShadow\n\tDBoxSizing\n\tDBreakAfter\n\tDBreakBefore\n\tDBreakInside\n\tDCaptionSide\n\tDCaretColor\n\tDClear\n\tDClip\n\tDClipPath\n\tDClipRule\n\tDColor\n\tDColorInterpolation\n\tDColorInterpolationFilters\n\tDColumnCount\n\tDColumnFill\n\tDColumnGap\n\tDColumnRule\n\tDColumnRuleColor\n\tDColumnRuleStyle\n\tDColumnRuleWidth\n\tDColumnSpan\n\tDColumnWidth\n\tDColumns\n\tDContent\n\tDCounterIncrement\n\tDCounterReset\n\tDCssFloat\n\tDCssText\n\tDCursor\n\tDDirection\n\tDDisplay\n\tDDominantBaseline\n\tDEmptyCells\n\tDFill\n\tDFillOpacity\n\tDFillRule\n\tDFilter\n\tDFlex\n\tDFlexBasis\n\tDFlexDirection\n\tDFlexFlow\n\tDFlexGrow\n\tDFlexShrink\n\tDFlexWrap\n\tDFloat\n\tDFloodColor\n\tDFloodOpacity\n\tDFont\n\tDFontFamily\n\tDFontFeatureSettings\n\tDFontKerning\n\tDFontSize\n\tDFontSizeAdjust\n\tDFontStretch\n\tDFontStyle\n\tDFontSynthesis\n\tDFontVariant\n\tDFontVariantCaps\n\tDFontVariantEastAsian\n\tDFontVariantLigatures\n\tDFontVariantNumeric\n\tDFontVariantPosition\n\tDFontWeight\n\tDGap\n\tDGlyphOrientationVertical\n\tDGrid\n\tDGridArea\n\tDGridAutoColumns\n\tDGridAutoFlow\n\tDGridAutoRows\n\tDGridColumn\n\tDGridColumnEnd\n\tDGridColumnGap\n\tDGridColumnStart\n\tDGridGap\n\tDGridRow\n\tDGridRowEnd\n\tDGridRowGap\n\tDGridRowStart\n\tDGridTemplate\n\tDGridTemplateAreas\n\tDGridTemplateColumns\n\tDGridTemplateRows\n\tDHeight\n\tDHyphens\n\tDImageOrientation\n\tDImageRendering\n\tDInlineSize\n\tDInset\n\tDJustifyContent\n\tDJustifyItems\n\tDJustifySelf\n\tDLeft\n\tDLetterSpacing\n\tDLightingColor\n\tDLineBreak\n\tDLineHeight\n\tDListStyle\n\tDListStyleImage\n\tDListStylePosition\n\tDListStyleType\n\tDMargin\n\tDMarginBlockEnd\n\tDMarginBlockStart\n\tDMarginBottom\n\tDMarginInlineEnd\n\tDMarginInlineStart\n\tDMarginLeft\n\tDMarginRight\n\tDMarginTop\n\tDMarker\n\tDMarkerEnd\n\tDMarkerMid\n\tDMarkerStart\n\tDMask\n\tDMaskComposite\n\tDMaskImage\n\tDMaskPosition\n\tDMaskRepeat\n\tDMaskSize\n\tDMaskType\n\tDMaxBlockSize\n\tDMaxHeight\n\tDMaxInlineSize\n\tDMaxWidth\n\tDMinBlockSize\n\tDMinHeight\n\tDMinInlineSize\n\tDMinWidth\n\tDObjectFit\n\tDObjectPosition\n\tDOpacity\n\tDOrder\n\tDOrphans\n\tDOutline\n\tDOutlineColor\n\tDOutlineOffset\n\tDOutlineStyle\n\tDOutlineWidth\n\tDOverflow\n\tDOverflowAnchor\n\tDOverflowWrap\n\tDOverflowX\n\tDOverflowY\n\tDOverscrollBehavior\n\tDOverscrollBehaviorBlock\n\tDOverscrollBehaviorInline\n\tDOverscrollBehaviorX\n\tDOverscrollBehaviorY\n\tDPadding\n\tDPaddingBlockEnd\n\tDPaddingBlockStart\n\tDPaddingBottom\n\tDPaddingInlineEnd\n\tDPaddingInlineStart\n\tDPaddingLeft\n\tDPaddingRight\n\tDPaddingTop\n\tDPageBreakAfter\n\tDPageBreakBefore\n\tDPageBreakInside\n\tDPaintOrder\n\tDPerspective\n\tDPerspectiveOrigin\n\tDPlaceContent\n\tDPlaceItems\n\tDPlaceSelf\n\tDPointerEvents\n\tDPosition\n\tDQuotes\n\tDResize\n\tDRight\n\tDRotate\n\tDRowGap\n\tDRubyAlign\n\tDRubyPosition\n\tDScale\n\tDScrollBehavior\n\tDShapeRendering\n\tDStopColor\n\tDStopOpacity\n\tDStroke\n\tDStrokeDasharray\n\tDStrokeDashoffset\n\tDStrokeLinecap\n\tDStrokeLinejoin\n\tDStrokeMiterlimit\n\tDStrokeOpacity\n\tDStrokeWidth\n\tDTabSize\n\tDTableLayout\n\tDTextAlign\n\tDTextAlignLast\n\tDTextAnchor\n\tDTextCombineUpright\n\tDTextDecoration\n\tDTextDecorationColor\n\tDTextDecorationLine\n\tDTextDecorationStyle\n\tDTextEmphasis\n\tDTextEmphasisColor\n\tDTextEmphasisPosition\n\tDTextEmphasisStyle\n\tDTextIndent\n\tDTextJustify\n\tDTextOrientation\n\tDTextOverflow\n\tDTextRendering\n\tDTextShadow\n\tDTextTransform\n\tDTextUnderlinePosition\n\tDTop\n\tDTouchAction\n\tDTransform\n\tDTransformBox\n\tDTransformOrigin\n\tDTransformStyle\n\tDTransition\n\tDTransitionDelay\n\tDTransitionDuration\n\tDTransitionProperty\n\tDTransitionTimingFunction\n\tDTranslate\n\tDUnicodeBidi\n\tDUserSelect\n\tDVerticalAlign\n\tDVisibility\n\tDWhiteSpace\n\tDWidows\n\tDWidth\n\tDWillChange\n\tDWordBreak\n\tDWordSpacing\n\tDWordWrap\n\tDWritingMode\n\tDZIndex\n\tDZoom\n)\n\nvar KnownDeclarations = map[string]D{\n\t\"align-content\":               DAlignContent,\n\t\"align-items\":                 DAlignItems,\n\t\"align-self\":                  DAlignSelf,\n\t\"alignment-baseline\":          DAlignmentBaseline,\n\t\"all\":                         DAll,\n\t\"animation\":                   DAnimation,\n\t\"animation-delay\":             DAnimationDelay,\n\t\"animation-direction\":         DAnimationDirection,\n\t\"animation-duration\":          DAnimationDuration,\n\t\"animation-fill-mode\":         DAnimationFillMode,\n\t\"animation-iteration-count\":   DAnimationIterationCount,\n\t\"animation-name\":              DAnimationName,\n\t\"animation-play-state\":        DAnimationPlayState,\n\t\"animation-timing-function\":   DAnimationTimingFunction,\n\t\"backface-visibility\":         DBackfaceVisibility,\n\t\"background\":                  DBackground,\n\t\"background-attachment\":       DBackgroundAttachment,\n\t\"background-clip\":             DBackgroundClip,\n\t\"background-color\":            DBackgroundColor,\n\t\"background-image\":            DBackgroundImage,\n\t\"background-origin\":           DBackgroundOrigin,\n\t\"background-position\":         DBackgroundPosition,\n\t\"background-position-x\":       DBackgroundPositionX,\n\t\"background-position-y\":       DBackgroundPositionY,\n\t\"background-repeat\":           DBackgroundRepeat,\n\t\"background-size\":             DBackgroundSize,\n\t\"baseline-shift\":              DBaselineShift,\n\t\"block-size\":                  DBlockSize,\n\t\"border\":                      DBorder,\n\t\"border-block-end\":            DBorderBlockEnd,\n\t\"border-block-end-color\":      DBorderBlockEndColor,\n\t\"border-block-end-style\":      DBorderBlockEndStyle,\n\t\"border-block-end-width\":      DBorderBlockEndWidth,\n\t\"border-block-start\":          DBorderBlockStart,\n\t\"border-block-start-color\":    DBorderBlockStartColor,\n\t\"border-block-start-style\":    DBorderBlockStartStyle,\n\t\"border-block-start-width\":    DBorderBlockStartWidth,\n\t\"border-bottom\":               DBorderBottom,\n\t\"border-bottom-color\":         DBorderBottomColor,\n\t\"border-bottom-left-radius\":   DBorderBottomLeftRadius,\n\t\"border-bottom-right-radius\":  DBorderBottomRightRadius,\n\t\"border-bottom-style\":         DBorderBottomStyle,\n\t\"border-bottom-width\":         DBorderBottomWidth,\n\t\"border-collapse\":             DBorderCollapse,\n\t\"border-color\":                DBorderColor,\n\t\"border-image\":                DBorderImage,\n\t\"border-image-outset\":         DBorderImageOutset,\n\t\"border-image-repeat\":         DBorderImageRepeat,\n\t\"border-image-slice\":          DBorderImageSlice,\n\t\"border-image-source\":         DBorderImageSource,\n\t\"border-image-width\":          DBorderImageWidth,\n\t\"border-inline-end\":           DBorderInlineEnd,\n\t\"border-inline-end-color\":     DBorderInlineEndColor,\n\t\"border-inline-end-style\":     DBorderInlineEndStyle,\n\t\"border-inline-end-width\":     DBorderInlineEndWidth,\n\t\"border-inline-start\":         DBorderInlineStart,\n\t\"border-inline-start-color\":   DBorderInlineStartColor,\n\t\"border-inline-start-style\":   DBorderInlineStartStyle,\n\t\"border-inline-start-width\":   DBorderInlineStartWidth,\n\t\"border-left\":                 DBorderLeft,\n\t\"border-left-color\":           DBorderLeftColor,\n\t\"border-left-style\":           DBorderLeftStyle,\n\t\"border-left-width\":           DBorderLeftWidth,\n\t\"border-radius\":               DBorderRadius,\n\t\"border-right\":                DBorderRight,\n\t\"border-right-color\":          DBorderRightColor,\n\t\"border-right-style\":          DBorderRightStyle,\n\t\"border-right-width\":          DBorderRightWidth,\n\t\"border-spacing\":              DBorderSpacing,\n\t\"border-style\":                DBorderStyle,\n\t\"border-top\":                  DBorderTop,\n\t\"border-top-color\":            DBorderTopColor,\n\t\"border-top-left-radius\":      DBorderTopLeftRadius,\n\t\"border-top-right-radius\":     DBorderTopRightRadius,\n\t\"border-top-style\":            DBorderTopStyle,\n\t\"border-top-width\":            DBorderTopWidth,\n\t\"border-width\":                DBorderWidth,\n\t\"bottom\":                      DBottom,\n\t\"box-shadow\":                  DBoxShadow,\n\t\"box-sizing\":                  DBoxSizing,\n\t\"break-after\":                 DBreakAfter,\n\t\"break-before\":                DBreakBefore,\n\t\"break-inside\":                DBreakInside,\n\t\"caption-side\":                DCaptionSide,\n\t\"caret-color\":                 DCaretColor,\n\t\"clear\":                       DClear,\n\t\"clip\":                        DClip,\n\t\"clip-path\":                   DClipPath,\n\t\"clip-rule\":                   DClipRule,\n\t\"color\":                       DColor,\n\t\"color-interpolation\":         DColorInterpolation,\n\t\"color-interpolation-filters\": DColorInterpolationFilters,\n\t\"column-count\":                DColumnCount,\n\t\"column-fill\":                 DColumnFill,\n\t\"column-gap\":                  DColumnGap,\n\t\"column-rule\":                 DColumnRule,\n\t\"column-rule-color\":           DColumnRuleColor,\n\t\"column-rule-style\":           DColumnRuleStyle,\n\t\"column-rule-width\":           DColumnRuleWidth,\n\t\"column-span\":                 DColumnSpan,\n\t\"column-width\":                DColumnWidth,\n\t\"columns\":                     DColumns,\n\t\"content\":                     DContent,\n\t\"counter-increment\":           DCounterIncrement,\n\t\"counter-reset\":               DCounterReset,\n\t\"css-float\":                   DCssFloat,\n\t\"css-text\":                    DCssText,\n\t\"cursor\":                      DCursor,\n\t\"direction\":                   DDirection,\n\t\"display\":                     DDisplay,\n\t\"dominant-baseline\":           DDominantBaseline,\n\t\"empty-cells\":                 DEmptyCells,\n\t\"fill\":                        DFill,\n\t\"fill-opacity\":                DFillOpacity,\n\t\"fill-rule\":                   DFillRule,\n\t\"filter\":                      DFilter,\n\t\"flex\":                        DFlex,\n\t\"flex-basis\":                  DFlexBasis,\n\t\"flex-direction\":              DFlexDirection,\n\t\"flex-flow\":                   DFlexFlow,\n\t\"flex-grow\":                   DFlexGrow,\n\t\"flex-shrink\":                 DFlexShrink,\n\t\"flex-wrap\":                   DFlexWrap,\n\t\"float\":                       DFloat,\n\t\"flood-color\":                 DFloodColor,\n\t\"flood-opacity\":               DFloodOpacity,\n\t\"font\":                        DFont,\n\t\"font-family\":                 DFontFamily,\n\t\"font-feature-settings\":       DFontFeatureSettings,\n\t\"font-kerning\":                DFontKerning,\n\t\"font-size\":                   DFontSize,\n\t\"font-size-adjust\":            DFontSizeAdjust,\n\t\"font-stretch\":                DFontStretch,\n\t\"font-style\":                  DFontStyle,\n\t\"font-synthesis\":              DFontSynthesis,\n\t\"font-variant\":                DFontVariant,\n\t\"font-variant-caps\":           DFontVariantCaps,\n\t\"font-variant-east-asian\":     DFontVariantEastAsian,\n\t\"font-variant-ligatures\":      DFontVariantLigatures,\n\t\"font-variant-numeric\":        DFontVariantNumeric,\n\t\"font-variant-position\":       DFontVariantPosition,\n\t\"font-weight\":                 DFontWeight,\n\t\"gap\":                         DGap,\n\t\"glyph-orientation-vertical\":  DGlyphOrientationVertical,\n\t\"grid\":                        DGrid,\n\t\"grid-area\":                   DGridArea,\n\t\"grid-auto-columns\":           DGridAutoColumns,\n\t\"grid-auto-flow\":              DGridAutoFlow,\n\t\"grid-auto-rows\":              DGridAutoRows,\n\t\"grid-column\":                 DGridColumn,\n\t\"grid-column-end\":             DGridColumnEnd,\n\t\"grid-column-gap\":             DGridColumnGap,\n\t\"grid-column-start\":           DGridColumnStart,\n\t\"grid-gap\":                    DGridGap,\n\t\"grid-row\":                    DGridRow,\n\t\"grid-row-end\":                DGridRowEnd,\n\t\"grid-row-gap\":                DGridRowGap,\n\t\"grid-row-start\":              DGridRowStart,\n\t\"grid-template\":               DGridTemplate,\n\t\"grid-template-areas\":         DGridTemplateAreas,\n\t\"grid-template-columns\":       DGridTemplateColumns,\n\t\"grid-template-rows\":          DGridTemplateRows,\n\t\"height\":                      DHeight,\n\t\"hyphens\":                     DHyphens,\n\t\"image-orientation\":           DImageOrientation,\n\t\"image-rendering\":             DImageRendering,\n\t\"inline-size\":                 DInlineSize,\n\t\"inset\":                       DInset,\n\t\"justify-content\":             DJustifyContent,\n\t\"justify-items\":               DJustifyItems,\n\t\"justify-self\":                DJustifySelf,\n\t\"left\":                        DLeft,\n\t\"letter-spacing\":              DLetterSpacing,\n\t\"lighting-color\":              DLightingColor,\n\t\"line-break\":                  DLineBreak,\n\t\"line-height\":                 DLineHeight,\n\t\"list-style\":                  DListStyle,\n\t\"list-style-image\":            DListStyleImage,\n\t\"list-style-position\":         DListStylePosition,\n\t\"list-style-type\":             DListStyleType,\n\t\"margin\":                      DMargin,\n\t\"margin-block-end\":            DMarginBlockEnd,\n\t\"margin-block-start\":          DMarginBlockStart,\n\t\"margin-bottom\":               DMarginBottom,\n\t\"margin-inline-end\":           DMarginInlineEnd,\n\t\"margin-inline-start\":         DMarginInlineStart,\n\t\"margin-left\":                 DMarginLeft,\n\t\"margin-right\":                DMarginRight,\n\t\"margin-top\":                  DMarginTop,\n\t\"marker\":                      DMarker,\n\t\"marker-end\":                  DMarkerEnd,\n\t\"marker-mid\":                  DMarkerMid,\n\t\"marker-start\":                DMarkerStart,\n\t\"mask\":                        DMask,\n\t\"mask-composite\":              DMaskComposite,\n\t\"mask-image\":                  DMaskImage,\n\t\"mask-position\":               DMaskPosition,\n\t\"mask-repeat\":                 DMaskRepeat,\n\t\"mask-size\":                   DMaskSize,\n\t\"mask-type\":                   DMaskType,\n\t\"max-block-size\":              DMaxBlockSize,\n\t\"max-height\":                  DMaxHeight,\n\t\"max-inline-size\":             DMaxInlineSize,\n\t\"max-width\":                   DMaxWidth,\n\t\"min-block-size\":              DMinBlockSize,\n\t\"min-height\":                  DMinHeight,\n\t\"min-inline-size\":             DMinInlineSize,\n\t\"min-width\":                   DMinWidth,\n\t\"object-fit\":                  DObjectFit,\n\t\"object-position\":             DObjectPosition,\n\t\"opacity\":                     DOpacity,\n\t\"order\":                       DOrder,\n\t\"orphans\":                     DOrphans,\n\t\"outline\":                     DOutline,\n\t\"outline-color\":               DOutlineColor,\n\t\"outline-offset\":              DOutlineOffset,\n\t\"outline-style\":               DOutlineStyle,\n\t\"outline-width\":               DOutlineWidth,\n\t\"overflow\":                    DOverflow,\n\t\"overflow-anchor\":             DOverflowAnchor,\n\t\"overflow-wrap\":               DOverflowWrap,\n\t\"overflow-x\":                  DOverflowX,\n\t\"overflow-y\":                  DOverflowY,\n\t\"overscroll-behavior\":         DOverscrollBehavior,\n\t\"overscroll-behavior-block\":   DOverscrollBehaviorBlock,\n\t\"overscroll-behavior-inline\":  DOverscrollBehaviorInline,\n\t\"overscroll-behavior-x\":       DOverscrollBehaviorX,\n\t\"overscroll-behavior-y\":       DOverscrollBehaviorY,\n\t\"padding\":                     DPadding,\n\t\"padding-block-end\":           DPaddingBlockEnd,\n\t\"padding-block-start\":         DPaddingBlockStart,\n\t\"padding-bottom\":              DPaddingBottom,\n\t\"padding-inline-end\":          DPaddingInlineEnd,\n\t\"padding-inline-start\":        DPaddingInlineStart,\n\t\"padding-left\":                DPaddingLeft,\n\t\"padding-right\":               DPaddingRight,\n\t\"padding-top\":                 DPaddingTop,\n\t\"page-break-after\":            DPageBreakAfter,\n\t\"page-break-before\":           DPageBreakBefore,\n\t\"page-break-inside\":           DPageBreakInside,\n\t\"paint-order\":                 DPaintOrder,\n\t\"perspective\":                 DPerspective,\n\t\"perspective-origin\":          DPerspectiveOrigin,\n\t\"place-content\":               DPlaceContent,\n\t\"place-items\":                 DPlaceItems,\n\t\"place-self\":                  DPlaceSelf,\n\t\"pointer-events\":              DPointerEvents,\n\t\"position\":                    DPosition,\n\t\"quotes\":                      DQuotes,\n\t\"resize\":                      DResize,\n\t\"right\":                       DRight,\n\t\"rotate\":                      DRotate,\n\t\"row-gap\":                     DRowGap,\n\t\"ruby-align\":                  DRubyAlign,\n\t\"ruby-position\":               DRubyPosition,\n\t\"scale\":                       DScale,\n\t\"scroll-behavior\":             DScrollBehavior,\n\t\"shape-rendering\":             DShapeRendering,\n\t\"stop-color\":                  DStopColor,\n\t\"stop-opacity\":                DStopOpacity,\n\t\"stroke\":                      DStroke,\n\t\"stroke-dasharray\":            DStrokeDasharray,\n\t\"stroke-dashoffset\":           DStrokeDashoffset,\n\t\"stroke-linecap\":              DStrokeLinecap,\n\t\"stroke-linejoin\":             DStrokeLinejoin,\n\t\"stroke-miterlimit\":           DStrokeMiterlimit,\n\t\"stroke-opacity\":              DStrokeOpacity,\n\t\"stroke-width\":                DStrokeWidth,\n\t\"tab-size\":                    DTabSize,\n\t\"table-layout\":                DTableLayout,\n\t\"text-align\":                  DTextAlign,\n\t\"text-align-last\":             DTextAlignLast,\n\t\"text-anchor\":                 DTextAnchor,\n\t\"text-combine-upright\":        DTextCombineUpright,\n\t\"text-decoration\":             DTextDecoration,\n\t\"text-decoration-color\":       DTextDecorationColor,\n\t\"text-decoration-line\":        DTextDecorationLine,\n\t\"text-decoration-style\":       DTextDecorationStyle,\n\t\"text-emphasis\":               DTextEmphasis,\n\t\"text-emphasis-color\":         DTextEmphasisColor,\n\t\"text-emphasis-position\":      DTextEmphasisPosition,\n\t\"text-emphasis-style\":         DTextEmphasisStyle,\n\t\"text-indent\":                 DTextIndent,\n\t\"text-justify\":                DTextJustify,\n\t\"text-orientation\":            DTextOrientation,\n\t\"text-overflow\":               DTextOverflow,\n\t\"text-rendering\":              DTextRendering,\n\t\"text-shadow\":                 DTextShadow,\n\t\"text-transform\":              DTextTransform,\n\t\"text-underline-position\":     DTextUnderlinePosition,\n\t\"top\":                         DTop,\n\t\"touch-action\":                DTouchAction,\n\t\"transform\":                   DTransform,\n\t\"transform-box\":               DTransformBox,\n\t\"transform-origin\":            DTransformOrigin,\n\t\"transform-style\":             DTransformStyle,\n\t\"transition\":                  DTransition,\n\t\"transition-delay\":            DTransitionDelay,\n\t\"transition-duration\":         DTransitionDuration,\n\t\"transition-property\":         DTransitionProperty,\n\t\"transition-timing-function\":  DTransitionTimingFunction,\n\t\"translate\":                   DTranslate,\n\t\"unicode-bidi\":                DUnicodeBidi,\n\t\"user-select\":                 DUserSelect,\n\t\"vertical-align\":              DVerticalAlign,\n\t\"visibility\":                  DVisibility,\n\t\"white-space\":                 DWhiteSpace,\n\t\"widows\":                      DWidows,\n\t\"width\":                       DWidth,\n\t\"will-change\":                 DWillChange,\n\t\"word-break\":                  DWordBreak,\n\t\"word-spacing\":                DWordSpacing,\n\t\"word-wrap\":                   DWordWrap,\n\t\"writing-mode\":                DWritingMode,\n\t\"z-index\":                     DZIndex,\n\t\"zoom\":                        DZoom,\n}\n\nvar typoDetector *helpers.TypoDetector\nvar typoDetectorMutex sync.Mutex\n\nfunc MaybeCorrectDeclarationTypo(text string) (string, bool) {\n\t// Ignore CSS variables, which should not be corrected to CSS properties\n\tif strings.HasPrefix(text, \"--\") {\n\t\treturn \"\", false\n\t}\n\n\ttypoDetectorMutex.Lock()\n\tdefer typoDetectorMutex.Unlock()\n\n\t// Lazily-initialize the typo detector for speed when it's not needed\n\tif typoDetector == nil {\n\t\tvalid := make([]string, 0, len(KnownDeclarations))\n\t\tfor key := range KnownDeclarations {\n\t\t\tvalid = append(valid, key)\n\t\t}\n\t\tdetector := helpers.MakeTypoDetector(valid)\n\t\ttypoDetector = &detector\n\t}\n\n\treturn typoDetector.MaybeCorrectTypo(text)\n}\n"
  },
  {
    "path": "lib/esbuild/css_lexer/css_lexer.go",
    "content": "package css_lexer\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/helpers\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\n// The lexer converts a source file to a stream of tokens. Unlike esbuild's\n// JavaScript lexer, this CSS lexer runs to completion before the CSS parser\n// begins, resulting in a single array of all tokens in the file.\n\ntype T uint8\n\nconst eof = -1\n\nconst (\n\tTEndOfFile T = iota\n\n\tTAtKeyword\n\tTBadString\n\tTBadURL\n\tTCDC // \"-->\"\n\tTCDO // \"<!--\"\n\tTCloseBrace\n\tTCloseBracket\n\tTCloseParen\n\tTColon\n\tTComma\n\tTDelim\n\tTDelimAmpersand\n\tTDelimAsterisk\n\tTDelimBar\n\tTDelimCaret\n\tTDelimDollar\n\tTDelimDot\n\tTDelimEquals\n\tTDelimExclamation\n\tTDelimGreaterThan\n\tTDelimMinus\n\tTDelimPlus\n\tTDelimSlash\n\tTDelimTilde\n\tTDimension\n\tTFunction\n\tTHash\n\tTIdent\n\tTNumber\n\tTOpenBrace\n\tTOpenBracket\n\tTOpenParen\n\tTPercentage\n\tTSemicolon\n\tTString\n\tTURL\n\tTWhitespace\n)\n\nvar tokenToString = []string{\n\t\"end of file\",\n\t\"@-keyword\",\n\t\"bad string token\",\n\t\"bad URL token\",\n\t\"\\\"-->\\\"\",\n\t\"\\\"<!--\\\"\",\n\t\"\\\"}\\\"\",\n\t\"\\\"]\\\"\",\n\t\"\\\")\\\"\",\n\t\"\\\":\\\"\",\n\t\"\\\",\\\"\",\n\t\"delimiter\",\n\t\"\\\"&\\\"\",\n\t\"\\\"*\\\"\",\n\t\"\\\"|\\\"\",\n\t\"\\\"^\\\"\",\n\t\"\\\"$\\\"\",\n\t\"\\\".\\\"\",\n\t\"\\\"=\\\"\",\n\t\"\\\"!\\\"\",\n\t\"\\\">\\\"\",\n\t\"\\\"-\\\"\",\n\t\"\\\"+\\\"\",\n\t\"\\\"/\\\"\",\n\t\"\\\"~\\\"\",\n\t\"dimension\",\n\t\"function token\",\n\t\"hash token\",\n\t\"identifier\",\n\t\"number\",\n\t\"\\\"{\\\"\",\n\t\"\\\"[\\\"\",\n\t\"\\\"(\\\"\",\n\t\"percentage\",\n\t\"\\\";\\\"\",\n\t\"string token\",\n\t\"URL token\",\n\t\"whitespace\",\n}\n\nfunc (t T) String() string {\n\treturn tokenToString[t]\n}\n\nfunc (t T) IsNumeric() bool {\n\treturn t == TNumber || t == TPercentage || t == TDimension\n}\n\ntype TokenFlags uint8\n\nconst (\n\tIsID TokenFlags = 1 << iota\n\tDidWarnAboutSingleLineComment\n)\n\n// This token struct is designed to be memory-efficient. It just references a\n// range in the input file instead of directly containing the substring of text\n// since a range takes up less memory than a string.\ntype Token struct {\n\tRange      logger.Range // 8 bytes\n\tUnitOffset uint16       // 2 bytes\n\tKind       T            // 1 byte\n\tFlags      TokenFlags   // 1 byte\n}\n\nfunc (token Token) DecodedText(contents string) string {\n\traw := contents[token.Range.Loc.Start:token.Range.End()]\n\n\tswitch token.Kind {\n\tcase TIdent, TDimension:\n\t\treturn decodeEscapesInToken(raw)\n\n\tcase TAtKeyword, THash:\n\t\treturn decodeEscapesInToken(raw[1:])\n\n\tcase TFunction:\n\t\treturn decodeEscapesInToken(raw[:len(raw)-1])\n\n\tcase TString:\n\t\treturn decodeEscapesInToken(raw[1 : len(raw)-1])\n\n\tcase TURL:\n\t\tstart := 4\n\t\tend := len(raw) - 1\n\n\t\t// Trim leading and trailing whitespace\n\t\tfor start < end && isWhitespace(rune(raw[start])) {\n\t\t\tstart++\n\t\t}\n\t\tfor start < end && isWhitespace(rune(raw[end-1])) {\n\t\t\tend--\n\t\t}\n\n\t\treturn decodeEscapesInToken(raw[start:end])\n\t}\n\n\treturn raw\n}\n\ntype lexer struct {\n\tlog                     logger.Log\n\tsource                  logger.Source\n\tlegalCommentsBefore     []Comment\n\tsourceMappingURL        logger.Span\n\ttracker                 logger.LineColumnTracker\n\tapproximateNewlineCount int\n\tcurrent                 int\n\toldSingleLineCommentEnd logger.Loc\n\tcodePoint               rune\n\tToken                   Token\n}\n\ntype Comment struct {\n\tText            string\n\tLoc             logger.Loc\n\tTokenIndexAfter uint32\n}\n\ntype TokenizeResult struct {\n\tTokens               []Token\n\tLegalComments        []Comment\n\tSourceMapComment     logger.Span\n\tApproximateLineCount int32\n}\n\nfunc Tokenize(log logger.Log, source logger.Source) TokenizeResult {\n\tlexer := lexer{\n\t\tlog:     log,\n\t\tsource:  source,\n\t\ttracker: logger.MakeLineColumnTracker(&source),\n\t}\n\tlexer.step()\n\n\t// The U+FEFF character is usually a zero-width non-breaking space. However,\n\t// when it's used at the start of a text stream it is called a BOM (byte order\n\t// mark) instead and indicates that the text stream is UTF-8 encoded. This is\n\t// problematic for us because CSS does not treat U+FEFF as whitespace. Only\n\t// \" \\t\\r\\n\\f\" characters are treated as whitespace. Skip over the BOM if it\n\t// is present so it doesn't cause us trouble when we try to parse it.\n\tif lexer.codePoint == '\\uFEFF' {\n\t\tlexer.step()\n\t}\n\n\tlexer.next()\n\tvar tokens []Token\n\tvar comments []Comment\n\tfor lexer.Token.Kind != TEndOfFile {\n\t\tif lexer.legalCommentsBefore != nil {\n\t\t\tfor _, comment := range lexer.legalCommentsBefore {\n\t\t\t\tcomment.TokenIndexAfter = uint32(len(tokens))\n\t\t\t\tcomments = append(comments, comment)\n\t\t\t}\n\t\t\tlexer.legalCommentsBefore = nil\n\t\t}\n\t\ttokens = append(tokens, lexer.Token)\n\t\tlexer.next()\n\t}\n\tif lexer.legalCommentsBefore != nil {\n\t\tfor _, comment := range lexer.legalCommentsBefore {\n\t\t\tcomment.TokenIndexAfter = uint32(len(tokens))\n\t\t\tcomments = append(comments, comment)\n\t\t}\n\t\tlexer.legalCommentsBefore = nil\n\t}\n\treturn TokenizeResult{\n\t\tTokens:               tokens,\n\t\tLegalComments:        comments,\n\t\tApproximateLineCount: int32(lexer.approximateNewlineCount) + 1,\n\t\tSourceMapComment:     lexer.sourceMappingURL,\n\t}\n}\n\nfunc (lexer *lexer) step() {\n\tcodePoint, width := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current:])\n\n\t// Use -1 to indicate the end of the file\n\tif width == 0 {\n\t\tcodePoint = eof\n\t}\n\n\t// Track the approximate number of newlines in the file so we can preallocate\n\t// the line offset table in the printer for source maps. The line offset table\n\t// is the #1 highest allocation in the heap profile, so this is worth doing.\n\t// This count is approximate because it handles \"\\n\" and \"\\r\\n\" (the common\n\t// cases) but not \"\\r\" or \"\\u2028\" or \"\\u2029\". Getting this wrong is harmless\n\t// because it's only a preallocation. The array will just grow if it's too small.\n\tif codePoint == '\\n' {\n\t\tlexer.approximateNewlineCount++\n\t}\n\n\tlexer.codePoint = codePoint\n\tlexer.Token.Range.Len = int32(lexer.current) - lexer.Token.Range.Loc.Start\n\tlexer.current += width\n}\n\nfunc (lexer *lexer) next() {\n\t// Reference: https://www.w3.org/TR/css-syntax-3/\n\n\tfor {\n\t\tlexer.Token = Token{Range: logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}}}\n\n\t\tswitch lexer.codePoint {\n\t\tcase eof:\n\t\t\tlexer.Token.Kind = TEndOfFile\n\n\t\tcase '/':\n\t\t\tlexer.step()\n\t\t\tswitch lexer.codePoint {\n\t\t\tcase '*':\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.consumeToEndOfMultiLineComment(lexer.Token.Range)\n\t\t\t\tcontinue\n\t\t\tcase '/':\n\t\t\t\t// Warn when people use \"//\" comments, which are invalid in CSS\n\t\t\t\tloc := lexer.Token.Range.Loc\n\t\t\t\tif loc.Start >= lexer.oldSingleLineCommentEnd.Start {\n\t\t\t\t\tcontents := lexer.source.Contents\n\t\t\t\t\tend := lexer.current\n\t\t\t\t\tfor end < len(contents) && !isNewline(rune(contents[end])) {\n\t\t\t\t\t\tend++\n\t\t\t\t\t}\n\t\t\t\t\tlexer.log.Add(logger.Warning, &lexer.tracker, logger.Range{Loc: loc, Len: 2},\n\t\t\t\t\t\t\"Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\")\n\t\t\t\t\tlexer.oldSingleLineCommentEnd.Start = int32(end)\n\t\t\t\t\tlexer.Token.Flags |= DidWarnAboutSingleLineComment\n\t\t\t\t}\n\t\t\t}\n\t\t\tlexer.Token.Kind = TDelimSlash\n\n\t\tcase ' ', '\\t', '\\n', '\\r', '\\f':\n\t\t\tlexer.step()\n\t\t\tfor {\n\t\t\t\tif isWhitespace(lexer.codePoint) {\n\t\t\t\t\tlexer.step()\n\t\t\t\t} else if lexer.codePoint == '/' && lexer.current < len(lexer.source.Contents) && lexer.source.Contents[lexer.current] == '*' {\n\t\t\t\t\tstartRange := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 2}\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.step()\n\t\t\t\t\tlexer.consumeToEndOfMultiLineComment(startRange)\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tlexer.Token.Kind = TWhitespace\n\n\t\tcase '\"', '\\'':\n\t\t\tlexer.Token.Kind = lexer.consumeString()\n\n\t\tcase '#':\n\t\t\tlexer.step()\n\t\t\tif IsNameContinue(lexer.codePoint) || lexer.isValidEscape() {\n\t\t\t\tlexer.Token.Kind = THash\n\t\t\t\tif lexer.wouldStartIdentifier() {\n\t\t\t\t\tlexer.Token.Flags |= IsID\n\t\t\t\t}\n\t\t\t\tlexer.consumeName()\n\t\t\t} else {\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\n\t\tcase '(':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TOpenParen\n\n\t\tcase ')':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TCloseParen\n\n\t\tcase '[':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TOpenBracket\n\n\t\tcase ']':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TCloseBracket\n\n\t\tcase '{':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TOpenBrace\n\n\t\tcase '}':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TCloseBrace\n\n\t\tcase ',':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TComma\n\n\t\tcase ':':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TColon\n\n\t\tcase ';':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TSemicolon\n\n\t\tcase '+':\n\t\t\tif lexer.wouldStartNumber() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelimPlus\n\t\t\t}\n\n\t\tcase '.':\n\t\t\tif lexer.wouldStartNumber() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelimDot\n\t\t\t}\n\n\t\tcase '-':\n\t\t\tif lexer.wouldStartNumber() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\t\t\t} else if lexer.current+2 <= len(lexer.source.Contents) && lexer.source.Contents[lexer.current:lexer.current+2] == \"->\" {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TCDC\n\t\t\t} else if lexer.wouldStartIdentifier() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeIdentLike()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelimMinus\n\t\t\t}\n\n\t\tcase '<':\n\t\t\tif lexer.current+3 <= len(lexer.source.Contents) && lexer.source.Contents[lexer.current:lexer.current+3] == \"!--\" {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TCDO\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\n\t\tcase '@':\n\t\t\tlexer.step()\n\t\t\tif lexer.wouldStartIdentifier() {\n\t\t\t\tlexer.consumeName()\n\t\t\t\tlexer.Token.Kind = TAtKeyword\n\t\t\t} else {\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\n\t\tcase '\\\\':\n\t\t\tif lexer.isValidEscape() {\n\t\t\t\tlexer.Token.Kind = lexer.consumeIdentLike()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.log.Add(logger.Error, &lexer.tracker, lexer.Token.Range, \"Invalid escape\")\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\n\t\tcase '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':\n\t\t\tlexer.Token.Kind = lexer.consumeNumeric()\n\n\t\tcase '>':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimGreaterThan\n\n\t\tcase '~':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimTilde\n\n\t\tcase '&':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimAmpersand\n\n\t\tcase '*':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimAsterisk\n\n\t\tcase '|':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimBar\n\n\t\tcase '!':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimExclamation\n\n\t\tcase '=':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimEquals\n\n\t\tcase '^':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimCaret\n\n\t\tcase '$':\n\t\t\tlexer.step()\n\t\t\tlexer.Token.Kind = TDelimDollar\n\n\t\tdefault:\n\t\t\tif IsNameStart(lexer.codePoint) {\n\t\t\t\tlexer.Token.Kind = lexer.consumeIdentLike()\n\t\t\t} else {\n\t\t\t\tlexer.step()\n\t\t\t\tlexer.Token.Kind = TDelim\n\t\t\t}\n\t\t}\n\n\t\treturn\n\t}\n}\n\nfunc (lexer *lexer) consumeToEndOfMultiLineComment(startRange logger.Range) {\n\tstartOfSourceMappingURL := 0\n\tisLegalComment := false\n\n\tswitch lexer.codePoint {\n\tcase '#', '@':\n\t\t// Keep track of the contents of the \"sourceMappingURL=\" comment\n\t\tif strings.HasPrefix(lexer.source.Contents[lexer.current:], \" sourceMappingURL=\") {\n\t\t\tstartOfSourceMappingURL = lexer.current + len(\" sourceMappingURL=\")\n\t\t}\n\n\tcase '!':\n\t\t// Remember if this is a legal comment\n\t\tisLegalComment = true\n\t}\n\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase '*':\n\t\t\tendOfSourceMappingURL := lexer.current - 1\n\t\t\tlexer.step()\n\t\t\tif lexer.codePoint == '/' {\n\t\t\t\tcommentEnd := lexer.current\n\t\t\t\tlexer.step()\n\n\t\t\t\t// Record the source mapping URL\n\t\t\t\tif startOfSourceMappingURL != 0 {\n\t\t\t\t\tr := logger.Range{Loc: logger.Loc{Start: int32(startOfSourceMappingURL)}}\n\t\t\t\t\ttext := lexer.source.Contents[startOfSourceMappingURL:endOfSourceMappingURL]\n\t\t\t\t\tfor int(r.Len) < len(text) && !isWhitespace(rune(text[r.Len])) {\n\t\t\t\t\t\tr.Len++\n\t\t\t\t\t}\n\t\t\t\t\tlexer.sourceMappingURL = logger.Span{Text: text[:r.Len], Range: r}\n\t\t\t\t}\n\n\t\t\t\t// Record legal comments\n\t\t\t\tif text := lexer.source.Contents[startRange.Loc.Start:commentEnd]; isLegalComment || containsAtPreserveOrAtLicense(text) {\n\t\t\t\t\ttext = helpers.RemoveMultiLineCommentIndent(lexer.source.Contents[:startRange.Loc.Start], text)\n\t\t\t\t\tlexer.legalCommentsBefore = append(lexer.legalCommentsBefore, Comment{Loc: startRange.Loc, Text: text})\n\t\t\t\t}\n\t\t\t\treturn\n\t\t\t}\n\n\t\tcase eof: // This indicates the end of the file\n\t\t\tlexer.log.AddWithNotes(logger.Error, &lexer.tracker, logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}},\n\t\t\t\t\"Expected \\\"*/\\\" to terminate multi-line comment\",\n\t\t\t\t[]logger.MsgData{lexer.tracker.MsgData(startRange, \"The multi-line comment starts here:\")})\n\t\t\treturn\n\n\t\tdefault:\n\t\t\tlexer.step()\n\t\t}\n\t}\n}\n\nfunc containsAtPreserveOrAtLicense(text string) bool {\n\tfor i, c := range text {\n\t\tif c == '@' && (strings.HasPrefix(text[i+1:], \"preserve\") || strings.HasPrefix(text[i+1:], \"license\")) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (lexer *lexer) isValidEscape() bool {\n\tif lexer.codePoint != '\\\\' {\n\t\treturn false\n\t}\n\tc, _ := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current:])\n\treturn !isNewline(c)\n}\n\nfunc (lexer *lexer) wouldStartIdentifier() bool {\n\tif IsNameStart(lexer.codePoint) {\n\t\treturn true\n\t}\n\n\tif lexer.codePoint == '-' {\n\t\tc, width := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current:])\n\t\tif c == utf8.RuneError && width <= 1 {\n\t\t\treturn false // Decoding error\n\t\t}\n\t\tif IsNameStart(c) || c == '-' {\n\t\t\treturn true\n\t\t}\n\t\tif c == '\\\\' {\n\t\t\tc2, _ := utf8.DecodeRuneInString(lexer.source.Contents[lexer.current+width:])\n\t\t\treturn !isNewline(c2)\n\t\t}\n\t\treturn false\n\t}\n\n\treturn lexer.isValidEscape()\n}\n\nfunc WouldStartIdentifierWithoutEscapes(text string) bool {\n\tc, width := utf8.DecodeRuneInString(text)\n\tif c == utf8.RuneError && width <= 1 {\n\t\treturn false // Decoding error\n\t}\n\tif IsNameStart(c) {\n\t\treturn true\n\t}\n\n\tif c == '-' {\n\t\tc2, width2 := utf8.DecodeRuneInString(text[width:])\n\t\tif c2 == utf8.RuneError && width2 <= 1 {\n\t\t\treturn false // Decoding error\n\t\t}\n\t\tif IsNameStart(c2) || c2 == '-' {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (lexer *lexer) wouldStartNumber() bool {\n\tif lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\treturn true\n\t} else if lexer.codePoint == '.' {\n\t\tcontents := lexer.source.Contents\n\t\tif lexer.current < len(contents) {\n\t\t\tc := contents[lexer.current]\n\t\t\treturn c >= '0' && c <= '9'\n\t\t}\n\t} else if lexer.codePoint == '+' || lexer.codePoint == '-' {\n\t\tcontents := lexer.source.Contents\n\t\tn := len(contents)\n\t\tif lexer.current < n {\n\t\t\tc := contents[lexer.current]\n\t\t\tif c >= '0' && c <= '9' {\n\t\t\t\treturn true\n\t\t\t}\n\t\t\tif c == '.' && lexer.current+1 < n {\n\t\t\t\tc = contents[lexer.current+1]\n\t\t\t\treturn c >= '0' && c <= '9'\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc (lexer *lexer) consumeName() string {\n\t// Common case: no escapes, identifier is a substring of the input\n\tfor IsNameContinue(lexer.codePoint) {\n\t\tlexer.step()\n\t}\n\traw := lexer.source.Contents[lexer.Token.Range.Loc.Start:lexer.Token.Range.End()]\n\tif !lexer.isValidEscape() {\n\t\treturn raw\n\t}\n\n\t// Uncommon case: escapes, identifier is allocated\n\tsb := strings.Builder{}\n\tsb.WriteString(raw)\n\tsb.WriteRune(lexer.consumeEscape())\n\tfor {\n\t\tif IsNameContinue(lexer.codePoint) {\n\t\t\tsb.WriteRune(lexer.codePoint)\n\t\t\tlexer.step()\n\t\t} else if lexer.isValidEscape() {\n\t\t\tsb.WriteRune(lexer.consumeEscape())\n\t\t} else {\n\t\t\tbreak\n\t\t}\n\t}\n\treturn sb.String()\n}\n\nfunc (lexer *lexer) consumeEscape() rune {\n\tlexer.step() // Skip the backslash\n\tc := lexer.codePoint\n\n\tif hex, ok := isHex(c); ok {\n\t\tlexer.step()\n\t\tfor i := 0; i < 5; i++ {\n\t\t\tif next, ok := isHex(lexer.codePoint); ok {\n\t\t\t\tlexer.step()\n\t\t\t\thex = hex*16 + next\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif isWhitespace(lexer.codePoint) {\n\t\t\tlexer.step()\n\t\t}\n\t\tif hex == 0 || (hex >= 0xD800 && hex <= 0xDFFF) || hex > 0x10FFFF {\n\t\t\treturn utf8.RuneError\n\t\t}\n\t\treturn rune(hex)\n\t}\n\n\tif c == eof {\n\t\treturn utf8.RuneError\n\t}\n\n\tlexer.step()\n\treturn c\n}\n\nfunc (lexer *lexer) consumeIdentLike() T {\n\tname := lexer.consumeName()\n\n\tif lexer.codePoint == '(' {\n\t\tlexer.step()\n\t\tif len(name) == 3 {\n\t\t\tu, r, l := name[0], name[1], name[2]\n\t\t\tif (u == 'u' || u == 'U') && (r == 'r' || r == 'R') && (l == 'l' || l == 'L') {\n\t\t\t\tfor isWhitespace(lexer.codePoint) {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tif lexer.codePoint != '\"' && lexer.codePoint != '\\'' {\n\t\t\t\t\treturn lexer.consumeURL()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn TFunction\n\t}\n\n\treturn TIdent\n}\n\nfunc (lexer *lexer) consumeURL() T {\nvalidURL:\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase ')':\n\t\t\tlexer.step()\n\t\t\treturn TURL\n\n\t\tcase eof:\n\t\t\tloc := logger.Loc{Start: lexer.Token.Range.End()}\n\t\t\tlexer.log.Add(logger.Error, &lexer.tracker, logger.Range{Loc: loc}, \"Expected \\\")\\\" to end URL token\")\n\t\t\treturn TBadURL\n\n\t\tcase ' ', '\\t', '\\n', '\\r', '\\f':\n\t\t\tlexer.step()\n\t\t\tfor isWhitespace(lexer.codePoint) {\n\t\t\t\tlexer.step()\n\t\t\t}\n\t\t\tif lexer.codePoint != ')' {\n\t\t\t\tloc := logger.Loc{Start: lexer.Token.Range.End()}\n\t\t\t\tlexer.log.Add(logger.Error, &lexer.tracker, logger.Range{Loc: loc}, \"Expected \\\")\\\" to end URL token\")\n\t\t\t\tbreak validURL\n\t\t\t}\n\t\t\tlexer.step()\n\t\t\treturn TURL\n\n\t\tcase '\"', '\\'', '(':\n\t\t\tr := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 1}\n\t\t\tlexer.log.Add(logger.Error, &lexer.tracker, r, \"Expected \\\")\\\" to end URL token\")\n\t\t\tbreak validURL\n\n\t\tcase '\\\\':\n\t\t\tif !lexer.isValidEscape() {\n\t\t\t\tr := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 1}\n\t\t\t\tlexer.log.Add(logger.Error, &lexer.tracker, r, \"Invalid escape\")\n\t\t\t\tbreak validURL\n\t\t\t}\n\t\t\tlexer.consumeEscape()\n\n\t\tdefault:\n\t\t\tif isNonPrintable(lexer.codePoint) {\n\t\t\t\tr := logger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}, Len: 1}\n\t\t\t\tlexer.log.Add(logger.Error, &lexer.tracker, r, \"Unexpected non-printable character in URL token\")\n\t\t\t}\n\t\t\tlexer.step()\n\t\t}\n\t}\n\n\t// Consume the remnants of a bad url\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase ')', eof:\n\t\t\tlexer.step()\n\t\t\treturn TBadURL\n\n\t\tcase '\\\\':\n\t\t\tif lexer.isValidEscape() {\n\t\t\t\tlexer.consumeEscape()\n\t\t\t}\n\t\t}\n\t\tlexer.step()\n\t}\n}\n\nfunc (lexer *lexer) consumeString() T {\n\tquote := lexer.codePoint\n\tlexer.step()\n\n\tfor {\n\t\tswitch lexer.codePoint {\n\t\tcase '\\\\':\n\t\t\tlexer.step()\n\n\t\t\t// Handle Windows CRLF\n\t\t\tif lexer.codePoint == '\\r' {\n\t\t\t\tlexer.step()\n\t\t\t\tif lexer.codePoint == '\\n' {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, fall through to ignore the character after the backslash\n\n\t\tcase eof:\n\t\t\tlexer.log.Add(logger.Error, &lexer.tracker,\n\t\t\t\tlogger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}},\n\t\t\t\t\"Unterminated string token\")\n\t\t\treturn TBadString\n\n\t\tcase '\\n', '\\r', '\\f':\n\t\t\tlexer.log.Add(logger.Error, &lexer.tracker,\n\t\t\t\tlogger.Range{Loc: logger.Loc{Start: lexer.Token.Range.End()}},\n\t\t\t\t\"Unterminated string token\")\n\t\t\treturn TBadString\n\n\t\tcase quote:\n\t\t\tlexer.step()\n\t\t\treturn TString\n\t\t}\n\t\tlexer.step()\n\t}\n}\n\nfunc (lexer *lexer) consumeNumeric() T {\n\t// Skip over leading sign\n\tif lexer.codePoint == '+' || lexer.codePoint == '-' {\n\t\tlexer.step()\n\t}\n\n\t// Skip over leading digits\n\tfor lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\tlexer.step()\n\t}\n\n\t// Skip over digits after dot\n\tif lexer.codePoint == '.' {\n\t\tlexer.step()\n\t\tfor lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\t\tlexer.step()\n\t\t}\n\t}\n\n\t// Skip over exponent\n\tif lexer.codePoint == 'e' || lexer.codePoint == 'E' {\n\t\tcontents := lexer.source.Contents\n\n\t\t// Look ahead before advancing to make sure this is an exponent, not a unit\n\t\tif lexer.current < len(contents) {\n\t\t\tc := contents[lexer.current]\n\t\t\tif (c == '+' || c == '-') && lexer.current+1 < len(contents) {\n\t\t\t\tc = contents[lexer.current+1]\n\t\t\t}\n\n\t\t\t// Only consume this if it's an exponent\n\t\t\tif c >= '0' && c <= '9' {\n\t\t\t\tlexer.step()\n\t\t\t\tif lexer.codePoint == '+' || lexer.codePoint == '-' {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t\tfor lexer.codePoint >= '0' && lexer.codePoint <= '9' {\n\t\t\t\t\tlexer.step()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Determine the numeric type\n\tif lexer.wouldStartIdentifier() {\n\t\tlexer.Token.UnitOffset = uint16(lexer.Token.Range.Len)\n\t\tlexer.consumeName()\n\t\treturn TDimension\n\t}\n\tif lexer.codePoint == '%' {\n\t\tlexer.step()\n\t\treturn TPercentage\n\t}\n\treturn TNumber\n}\n\nfunc IsNameStart(c rune) bool {\n\treturn (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c >= 0x80 || c == '\\x00'\n}\n\nfunc IsNameContinue(c rune) bool {\n\treturn IsNameStart(c) || (c >= '0' && c <= '9') || c == '-'\n}\n\nfunc isNewline(c rune) bool {\n\tswitch c {\n\tcase '\\n', '\\r', '\\f':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isWhitespace(c rune) bool {\n\tswitch c {\n\tcase ' ', '\\t', '\\n', '\\r', '\\f':\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc isHex(c rune) (int, bool) {\n\tif c >= '0' && c <= '9' {\n\t\treturn int(c - '0'), true\n\t}\n\tif c >= 'a' && c <= 'f' {\n\t\treturn int(c + (10 - 'a')), true\n\t}\n\tif c >= 'A' && c <= 'F' {\n\t\treturn int(c + (10 - 'A')), true\n\t}\n\treturn 0, false\n}\n\nfunc isNonPrintable(c rune) bool {\n\treturn c <= 0x08 || c == 0x0B || (c >= 0x0E && c <= 0x1F) || c == 0x7F\n}\n\nfunc decodeEscapesInToken(inner string) string {\n\ti := 0\n\n\tfor i < len(inner) {\n\t\tif c := inner[i]; c == '\\\\' || c == '\\x00' {\n\t\t\tbreak\n\t\t}\n\t\ti++\n\t}\n\n\tif i == len(inner) {\n\t\treturn inner\n\t}\n\n\tsb := strings.Builder{}\n\tsb.WriteString(inner[:i])\n\tinner = inner[i:]\n\n\tfor len(inner) > 0 {\n\t\tc, width := utf8.DecodeRuneInString(inner)\n\t\tinner = inner[width:]\n\n\t\tif c != '\\\\' {\n\t\t\tif c == '\\x00' {\n\t\t\t\tc = utf8.RuneError\n\t\t\t}\n\t\t\tsb.WriteRune(c)\n\t\t\tcontinue\n\t\t}\n\n\t\tif len(inner) == 0 {\n\t\t\tsb.WriteRune(utf8.RuneError)\n\t\t\tcontinue\n\t\t}\n\n\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\tinner = inner[width:]\n\t\thex, ok := isHex(c)\n\n\t\tif !ok {\n\t\t\tif c == '\\n' || c == '\\f' {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Handle Windows CRLF\n\t\t\tif c == '\\r' {\n\t\t\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\t\t\tif c == '\\n' {\n\t\t\t\t\tinner = inner[width:]\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// If we get here, this is not a valid escape. However, this is still\n\t\t\t// allowed. In this case the backslash is just ignored.\n\t\t\tsb.WriteRune(c)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Parse up to five additional hex characters (so six in total)\n\t\tfor i := 0; i < 5 && len(inner) > 0; i++ {\n\t\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\t\tif next, ok := isHex(c); ok {\n\t\t\t\tinner = inner[width:]\n\t\t\t\thex = hex*16 + next\n\t\t\t} else {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\n\t\tif len(inner) > 0 {\n\t\t\tc, width = utf8.DecodeRuneInString(inner)\n\t\t\tif isWhitespace(c) {\n\t\t\t\tinner = inner[width:]\n\t\t\t}\n\t\t}\n\n\t\tif hex == 0 || (hex >= 0xD800 && hex <= 0xDFFF) || hex > 0x10FFFF {\n\t\t\tsb.WriteRune(utf8.RuneError)\n\t\t\tcontinue\n\t\t}\n\n\t\tsb.WriteRune(rune(hex))\n\t}\n\n\treturn sb.String()\n}\n"
  },
  {
    "path": "lib/esbuild/css_lexer/css_lexer_test.go",
    "content": "package css_lexer\n\nimport (\n\t\"testing\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n\t\"github.com/withastro/compiler/lib/esbuild/test\"\n)\n\nfunc lexToken(contents string) (T, string) {\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug)\n\tresult := Tokenize(log, test.SourceForTest(contents))\n\tif len(result.Tokens) > 0 {\n\t\tt := result.Tokens[0]\n\t\treturn t.Kind, t.DecodedText(contents)\n\t}\n\treturn TEndOfFile, \"\"\n}\n\nfunc lexerError(contents string) string {\n\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug)\n\tTokenize(log, test.SourceForTest(contents))\n\ttext := \"\"\n\tfor _, msg := range log.Done() {\n\t\ttext += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})\n\t}\n\treturn text\n}\n\nfunc TestTokens(t *testing.T) {\n\texpected := []struct {\n\t\tcontents string\n\t\ttext     string\n\t\ttoken    T\n\t}{\n\t\t{\"\", \"end of file\", TEndOfFile},\n\t\t{\"@media\", \"@-keyword\", TAtKeyword},\n\t\t{\"url(x y\", \"bad URL token\", TBadURL},\n\t\t{\"-->\", \"\\\"-->\\\"\", TCDC},\n\t\t{\"<!--\", \"\\\"<!--\\\"\", TCDO},\n\t\t{\"}\", \"\\\"}\\\"\", TCloseBrace},\n\t\t{\"]\", \"\\\"]\\\"\", TCloseBracket},\n\t\t{\")\", \"\\\")\\\"\", TCloseParen},\n\t\t{\":\", \"\\\":\\\"\", TColon},\n\t\t{\",\", \"\\\",\\\"\", TComma},\n\t\t{\"?\", \"delimiter\", TDelim},\n\t\t{\"&\", \"\\\"&\\\"\", TDelimAmpersand},\n\t\t{\"*\", \"\\\"*\\\"\", TDelimAsterisk},\n\t\t{\"|\", \"\\\"|\\\"\", TDelimBar},\n\t\t{\"^\", \"\\\"^\\\"\", TDelimCaret},\n\t\t{\"$\", \"\\\"$\\\"\", TDelimDollar},\n\t\t{\".\", \"\\\".\\\"\", TDelimDot},\n\t\t{\"=\", \"\\\"=\\\"\", TDelimEquals},\n\t\t{\"!\", \"\\\"!\\\"\", TDelimExclamation},\n\t\t{\">\", \"\\\">\\\"\", TDelimGreaterThan},\n\t\t{\"+\", \"\\\"+\\\"\", TDelimPlus},\n\t\t{\"/\", \"\\\"/\\\"\", TDelimSlash},\n\t\t{\"~\", \"\\\"~\\\"\", TDelimTilde},\n\t\t{\"1px\", \"dimension\", TDimension},\n\t\t{\"max(\", \"function token\", TFunction},\n\t\t{\"#name\", \"hash token\", THash},\n\t\t{\"name\", \"identifier\", TIdent},\n\t\t{\"123\", \"number\", TNumber},\n\t\t{\"{\", \"\\\"{\\\"\", TOpenBrace},\n\t\t{\"[\", \"\\\"[\\\"\", TOpenBracket},\n\t\t{\"(\", \"\\\"(\\\"\", TOpenParen},\n\t\t{\"50%\", \"percentage\", TPercentage},\n\t\t{\";\", \"\\\";\\\"\", TSemicolon},\n\t\t{\"'abc'\", \"string token\", TString},\n\t\t{\"url(test)\", \"URL token\", TURL},\n\t\t{\" \", \"whitespace\", TWhitespace},\n\t}\n\n\tfor _, it := range expected {\n\t\tcontents := it.contents\n\t\ttoken := it.token\n\t\tt.Run(contents, func(t *testing.T) {\n\t\t\tkind, _ := lexToken(contents)\n\t\t\ttest.AssertEqual(t, kind, token)\n\t\t})\n\t}\n}\n\nfunc TestStringParsing(t *testing.T) {\n\tcontentsOfStringToken := func(contents string) string {\n\t\tt.Helper()\n\t\tkind, text := lexToken(contents)\n\t\ttest.AssertEqual(t, kind, TString)\n\t\treturn text\n\t}\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"foo\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\oo\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\\"o\\\"\"), \"f\\\"o\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\\\o\\\"\"), \"f\\\\o\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\no\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\ro\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\r\\no\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\\\fo\\\"\"), \"fo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\6fo\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\6f o\\\"\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\6f  o\\\"\"), \"fo o\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\fffffffo\\\"\"), \"f\\uFFFDfo\")\n\ttest.AssertEqual(t, contentsOfStringToken(\"\\\"f\\\\10abcdeo\\\"\"), \"f\\U0010ABCDeo\")\n}\n\nfunc TestURLParsing(t *testing.T) {\n\tcontentsOfURLToken := func(expected T, contents string) string {\n\t\tt.Helper()\n\t\tkind, text := lexToken(contents)\n\t\ttest.AssertEqual(t, kind, expected)\n\t\treturn text\n\t}\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(foo)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(  foo\\t\\t)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\oo)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\\\\"o)\"), \"f\\\"o\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\'o)\"), \"f'o\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\)o)\"), \"f)o\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\6fo)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TURL, \"url(f\\\\6f o)\"), \"foo\")\n\ttest.AssertEqual(t, contentsOfURLToken(TBadURL, \"url(f\\\\6f  o)\"), \"url(f\\\\6f  o)\")\n}\n\nfunc TestComment(t *testing.T) {\n\ttest.AssertEqualWithDiff(t, lexerError(\"/*\"), \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"/*/\"), \"<stdin>: ERROR: Expected \\\"*/\\\" to terminate multi-line comment\\n<stdin>: NOTE: The multi-line comment starts here:\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"/**/\"), \"\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"//\"), \"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\")\n}\n\nfunc TestString(t *testing.T) {\n\ttest.AssertEqualWithDiff(t, lexerError(\"'\"), \"<stdin>: ERROR: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"\\\"\"), \"<stdin>: ERROR: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"'\\\\'\"), \"<stdin>: ERROR: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"\\\"\\\\\\\"\"), \"<stdin>: ERROR: Unterminated string token\\n\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"''\"), \"\")\n\ttest.AssertEqualWithDiff(t, lexerError(\"\\\"\\\"\"), \"\")\n}\n\nfunc TestBOM(t *testing.T) {\n\t// A byte order mark should not be parsed as an identifier\n\tkind, _ := lexToken(\"\\uFEFF.\")\n\ttest.AssertEqual(t, kind, TDelimDot)\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls.go",
    "content": "package css_parser\n\nimport (\n\t\"github.com/withastro/compiler/lib/esbuild/compat\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\nfunc (p *parser) commaToken() css_ast.Token {\n\tt := css_ast.Token{\n\t\tKind: css_lexer.TComma,\n\t\tText: \",\",\n\t}\n\tif !p.options.MinifyWhitespace {\n\t\tt.Whitespace = css_ast.WhitespaceAfter\n\t}\n\treturn t\n}\n\nfunc expandTokenQuad(tokens []css_ast.Token, allowedIdent string) (result [4]css_ast.Token, ok bool) {\n\tn := len(tokens)\n\tif n < 1 || n > 4 {\n\t\treturn\n\t}\n\n\t// Don't do this if we encounter any unexpected tokens such as \"var()\"\n\tfor i := 0; i < n; i++ {\n\t\tif t := tokens[i]; !t.Kind.IsNumeric() && (t.Kind != css_lexer.TIdent || allowedIdent == \"\" || t.Text != allowedIdent) {\n\t\t\treturn\n\t\t}\n\t}\n\n\tresult[0] = tokens[0]\n\tif n > 1 {\n\t\tresult[1] = tokens[1]\n\t} else {\n\t\tresult[1] = result[0]\n\t}\n\tif n > 2 {\n\t\tresult[2] = tokens[2]\n\t} else {\n\t\tresult[2] = result[0]\n\t}\n\tif n > 3 {\n\t\tresult[3] = tokens[3]\n\t} else {\n\t\tresult[3] = result[1]\n\t}\n\n\tok = true\n\treturn\n}\n\nfunc compactTokenQuad(a css_ast.Token, b css_ast.Token, c css_ast.Token, d css_ast.Token, minifyWhitespace bool) []css_ast.Token {\n\ttokens := []css_ast.Token{a, b, c, d}\n\tif tokens[3].EqualIgnoringWhitespace(tokens[1]) {\n\t\tif tokens[2].EqualIgnoringWhitespace(tokens[0]) {\n\t\t\tif tokens[1].EqualIgnoringWhitespace(tokens[0]) {\n\t\t\t\ttokens = tokens[:1]\n\t\t\t} else {\n\t\t\t\ttokens = tokens[:2]\n\t\t\t}\n\t\t} else {\n\t\t\ttokens = tokens[:3]\n\t\t}\n\t}\n\tfor i := range tokens {\n\t\tvar whitespace css_ast.WhitespaceFlags\n\t\tif !minifyWhitespace || i > 0 {\n\t\t\twhitespace |= css_ast.WhitespaceBefore\n\t\t}\n\t\tif i+1 < len(tokens) {\n\t\t\twhitespace |= css_ast.WhitespaceAfter\n\t\t}\n\t\ttokens[i].Whitespace = whitespace\n\t}\n\treturn tokens\n}\n\nfunc (p *parser) processDeclarations(rules []css_ast.Rule) []css_ast.Rule {\n\tmargin := boxTracker{key: css_ast.DMargin, keyText: \"margin\", allowAuto: true}\n\tpadding := boxTracker{key: css_ast.DPadding, keyText: \"padding\", allowAuto: false}\n\tinset := boxTracker{key: css_ast.DInset, keyText: \"inset\", allowAuto: true}\n\tborderRadius := borderRadiusTracker{}\n\n\tfor i, rule := range rules {\n\t\tdecl, ok := rule.Data.(*css_ast.RDeclaration)\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch decl.Key {\n\t\tcase css_ast.DBackgroundColor,\n\t\t\tcss_ast.DBorderBlockEndColor,\n\t\t\tcss_ast.DBorderBlockStartColor,\n\t\t\tcss_ast.DBorderBottomColor,\n\t\t\tcss_ast.DBorderColor,\n\t\t\tcss_ast.DBorderInlineEndColor,\n\t\t\tcss_ast.DBorderInlineStartColor,\n\t\t\tcss_ast.DBorderLeftColor,\n\t\t\tcss_ast.DBorderRightColor,\n\t\t\tcss_ast.DBorderTopColor,\n\t\t\tcss_ast.DCaretColor,\n\t\t\tcss_ast.DColor,\n\t\t\tcss_ast.DColumnRuleColor,\n\t\t\tcss_ast.DFill,\n\t\t\tcss_ast.DFloodColor,\n\t\t\tcss_ast.DLightingColor,\n\t\t\tcss_ast.DOutlineColor,\n\t\t\tcss_ast.DStopColor,\n\t\t\tcss_ast.DStroke,\n\t\t\tcss_ast.DTextDecorationColor,\n\t\t\tcss_ast.DTextEmphasisColor:\n\n\t\t\tif len(decl.Value) == 1 {\n\t\t\t\tdecl.Value[0] = p.lowerColor(decl.Value[0])\n\n\t\t\t\tif p.options.MinifySyntax {\n\t\t\t\t\tt := decl.Value[0]\n\t\t\t\t\tif hex, ok := parseColor(t); ok {\n\t\t\t\t\t\tdecl.Value[0] = p.mangleColor(t, hex)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_ast.DFont:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tdecl.Value = p.mangleFont(decl.Value)\n\t\t\t}\n\n\t\tcase css_ast.DFontFamily:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tif value, ok := p.mangleFontFamily(decl.Value); ok {\n\t\t\t\t\tdecl.Value = value\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_ast.DFontWeight:\n\t\t\tif len(decl.Value) == 1 && p.options.MinifySyntax {\n\t\t\t\tdecl.Value[0] = p.mangleFontWeight(decl.Value[0])\n\t\t\t}\n\n\t\tcase css_ast.DTransform:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tdecl.Value = p.mangleTransforms(decl.Value)\n\t\t\t}\n\n\t\tcase css_ast.DBoxShadow:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tdecl.Value = p.mangleBoxShadows(decl.Value)\n\t\t\t}\n\n\t\t// Margin\n\t\tcase css_ast.DMargin:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tmargin.mangleSides(rules, decl, i, p.options.MinifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DMarginTop:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tmargin.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxTop)\n\t\t\t}\n\t\tcase css_ast.DMarginRight:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tmargin.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxRight)\n\t\t\t}\n\t\tcase css_ast.DMarginBottom:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tmargin.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxBottom)\n\t\t\t}\n\t\tcase css_ast.DMarginLeft:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tmargin.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxLeft)\n\t\t\t}\n\n\t\t// Padding\n\t\tcase css_ast.DPadding:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tpadding.mangleSides(rules, decl, i, p.options.MinifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DPaddingTop:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tpadding.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxTop)\n\t\t\t}\n\t\tcase css_ast.DPaddingRight:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tpadding.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxRight)\n\t\t\t}\n\t\tcase css_ast.DPaddingBottom:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tpadding.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxBottom)\n\t\t\t}\n\t\tcase css_ast.DPaddingLeft:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tpadding.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxLeft)\n\t\t\t}\n\n\t\t// Inset\n\t\tcase css_ast.DInset:\n\t\t\tif !p.options.UnsupportedCSSFeatures.Has(compat.InsetProperty) && p.options.MinifySyntax {\n\t\t\t\tinset.mangleSides(rules, decl, i, p.options.MinifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DTop:\n\t\t\tif !p.options.UnsupportedCSSFeatures.Has(compat.InsetProperty) && p.options.MinifySyntax {\n\t\t\t\tinset.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxTop)\n\t\t\t}\n\t\tcase css_ast.DRight:\n\t\t\tif !p.options.UnsupportedCSSFeatures.Has(compat.InsetProperty) && p.options.MinifySyntax {\n\t\t\t\tinset.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxRight)\n\t\t\t}\n\t\tcase css_ast.DBottom:\n\t\t\tif !p.options.UnsupportedCSSFeatures.Has(compat.InsetProperty) && p.options.MinifySyntax {\n\t\t\t\tinset.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxBottom)\n\t\t\t}\n\t\tcase css_ast.DLeft:\n\t\t\tif !p.options.UnsupportedCSSFeatures.Has(compat.InsetProperty) && p.options.MinifySyntax {\n\t\t\t\tinset.mangleSide(rules, decl, i, p.options.MinifyWhitespace, boxLeft)\n\t\t\t}\n\n\t\t// Border radius\n\t\tcase css_ast.DBorderRadius:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tborderRadius.mangleCorners(rules, decl, i, p.options.MinifyWhitespace)\n\t\t\t}\n\t\tcase css_ast.DBorderTopLeftRadius:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rules, decl, i, p.options.MinifyWhitespace, borderRadiusTopLeft)\n\t\t\t}\n\t\tcase css_ast.DBorderTopRightRadius:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rules, decl, i, p.options.MinifyWhitespace, borderRadiusTopRight)\n\t\t\t}\n\t\tcase css_ast.DBorderBottomRightRadius:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rules, decl, i, p.options.MinifyWhitespace, borderRadiusBottomRight)\n\t\t\t}\n\t\tcase css_ast.DBorderBottomLeftRadius:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tborderRadius.mangleCorner(rules, decl, i, p.options.MinifyWhitespace, borderRadiusBottomLeft)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compact removed rules\n\tif p.options.MinifySyntax {\n\t\tend := 0\n\t\tfor _, rule := range rules {\n\t\t\tif rule.Data != nil {\n\t\t\t\trules[end] = rule\n\t\t\t\tend++\n\t\t\t}\n\t\t}\n\t\trules = rules[:end]\n\t}\n\n\treturn rules\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_border_radius.go",
    "content": "package css_parser\n\nimport (\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\nconst (\n\tborderRadiusTopLeft = iota\n\tborderRadiusTopRight\n\tborderRadiusBottomRight\n\tborderRadiusBottomLeft\n)\n\ntype borderRadiusCorner struct {\n\tfirstToken    css_ast.Token\n\tsecondToken   css_ast.Token\n\tunitSafety    unitSafetyTracker\n\truleIndex     uint32 // The index of the originating rule in the rules array\n\twasSingleRule bool   // True if the originating rule was just for this side\n}\n\ntype borderRadiusTracker struct {\n\tcorners   [4]borderRadiusCorner\n\timportant bool // True if all active rules were flagged as \"!important\"\n}\n\nfunc (borderRadius *borderRadiusTracker) updateCorner(rules []css_ast.Rule, corner int, new borderRadiusCorner) {\n\tif old := borderRadius.corners[corner]; old.firstToken.Kind != css_lexer.TEndOfFile &&\n\t\t(!new.wasSingleRule || old.wasSingleRule) &&\n\t\told.unitSafety.status == unitSafe && new.unitSafety.status == unitSafe {\n\t\trules[old.ruleIndex] = css_ast.Rule{}\n\t}\n\tborderRadius.corners[corner] = new\n}\n\nfunc (borderRadius *borderRadiusTracker) mangleCorners(rules []css_ast.Rule, decl *css_ast.RDeclaration, index int, minifyWhitespace bool) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif borderRadius.important != decl.Important {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\tborderRadius.important = decl.Important\n\t}\n\n\ttokens := decl.Value\n\tbeforeSplit := len(tokens)\n\tafterSplit := len(tokens)\n\n\t// Search for the single slash if present\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TDelimSlash {\n\t\t\tif beforeSplit == len(tokens) {\n\t\t\t\tbeforeSplit = i\n\t\t\t\tafterSplit = i + 1\n\t\t\t} else {\n\t\t\t\t// Multiple slashes are an error\n\t\t\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Use a single tracker for the whole rule\n\tunitSafety := unitSafetyTracker{}\n\tfor _, t := range tokens[:beforeSplit] {\n\t\tunitSafety.includeUnitOf(t)\n\t}\n\tfor _, t := range tokens[afterSplit:] {\n\t\tunitSafety.includeUnitOf(t)\n\t}\n\n\tfirstRadii, firstRadiiOk := expandTokenQuad(tokens[:beforeSplit], \"\")\n\tlastRadii, lastRadiiOk := expandTokenQuad(tokens[afterSplit:], \"\")\n\n\t// Stop now if the pattern wasn't matched\n\tif !firstRadiiOk || (beforeSplit < afterSplit && !lastRadiiOk) {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\treturn\n\t}\n\n\t// Handle the first radii\n\tfor corner, t := range firstRadii {\n\t\tif unitSafety.status == unitSafe {\n\t\t\tt.TurnLengthIntoNumberIfZero()\n\t\t}\n\t\tborderRadius.updateCorner(rules, corner, borderRadiusCorner{\n\t\t\tfirstToken:  t,\n\t\t\tsecondToken: t,\n\t\t\tunitSafety:  unitSafety,\n\t\t\truleIndex:   uint32(index),\n\t\t})\n\t}\n\n\t// Handle the last radii\n\tif lastRadiiOk {\n\t\tfor corner, t := range lastRadii {\n\t\t\tif unitSafety.status == unitSafe {\n\t\t\t\tt.TurnLengthIntoNumberIfZero()\n\t\t\t}\n\t\t\tborderRadius.corners[corner].secondToken = t\n\t\t}\n\t}\n\n\t// Success\n\tborderRadius.compactRules(rules, decl.KeyRange, minifyWhitespace)\n}\n\nfunc (borderRadius *borderRadiusTracker) mangleCorner(rules []css_ast.Rule, decl *css_ast.RDeclaration, index int, minifyWhitespace bool, corner int) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif borderRadius.important != decl.Important {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t\tborderRadius.important = decl.Important\n\t}\n\n\tif tokens := decl.Value; (len(tokens) == 1 && tokens[0].Kind.IsNumeric()) ||\n\t\t(len(tokens) == 2 && tokens[0].Kind.IsNumeric() && tokens[1].Kind.IsNumeric()) {\n\t\tfirstToken := tokens[0]\n\t\tsecondToken := firstToken\n\t\tif len(tokens) == 2 {\n\t\t\tsecondToken = tokens[1]\n\t\t}\n\n\t\t// Check to see if these units are safe to use in every browser\n\t\tunitSafety := unitSafetyTracker{}\n\t\tunitSafety.includeUnitOf(firstToken)\n\t\tunitSafety.includeUnitOf(secondToken)\n\n\t\t// Only collapse \"0unit\" into \"0\" if the unit is safe\n\t\tif unitSafety.status == unitSafe && firstToken.TurnLengthIntoNumberIfZero() {\n\t\t\ttokens[0] = firstToken\n\t\t}\n\t\tif len(tokens) == 2 {\n\t\t\tif unitSafety.status == unitSafe && secondToken.TurnLengthIntoNumberIfZero() {\n\t\t\t\ttokens[1] = secondToken\n\t\t\t}\n\n\t\t\t// If both tokens are equal, merge them into one\n\t\t\tif firstToken.EqualIgnoringWhitespace(secondToken) {\n\t\t\t\ttokens[0].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\tdecl.Value = tokens[:1]\n\t\t\t}\n\t\t}\n\n\t\tborderRadius.updateCorner(rules, corner, borderRadiusCorner{\n\t\t\tfirstToken:    firstToken,\n\t\t\tsecondToken:   secondToken,\n\t\t\tunitSafety:    unitSafety,\n\t\t\truleIndex:     uint32(index),\n\t\t\twasSingleRule: true,\n\t\t})\n\t\tborderRadius.compactRules(rules, decl.KeyRange, minifyWhitespace)\n\t} else {\n\t\tborderRadius.corners = [4]borderRadiusCorner{}\n\t}\n}\n\nfunc (borderRadius *borderRadiusTracker) compactRules(rules []css_ast.Rule, keyRange logger.Range, minifyWhitespace bool) {\n\t// All tokens must be present\n\tif eof := css_lexer.TEndOfFile; borderRadius.corners[0].firstToken.Kind == eof || borderRadius.corners[1].firstToken.Kind == eof ||\n\t\tborderRadius.corners[2].firstToken.Kind == eof || borderRadius.corners[3].firstToken.Kind == eof {\n\t\treturn\n\t}\n\n\t// All tokens must have the same unit\n\tfor _, side := range borderRadius.corners[1:] {\n\t\tif !side.unitSafety.isSafeWith(borderRadius.corners[0].unitSafety) {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Generate the most minimal representation\n\ttokens := compactTokenQuad(\n\t\tborderRadius.corners[0].firstToken,\n\t\tborderRadius.corners[1].firstToken,\n\t\tborderRadius.corners[2].firstToken,\n\t\tborderRadius.corners[3].firstToken,\n\t\tminifyWhitespace,\n\t)\n\tsecondTokens := compactTokenQuad(\n\t\tborderRadius.corners[0].secondToken,\n\t\tborderRadius.corners[1].secondToken,\n\t\tborderRadius.corners[2].secondToken,\n\t\tborderRadius.corners[3].secondToken,\n\t\tminifyWhitespace,\n\t)\n\tif !css_ast.TokensEqualIgnoringWhitespace(tokens, secondTokens) {\n\t\tvar whitespace css_ast.WhitespaceFlags\n\t\tif !minifyWhitespace {\n\t\t\twhitespace = css_ast.WhitespaceBefore | css_ast.WhitespaceAfter\n\t\t}\n\t\ttokens = append(tokens, css_ast.Token{\n\t\t\tKind:       css_lexer.TDelimSlash,\n\t\t\tText:       \"/\",\n\t\t\tWhitespace: whitespace,\n\t\t})\n\t\ttokens = append(tokens, secondTokens...)\n\t}\n\n\t// Remove all of the existing declarations\n\trules[borderRadius.corners[0].ruleIndex] = css_ast.Rule{}\n\trules[borderRadius.corners[1].ruleIndex] = css_ast.Rule{}\n\trules[borderRadius.corners[2].ruleIndex] = css_ast.Rule{}\n\trules[borderRadius.corners[3].ruleIndex] = css_ast.Rule{}\n\n\t// Insert the combined declaration where the last rule was\n\trules[borderRadius.corners[3].ruleIndex].Data = &css_ast.RDeclaration{\n\t\tKey:       css_ast.DBorderRadius,\n\t\tKeyText:   \"border-radius\",\n\t\tValue:     tokens,\n\t\tKeyRange:  keyRange,\n\t\tImportant: borderRadius.important,\n\t}\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_box.go",
    "content": "package css_parser\n\nimport (\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\nconst (\n\tboxTop = iota\n\tboxRight\n\tboxBottom\n\tboxLeft\n)\n\ntype boxSide struct {\n\ttoken         css_ast.Token\n\tunitSafety    unitSafetyTracker\n\truleIndex     uint32 // The index of the originating rule in the rules array\n\twasSingleRule bool   // True if the originating rule was just for this side\n}\n\ntype boxTracker struct {\n\tkeyText   string\n\tsides     [4]boxSide\n\tallowAuto bool // If true, allow the \"auto\" keyword\n\timportant bool // True if all active rules were flagged as \"!important\"\n\tkey       css_ast.D\n}\n\ntype unitSafetyStatus uint8\n\nconst (\n\tunitSafe         unitSafetyStatus = iota // \"margin: 0 1px 2cm 3%;\"\n\tunitUnsafeSingle                         // \"margin: 0 1vw 2vw 3vw;\"\n\tunitUnsafeMixed                          // \"margin: 0 1vw 2vh 3ch;\"\n)\n\n// We can only compact rules together if they have the same unit safety level.\n// We want to avoid a situation where the browser treats some of the original\n// rules as valid and others as invalid.\n//\n//   Safe:\n//     top: 1px; left: 0; bottom: 1px; right: 0;\n//     top: 1Q; left: 2Q; bottom: 3Q; right: 4Q;\n//\n//   Unsafe:\n//     top: 1vh; left: 2vw; bottom: 3vh; right: 4vw;\n//     top: 1Q; left: 2Q; bottom: 3Q; right: 0;\n//     inset: 1Q 0 0 0; top: 0;\n//\ntype unitSafetyTracker struct {\n\tunit   string\n\tstatus unitSafetyStatus\n}\n\nfunc (a unitSafetyTracker) isSafeWith(b unitSafetyTracker) bool {\n\treturn a.status == b.status && a.status != unitUnsafeMixed && (a.status != unitUnsafeSingle || a.unit == b.unit)\n}\n\nfunc (t *unitSafetyTracker) includeUnitOf(token css_ast.Token) {\n\tswitch token.Kind {\n\tcase css_lexer.TNumber:\n\t\tif token.Text == \"0\" {\n\t\t\treturn\n\t\t}\n\n\tcase css_lexer.TPercentage:\n\t\treturn\n\n\tcase css_lexer.TDimension:\n\t\tif token.DimensionUnitIsSafeLength() {\n\t\t\treturn\n\t\t} else if unit := token.DimensionUnit(); t.status == unitSafe {\n\t\t\tt.status = unitUnsafeSingle\n\t\t\tt.unit = unit\n\t\t\treturn\n\t\t} else if t.status == unitUnsafeSingle && t.unit == unit {\n\t\t\treturn\n\t\t}\n\t}\n\n\tt.status = unitUnsafeMixed\n}\n\nfunc (box *boxTracker) updateSide(rules []css_ast.Rule, side int, new boxSide) {\n\tif old := box.sides[side]; old.token.Kind != css_lexer.TEndOfFile &&\n\t\t(!new.wasSingleRule || old.wasSingleRule) &&\n\t\told.unitSafety.status == unitSafe && new.unitSafety.status == unitSafe {\n\t\trules[old.ruleIndex] = css_ast.Rule{}\n\t}\n\tbox.sides[side] = new\n}\n\nfunc (box *boxTracker) mangleSides(rules []css_ast.Rule, decl *css_ast.RDeclaration, index int, minifyWhitespace bool) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif box.important != decl.Important {\n\t\tbox.sides = [4]boxSide{}\n\t\tbox.important = decl.Important\n\t}\n\n\tallowedIdent := \"\"\n\tif box.allowAuto {\n\t\tallowedIdent = \"auto\"\n\t}\n\tif quad, ok := expandTokenQuad(decl.Value, allowedIdent); ok {\n\t\t// Use a single tracker for the whole rule\n\t\tunitSafety := unitSafetyTracker{}\n\t\tfor _, t := range quad {\n\t\t\tif !box.allowAuto || t.Kind.IsNumeric() {\n\t\t\t\tunitSafety.includeUnitOf(t)\n\t\t\t}\n\t\t}\n\t\tfor side, t := range quad {\n\t\t\tif unitSafety.status == unitSafe {\n\t\t\t\tt.TurnLengthIntoNumberIfZero()\n\t\t\t}\n\t\t\tbox.updateSide(rules, side, boxSide{\n\t\t\t\ttoken:      t,\n\t\t\t\truleIndex:  uint32(index),\n\t\t\t\tunitSafety: unitSafety,\n\t\t\t})\n\t\t}\n\t\tbox.compactRules(rules, decl.KeyRange, minifyWhitespace)\n\t} else {\n\t\tbox.sides = [4]boxSide{}\n\t}\n}\n\nfunc (box *boxTracker) mangleSide(rules []css_ast.Rule, decl *css_ast.RDeclaration, index int, minifyWhitespace bool, side int) {\n\t// Reset if we see a change in the \"!important\" flag\n\tif box.important != decl.Important {\n\t\tbox.sides = [4]boxSide{}\n\t\tbox.important = decl.Important\n\t}\n\n\tif tokens := decl.Value; len(tokens) == 1 {\n\t\tif t := tokens[0]; t.Kind.IsNumeric() || (t.Kind == css_lexer.TIdent && box.allowAuto && t.Text == \"auto\") {\n\t\t\tunitSafety := unitSafetyTracker{}\n\t\t\tif !box.allowAuto || t.Kind.IsNumeric() {\n\t\t\t\tunitSafety.includeUnitOf(t)\n\t\t\t}\n\t\t\tif unitSafety.status == unitSafe && t.TurnLengthIntoNumberIfZero() {\n\t\t\t\ttokens[0] = t\n\t\t\t}\n\t\t\tbox.updateSide(rules, side, boxSide{\n\t\t\t\ttoken:         t,\n\t\t\t\truleIndex:     uint32(index),\n\t\t\t\twasSingleRule: true,\n\t\t\t\tunitSafety:    unitSafety,\n\t\t\t})\n\t\t\tbox.compactRules(rules, decl.KeyRange, minifyWhitespace)\n\t\t\treturn\n\t\t}\n\t}\n\n\tbox.sides = [4]boxSide{}\n}\n\nfunc (box *boxTracker) compactRules(rules []css_ast.Rule, keyRange logger.Range, minifyWhitespace bool) {\n\t// All tokens must be present\n\tif eof := css_lexer.TEndOfFile; box.sides[0].token.Kind == eof || box.sides[1].token.Kind == eof ||\n\t\tbox.sides[2].token.Kind == eof || box.sides[3].token.Kind == eof {\n\t\treturn\n\t}\n\n\t// All tokens must have the same unit\n\tfor _, side := range box.sides[1:] {\n\t\tif !side.unitSafety.isSafeWith(box.sides[0].unitSafety) {\n\t\t\treturn\n\t\t}\n\t}\n\n\t// Generate the most minimal representation\n\ttokens := compactTokenQuad(\n\t\tbox.sides[0].token,\n\t\tbox.sides[1].token,\n\t\tbox.sides[2].token,\n\t\tbox.sides[3].token,\n\t\tminifyWhitespace,\n\t)\n\n\t// Remove all of the existing declarations\n\trules[box.sides[0].ruleIndex] = css_ast.Rule{}\n\trules[box.sides[1].ruleIndex] = css_ast.Rule{}\n\trules[box.sides[2].ruleIndex] = css_ast.Rule{}\n\trules[box.sides[3].ruleIndex] = css_ast.Rule{}\n\n\t// Insert the combined declaration where the last rule was\n\trules[box.sides[3].ruleIndex].Data = &css_ast.RDeclaration{\n\t\tKey:       box.key,\n\t\tKeyText:   box.keyText,\n\t\tValue:     tokens,\n\t\tKeyRange:  keyRange,\n\t\tImportant: box.important,\n\t}\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_box_shadow.go",
    "content": "package css_parser\n\nimport (\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\nfunc (p *parser) mangleBoxShadow(tokens []css_ast.Token) []css_ast.Token {\n\tinsetCount := 0\n\tcolorCount := 0\n\tnumbersBegin := 0\n\tnumbersCount := 0\n\tnumbersDone := false\n\tfoundUnexpectedToken := false\n\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TNumber || t.Kind == css_lexer.TDimension {\n\t\t\tif numbersDone {\n\t\t\t\t// Track if we found a non-number in between two numbers\n\t\t\t\tfoundUnexpectedToken = true\n\t\t\t}\n\t\t\tif t.TurnLengthIntoNumberIfZero() {\n\t\t\t\t// \"0px\" => \"0\"\n\t\t\t\ttokens[i] = t\n\t\t\t}\n\t\t\tif numbersCount == 0 {\n\t\t\t\t// Track the index of the first number\n\t\t\t\tnumbersBegin = i\n\t\t\t}\n\t\t\tnumbersCount++\n\t\t} else {\n\t\t\tif numbersCount != 0 {\n\t\t\t\t// Track when we find a non-number after a number\n\t\t\t\tnumbersDone = true\n\t\t\t}\n\t\t\tif hex, ok := parseColor(t); ok {\n\t\t\t\tcolorCount++\n\t\t\t\ttokens[i] = p.mangleColor(t, hex)\n\t\t\t} else if t.Kind == css_lexer.TIdent && t.Text == \"inset\" {\n\t\t\t\tinsetCount++\n\t\t\t} else {\n\t\t\t\t// Track if we found a token other than a number, a color, or \"inset\"\n\t\t\t\tfoundUnexpectedToken = true\n\t\t\t}\n\t\t}\n\t}\n\n\t// If everything looks like a valid rule, trim trailing zeros off the numbers.\n\t// There are three valid configurations of numbers:\n\t//\n\t//   offset-x | offset-y\n\t//   offset-x | offset-y | blur-radius\n\t//   offset-x | offset-y | blur-radius | spread-radius\n\t//\n\t// If omitted, blur-radius and spread-radius are implied to be zero.\n\tif insetCount <= 1 && colorCount <= 1 && numbersCount > 2 && numbersCount <= 4 && !foundUnexpectedToken {\n\t\tnumbersEnd := numbersBegin + numbersCount\n\t\tfor numbersCount > 2 && tokens[numbersBegin+numbersCount-1].IsZero() {\n\t\t\tnumbersCount--\n\t\t}\n\t\ttokens = append(tokens[:numbersBegin+numbersCount], tokens[numbersEnd:]...)\n\t}\n\n\t// Set the whitespace flags\n\tfor i := range tokens {\n\t\tvar whitespace css_ast.WhitespaceFlags\n\t\tif i > 0 || !p.options.MinifyWhitespace {\n\t\t\twhitespace |= css_ast.WhitespaceBefore\n\t\t}\n\t\tif i+1 < len(tokens) {\n\t\t\twhitespace |= css_ast.WhitespaceAfter\n\t\t}\n\t\ttokens[i].Whitespace = whitespace\n\t}\n\treturn tokens\n}\n\nfunc (p *parser) mangleBoxShadows(tokens []css_ast.Token) []css_ast.Token {\n\tn := len(tokens)\n\tend := 0\n\ti := 0\n\n\tfor i < n {\n\t\t// Find the comma or the end of the token list\n\t\tcomma := i\n\t\tfor comma < n && tokens[comma].Kind != css_lexer.TComma {\n\t\t\tcomma++\n\t\t}\n\n\t\t// Mangle this individual shadow\n\t\tend += copy(tokens[end:], p.mangleBoxShadow(tokens[i:comma]))\n\n\t\t// Skip over the comma\n\t\tif comma < n {\n\t\t\ttokens[end] = tokens[comma]\n\t\t\tend++\n\t\t\tcomma++\n\t\t}\n\t\ti = comma\n\t}\n\n\treturn tokens[:end]\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_color.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/compat\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\n// These names are shorter than their hex codes\nvar shortColorName = map[uint32]string{\n\t0x000080ff: \"navy\",\n\t0x008000ff: \"green\",\n\t0x008080ff: \"teal\",\n\t0x4b0082ff: \"indigo\",\n\t0x800000ff: \"maroon\",\n\t0x800080ff: \"purple\",\n\t0x808000ff: \"olive\",\n\t0x808080ff: \"gray\",\n\t0xa0522dff: \"sienna\",\n\t0xa52a2aff: \"brown\",\n\t0xc0c0c0ff: \"silver\",\n\t0xcd853fff: \"peru\",\n\t0xd2b48cff: \"tan\",\n\t0xda70d6ff: \"orchid\",\n\t0xdda0ddff: \"plum\",\n\t0xee82eeff: \"violet\",\n\t0xf0e68cff: \"khaki\",\n\t0xf0ffffff: \"azure\",\n\t0xf5deb3ff: \"wheat\",\n\t0xf5f5dcff: \"beige\",\n\t0xfa8072ff: \"salmon\",\n\t0xfaf0e6ff: \"linen\",\n\t0xff0000ff: \"red\",\n\t0xff6347ff: \"tomato\",\n\t0xff7f50ff: \"coral\",\n\t0xffa500ff: \"orange\",\n\t0xffc0cbff: \"pink\",\n\t0xffd700ff: \"gold\",\n\t0xffe4c4ff: \"bisque\",\n\t0xfffafaff: \"snow\",\n\t0xfffff0ff: \"ivory\",\n}\n\nvar colorNameToHex = map[string]uint32{\n\t\"black\":                0x000000ff,\n\t\"silver\":               0xc0c0c0ff,\n\t\"gray\":                 0x808080ff,\n\t\"white\":                0xffffffff,\n\t\"maroon\":               0x800000ff,\n\t\"red\":                  0xff0000ff,\n\t\"purple\":               0x800080ff,\n\t\"fuchsia\":              0xff00ffff,\n\t\"green\":                0x008000ff,\n\t\"lime\":                 0x00ff00ff,\n\t\"olive\":                0x808000ff,\n\t\"yellow\":               0xffff00ff,\n\t\"navy\":                 0x000080ff,\n\t\"blue\":                 0x0000ffff,\n\t\"teal\":                 0x008080ff,\n\t\"aqua\":                 0x00ffffff,\n\t\"orange\":               0xffa500ff,\n\t\"aliceblue\":            0xf0f8ffff,\n\t\"antiquewhite\":         0xfaebd7ff,\n\t\"aquamarine\":           0x7fffd4ff,\n\t\"azure\":                0xf0ffffff,\n\t\"beige\":                0xf5f5dcff,\n\t\"bisque\":               0xffe4c4ff,\n\t\"blanchedalmond\":       0xffebcdff,\n\t\"blueviolet\":           0x8a2be2ff,\n\t\"brown\":                0xa52a2aff,\n\t\"burlywood\":            0xdeb887ff,\n\t\"cadetblue\":            0x5f9ea0ff,\n\t\"chartreuse\":           0x7fff00ff,\n\t\"chocolate\":            0xd2691eff,\n\t\"coral\":                0xff7f50ff,\n\t\"cornflowerblue\":       0x6495edff,\n\t\"cornsilk\":             0xfff8dcff,\n\t\"crimson\":              0xdc143cff,\n\t\"cyan\":                 0x00ffffff,\n\t\"darkblue\":             0x00008bff,\n\t\"darkcyan\":             0x008b8bff,\n\t\"darkgoldenrod\":        0xb8860bff,\n\t\"darkgray\":             0xa9a9a9ff,\n\t\"darkgreen\":            0x006400ff,\n\t\"darkgrey\":             0xa9a9a9ff,\n\t\"darkkhaki\":            0xbdb76bff,\n\t\"darkmagenta\":          0x8b008bff,\n\t\"darkolivegreen\":       0x556b2fff,\n\t\"darkorange\":           0xff8c00ff,\n\t\"darkorchid\":           0x9932ccff,\n\t\"darkred\":              0x8b0000ff,\n\t\"darksalmon\":           0xe9967aff,\n\t\"darkseagreen\":         0x8fbc8fff,\n\t\"darkslateblue\":        0x483d8bff,\n\t\"darkslategray\":        0x2f4f4fff,\n\t\"darkslategrey\":        0x2f4f4fff,\n\t\"darkturquoise\":        0x00ced1ff,\n\t\"darkviolet\":           0x9400d3ff,\n\t\"deeppink\":             0xff1493ff,\n\t\"deepskyblue\":          0x00bfffff,\n\t\"dimgray\":              0x696969ff,\n\t\"dimgrey\":              0x696969ff,\n\t\"dodgerblue\":           0x1e90ffff,\n\t\"firebrick\":            0xb22222ff,\n\t\"floralwhite\":          0xfffaf0ff,\n\t\"forestgreen\":          0x228b22ff,\n\t\"gainsboro\":            0xdcdcdcff,\n\t\"ghostwhite\":           0xf8f8ffff,\n\t\"gold\":                 0xffd700ff,\n\t\"goldenrod\":            0xdaa520ff,\n\t\"greenyellow\":          0xadff2fff,\n\t\"grey\":                 0x808080ff,\n\t\"honeydew\":             0xf0fff0ff,\n\t\"hotpink\":              0xff69b4ff,\n\t\"indianred\":            0xcd5c5cff,\n\t\"indigo\":               0x4b0082ff,\n\t\"ivory\":                0xfffff0ff,\n\t\"khaki\":                0xf0e68cff,\n\t\"lavender\":             0xe6e6faff,\n\t\"lavenderblush\":        0xfff0f5ff,\n\t\"lawngreen\":            0x7cfc00ff,\n\t\"lemonchiffon\":         0xfffacdff,\n\t\"lightblue\":            0xadd8e6ff,\n\t\"lightcoral\":           0xf08080ff,\n\t\"lightcyan\":            0xe0ffffff,\n\t\"lightgoldenrodyellow\": 0xfafad2ff,\n\t\"lightgray\":            0xd3d3d3ff,\n\t\"lightgreen\":           0x90ee90ff,\n\t\"lightgrey\":            0xd3d3d3ff,\n\t\"lightpink\":            0xffb6c1ff,\n\t\"lightsalmon\":          0xffa07aff,\n\t\"lightseagreen\":        0x20b2aaff,\n\t\"lightskyblue\":         0x87cefaff,\n\t\"lightslategray\":       0x778899ff,\n\t\"lightslategrey\":       0x778899ff,\n\t\"lightsteelblue\":       0xb0c4deff,\n\t\"lightyellow\":          0xffffe0ff,\n\t\"limegreen\":            0x32cd32ff,\n\t\"linen\":                0xfaf0e6ff,\n\t\"magenta\":              0xff00ffff,\n\t\"mediumaquamarine\":     0x66cdaaff,\n\t\"mediumblue\":           0x0000cdff,\n\t\"mediumorchid\":         0xba55d3ff,\n\t\"mediumpurple\":         0x9370dbff,\n\t\"mediumseagreen\":       0x3cb371ff,\n\t\"mediumslateblue\":      0x7b68eeff,\n\t\"mediumspringgreen\":    0x00fa9aff,\n\t\"mediumturquoise\":      0x48d1ccff,\n\t\"mediumvioletred\":      0xc71585ff,\n\t\"midnightblue\":         0x191970ff,\n\t\"mintcream\":            0xf5fffaff,\n\t\"mistyrose\":            0xffe4e1ff,\n\t\"moccasin\":             0xffe4b5ff,\n\t\"navajowhite\":          0xffdeadff,\n\t\"oldlace\":              0xfdf5e6ff,\n\t\"olivedrab\":            0x6b8e23ff,\n\t\"orangered\":            0xff4500ff,\n\t\"orchid\":               0xda70d6ff,\n\t\"palegoldenrod\":        0xeee8aaff,\n\t\"palegreen\":            0x98fb98ff,\n\t\"paleturquoise\":        0xafeeeeff,\n\t\"palevioletred\":        0xdb7093ff,\n\t\"papayawhip\":           0xffefd5ff,\n\t\"peachpuff\":            0xffdab9ff,\n\t\"peru\":                 0xcd853fff,\n\t\"pink\":                 0xffc0cbff,\n\t\"plum\":                 0xdda0ddff,\n\t\"powderblue\":           0xb0e0e6ff,\n\t\"rosybrown\":            0xbc8f8fff,\n\t\"royalblue\":            0x4169e1ff,\n\t\"saddlebrown\":          0x8b4513ff,\n\t\"salmon\":               0xfa8072ff,\n\t\"sandybrown\":           0xf4a460ff,\n\t\"seagreen\":             0x2e8b57ff,\n\t\"seashell\":             0xfff5eeff,\n\t\"sienna\":               0xa0522dff,\n\t\"skyblue\":              0x87ceebff,\n\t\"slateblue\":            0x6a5acdff,\n\t\"slategray\":            0x708090ff,\n\t\"slategrey\":            0x708090ff,\n\t\"snow\":                 0xfffafaff,\n\t\"springgreen\":          0x00ff7fff,\n\t\"steelblue\":            0x4682b4ff,\n\t\"tan\":                  0xd2b48cff,\n\t\"thistle\":              0xd8bfd8ff,\n\t\"tomato\":               0xff6347ff,\n\t\"turquoise\":            0x40e0d0ff,\n\t\"violet\":               0xee82eeff,\n\t\"wheat\":                0xf5deb3ff,\n\t\"whitesmoke\":           0xf5f5f5ff,\n\t\"yellowgreen\":          0x9acd32ff,\n\t\"rebeccapurple\":        0x663399ff,\n}\n\nfunc parseHex(text string) (uint32, bool) {\n\thex := uint32(0)\n\tfor _, c := range text {\n\t\thex <<= 4\n\t\tswitch {\n\t\tcase c >= '0' && c <= '9':\n\t\t\thex |= uint32(c) - '0'\n\t\tcase c >= 'a' && c <= 'f':\n\t\t\thex |= uint32(c) - ('a' - 10)\n\t\tcase c >= 'A' && c <= 'F':\n\t\t\thex |= uint32(c) - ('A' - 10)\n\t\tdefault:\n\t\t\treturn 0, false\n\t\t}\n\t}\n\treturn hex, true\n}\n\n// 0xAABBCCDD => 0xABCD\nfunc compactHex(v uint32) uint32 {\n\treturn ((v & 0x0FF00000) >> 12) | ((v & 0x00000FF0) >> 4)\n}\n\n// 0xABCD => 0xAABBCCDD\nfunc expandHex(v uint32) uint32 {\n\treturn ((v & 0xF000) << 16) | ((v & 0xFF00) << 12) | ((v & 0x0FF0) << 8) | ((v & 0x00FF) << 4) | (v & 0x000F)\n}\n\nfunc hexR(v uint32) int { return int(v >> 24) }\nfunc hexG(v uint32) int { return int((v >> 16) & 255) }\nfunc hexB(v uint32) int { return int((v >> 8) & 255) }\nfunc hexA(v uint32) int { return int(v & 255) }\n\nfunc floatToStringForColor(a float64) string {\n\ttext := fmt.Sprintf(\"%.03f\", a)\n\tfor text[len(text)-1] == '0' {\n\t\ttext = text[:len(text)-1]\n\t}\n\tif text[len(text)-1] == '.' {\n\t\ttext = text[:len(text)-1]\n\t}\n\treturn text\n}\n\nfunc degreesForAngle(token css_ast.Token) (float64, bool) {\n\tswitch token.Kind {\n\tcase css_lexer.TNumber:\n\t\tif value, err := strconv.ParseFloat(token.Text, 64); err == nil {\n\t\t\treturn value, true\n\t\t}\n\n\tcase css_lexer.TDimension:\n\t\tif value, err := strconv.ParseFloat(token.DimensionValue(), 64); err == nil {\n\t\t\tswitch token.DimensionUnit() {\n\t\t\tcase \"deg\":\n\t\t\t\treturn value, true\n\t\t\tcase \"grad\":\n\t\t\t\treturn value * (360.0 / 400.0), true\n\t\t\tcase \"rad\":\n\t\t\t\treturn value * (180.0 / math.Pi), true\n\t\t\tcase \"turn\":\n\t\t\t\treturn value * 360.0, true\n\t\t\t}\n\t\t}\n\t}\n\treturn 0, false\n}\n\nfunc lowerAlphaPercentageToNumber(token css_ast.Token) css_ast.Token {\n\tif token.Kind == css_lexer.TPercentage {\n\t\tif value, err := strconv.ParseFloat(token.Text[:len(token.Text)-1], 64); err == nil {\n\t\t\ttoken.Kind = css_lexer.TNumber\n\t\t\ttoken.Text = floatToStringForColor(value / 100.0)\n\t\t}\n\t}\n\treturn token\n}\n\n// Convert newer color syntax to older color syntax for older browsers\nfunc (p *parser) lowerColor(token css_ast.Token) css_ast.Token {\n\ttext := token.Text\n\n\tswitch token.Kind {\n\tcase css_lexer.THash:\n\t\tif p.options.UnsupportedCSSFeatures.Has(compat.HexRGBA) {\n\t\t\tswitch len(text) {\n\t\t\tcase 4:\n\t\t\t\t// \"#1234\" => \"rgba(1, 2, 3, 0.004)\"\n\t\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\t\thex = expandHex(hex)\n\t\t\t\t\ttoken.Kind = css_lexer.TFunction\n\t\t\t\t\ttoken.Text = \"rgba\"\n\t\t\t\t\tcommaToken := p.commaToken()\n\t\t\t\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexR(hex))}, commaToken,\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexG(hex))}, commaToken,\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexB(hex))}, commaToken,\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: floatToStringForColor(float64(hexA(hex)) / 255)},\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\tcase 8:\n\t\t\t\t// \"#12345678\" => \"rgba(18, 52, 86, 0.47)\"\n\t\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\t\ttoken.Kind = css_lexer.TFunction\n\t\t\t\t\ttoken.Text = \"rgba\"\n\t\t\t\t\tcommaToken := p.commaToken()\n\t\t\t\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexR(hex))}, commaToken,\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexG(hex))}, commaToken,\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexB(hex))}, commaToken,\n\t\t\t\t\t\t{Kind: css_lexer.TNumber, Text: floatToStringForColor(float64(hexA(hex)) / 255)},\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tcase css_lexer.TIdent:\n\t\tif text == \"rebeccapurple\" && p.options.UnsupportedCSSFeatures.Has(compat.RebeccaPurple) {\n\t\t\ttoken.Kind = css_lexer.THash\n\t\t\ttoken.Text = \"663399\"\n\t\t}\n\n\tcase css_lexer.TFunction:\n\t\tswitch text {\n\t\tcase \"rgb\", \"rgba\", \"hsl\", \"hsla\":\n\t\t\tif p.options.UnsupportedCSSFeatures.Has(compat.Modern_RGB_HSL) {\n\t\t\t\targs := *token.Children\n\t\t\t\tremoveAlpha := false\n\t\t\t\taddAlpha := false\n\n\t\t\t\t// \"hsl(1deg, 2%, 3%)\" => \"hsl(1, 2%, 3%)\"\n\t\t\t\tif (text == \"hsl\" || text == \"hsla\") && len(args) > 0 {\n\t\t\t\t\tif degrees, ok := degreesForAngle(args[0]); ok {\n\t\t\t\t\t\targs[0].Kind = css_lexer.TNumber\n\t\t\t\t\t\targs[0].Text = floatToStringForColor(degrees)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// These check for \"IsNumeric\" to reject \"var()\" since a single \"var()\"\n\t\t\t\t// can substitute for multiple tokens and that messes up pattern matching\n\t\t\t\tswitch len(args) {\n\t\t\t\tcase 3:\n\t\t\t\t\t// \"rgba(1 2 3)\" => \"rgb(1, 2, 3)\"\n\t\t\t\t\t// \"hsla(1 2% 3%)\" => \"hsl(1, 2%, 3%)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind.IsNumeric() && args[2].Kind.IsNumeric() {\n\t\t\t\t\t\tremoveAlpha = true\n\t\t\t\t\t\targs[0].Whitespace = 0\n\t\t\t\t\t\targs[1].Whitespace = 0\n\t\t\t\t\t\tcommaToken := p.commaToken()\n\t\t\t\t\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t\t\t\t\targs[0], commaToken,\n\t\t\t\t\t\t\targs[1], commaToken,\n\t\t\t\t\t\t\targs[2],\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase 5:\n\t\t\t\t\t// \"rgba(1, 2, 3)\" => \"rgb(1, 2, 3)\"\n\t\t\t\t\t// \"hsla(1, 2%, 3%)\" => \"hsl(1%, 2%, 3%)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[2].Kind.IsNumeric() && args[3].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[4].Kind.IsNumeric() {\n\t\t\t\t\t\tremoveAlpha = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\n\t\t\t\t\t// \"rgb(1 2 3 / 4%)\" => \"rgba(1, 2, 3, 0.04)\"\n\t\t\t\t\t// \"hsl(1 2% 3% / 4%)\" => \"hsla(1, 2%, 3%, 0.04)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind.IsNumeric() && args[2].Kind.IsNumeric() &&\n\t\t\t\t\t\targs[3].Kind == css_lexer.TDelimSlash && args[4].Kind.IsNumeric() {\n\t\t\t\t\t\taddAlpha = true\n\t\t\t\t\t\targs[0].Whitespace = 0\n\t\t\t\t\t\targs[1].Whitespace = 0\n\t\t\t\t\t\targs[2].Whitespace = 0\n\t\t\t\t\t\tcommaToken := p.commaToken()\n\t\t\t\t\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t\t\t\t\targs[0], commaToken,\n\t\t\t\t\t\t\targs[1], commaToken,\n\t\t\t\t\t\t\targs[2], commaToken,\n\t\t\t\t\t\t\tlowerAlphaPercentageToNumber(args[4]),\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase 7:\n\t\t\t\t\t// \"rgb(1%, 2%, 3%, 4%)\" => \"rgba(1%, 2%, 3%, 0.04)\"\n\t\t\t\t\t// \"hsl(1, 2%, 3%, 4%)\" => \"hsla(1, 2%, 3%, 0.04)\"\n\t\t\t\t\tif args[0].Kind.IsNumeric() && args[1].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[2].Kind.IsNumeric() && args[3].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[4].Kind.IsNumeric() && args[5].Kind == css_lexer.TComma &&\n\t\t\t\t\t\targs[6].Kind.IsNumeric() {\n\t\t\t\t\t\taddAlpha = true\n\t\t\t\t\t\targs[6] = lowerAlphaPercentageToNumber(args[6])\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif removeAlpha {\n\t\t\t\t\tif text == \"rgba\" {\n\t\t\t\t\t\ttoken.Text = \"rgb\"\n\t\t\t\t\t} else if text == \"hsla\" {\n\t\t\t\t\t\ttoken.Text = \"hsl\"\n\t\t\t\t\t}\n\t\t\t\t} else if addAlpha {\n\t\t\t\t\tif text == \"rgb\" {\n\t\t\t\t\t\ttoken.Text = \"rgba\"\n\t\t\t\t\t} else if text == \"hsl\" {\n\t\t\t\t\t\ttoken.Text = \"hsla\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn token\n}\n\nfunc parseColor(token css_ast.Token) (uint32, bool) {\n\ttext := token.Text\n\n\tswitch token.Kind {\n\tcase css_lexer.TIdent:\n\t\tif hex, ok := colorNameToHex[strings.ToLower(text)]; ok {\n\t\t\treturn hex, true\n\t\t}\n\n\tcase css_lexer.THash:\n\t\tswitch len(text) {\n\t\tcase 3:\n\t\t\t// \"#123\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn (expandHex(hex) << 8) | 0xFF, true\n\t\t\t}\n\n\t\tcase 4:\n\t\t\t// \"#1234\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn expandHex(hex), true\n\t\t\t}\n\n\t\tcase 6:\n\t\t\t// \"#112233\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn (hex << 8) | 0xFF, true\n\t\t\t}\n\n\t\tcase 8:\n\t\t\t// \"#11223344\"\n\t\t\tif hex, ok := parseHex(text); ok {\n\t\t\t\treturn hex, true\n\t\t\t}\n\t\t}\n\n\tcase css_lexer.TFunction:\n\t\tswitch text {\n\t\tcase \"rgb\", \"rgba\":\n\t\t\targs := *token.Children\n\t\t\tvar r, g, b, a css_ast.Token\n\n\t\t\tswitch len(args) {\n\t\t\tcase 3:\n\t\t\t\t// \"rgb(1 2 3)\"\n\t\t\t\tr, g, b = args[0], args[1], args[2]\n\n\t\t\tcase 5:\n\t\t\t\t// \"rgba(1, 2, 3)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma {\n\t\t\t\t\tr, g, b = args[0], args[2], args[4]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// \"rgb(1 2 3 / 4%)\"\n\t\t\t\tif args[3].Kind == css_lexer.TDelimSlash {\n\t\t\t\t\tr, g, b, a = args[0], args[1], args[2], args[4]\n\t\t\t\t}\n\n\t\t\tcase 7:\n\t\t\t\t// \"rgb(1%, 2%, 3%, 4%)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma && args[5].Kind == css_lexer.TComma {\n\t\t\t\t\tr, g, b, a = args[0], args[2], args[4], args[6]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif r, ok := parseColorByte(r, 1); ok {\n\t\t\t\tif g, ok := parseColorByte(g, 1); ok {\n\t\t\t\t\tif b, ok := parseColorByte(b, 1); ok {\n\t\t\t\t\t\tif a, ok := parseAlphaByte(a); ok {\n\t\t\t\t\t\t\treturn uint32((r << 24) | (g << 16) | (b << 8) | a), true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase \"hsl\", \"hsla\":\n\t\t\targs := *token.Children\n\t\t\tvar h, s, l, a css_ast.Token\n\n\t\t\tswitch len(args) {\n\t\t\tcase 3:\n\t\t\t\t// \"hsl(1 2 3)\"\n\t\t\t\th, s, l = args[0], args[1], args[2]\n\n\t\t\tcase 5:\n\t\t\t\t// \"hsla(1, 2, 3)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma {\n\t\t\t\t\th, s, l = args[0], args[2], args[4]\n\t\t\t\t\tbreak\n\t\t\t\t}\n\n\t\t\t\t// \"hsl(1 2 3 / 4%)\"\n\t\t\t\tif args[3].Kind == css_lexer.TDelimSlash {\n\t\t\t\t\th, s, l, a = args[0], args[1], args[2], args[4]\n\t\t\t\t}\n\n\t\t\tcase 7:\n\t\t\t\t// \"hsl(1%, 2%, 3%, 4%)\"\n\t\t\t\tif args[1].Kind == css_lexer.TComma && args[3].Kind == css_lexer.TComma && args[5].Kind == css_lexer.TComma {\n\t\t\t\t\th, s, l, a = args[0], args[2], args[4], args[6]\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Convert from HSL to RGB. The algorithm is from the section\n\t\t\t// \"Converting HSL colors to sRGB colors\" in the specification.\n\t\t\tif h, ok := degreesForAngle(h); ok {\n\t\t\t\tif s, ok := s.FractionForPercentage(); ok {\n\t\t\t\t\tif l, ok := l.FractionForPercentage(); ok {\n\t\t\t\t\t\tif a, ok := parseAlphaByte(a); ok {\n\t\t\t\t\t\t\th /= 360.0\n\t\t\t\t\t\t\tvar t2 float64\n\t\t\t\t\t\t\tif l <= 0.5 {\n\t\t\t\t\t\t\t\tt2 = l * (s + 1)\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tt2 = l + s - (l * s)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tt1 := l*2 - t2\n\t\t\t\t\t\t\tr := hueToRgb(t1, t2, h+1.0/3.0)\n\t\t\t\t\t\t\tg := hueToRgb(t1, t2, h)\n\t\t\t\t\t\t\tb := hueToRgb(t1, t2, h-1.0/3.0)\n\t\t\t\t\t\t\treturn uint32((r << 24) | (g << 16) | (b << 8) | a), true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn 0, false\n}\n\nfunc hueToRgb(t1 float64, t2 float64, hue float64) uint32 {\n\thue -= math.Floor(hue)\n\thue *= 6.0\n\tvar f float64\n\tif hue < 1 {\n\t\tf = (t2-t1)*hue + t1\n\t} else if hue < 3 {\n\t\tf = t2\n\t} else if hue < 4 {\n\t\tf = (t2-t1)*(4-hue) + t1\n\t} else {\n\t\tf = t1\n\t}\n\ti := int(math.Round(f * 255))\n\tif i < 0 {\n\t\ti = 0\n\t} else if i > 255 {\n\t\ti = 255\n\t}\n\treturn uint32(i)\n}\n\nfunc parseAlphaByte(token css_ast.Token) (uint32, bool) {\n\tif token.Kind == css_lexer.T(0) {\n\t\treturn 255, true\n\t}\n\treturn parseColorByte(token, 255)\n}\n\nfunc parseColorByte(token css_ast.Token, scale float64) (uint32, bool) {\n\tvar i int\n\tvar ok bool\n\n\tswitch token.Kind {\n\tcase css_lexer.TNumber:\n\t\tif f, err := strconv.ParseFloat(token.Text, 64); err == nil {\n\t\t\ti = int(math.Round(f * scale))\n\t\t\tok = true\n\t\t}\n\n\tcase css_lexer.TPercentage:\n\t\tif f, err := strconv.ParseFloat(token.PercentageValue(), 64); err == nil {\n\t\t\ti = int(math.Round(f * (255.0 / 100.0)))\n\t\t\tok = true\n\t\t}\n\t}\n\n\tif i < 0 {\n\t\ti = 0\n\t} else if i > 255 {\n\t\ti = 255\n\t}\n\treturn uint32(i), ok\n}\n\nfunc (p *parser) mangleColor(token css_ast.Token, hex uint32) css_ast.Token {\n\t// Note: Do NOT remove color information from fully transparent colors.\n\t// Safari behaves differently than other browsers for color interpolation:\n\t// https://css-tricks.com/thing-know-gradients-transparent-black/\n\n\tif hexA(hex) == 255 {\n\t\ttoken.Children = nil\n\t\tif name, ok := shortColorName[hex]; ok {\n\t\t\ttoken.Kind = css_lexer.TIdent\n\t\t\ttoken.Text = name\n\t\t} else {\n\t\t\ttoken.Kind = css_lexer.THash\n\t\t\thex >>= 8\n\t\t\tcompact := compactHex(hex)\n\t\t\tif hex == expandHex(compact) {\n\t\t\t\ttoken.Text = fmt.Sprintf(\"%03x\", compact)\n\t\t\t} else {\n\t\t\t\ttoken.Text = fmt.Sprintf(\"%06x\", hex)\n\t\t\t}\n\t\t}\n\t} else if !p.options.UnsupportedCSSFeatures.Has(compat.HexRGBA) {\n\t\ttoken.Children = nil\n\t\ttoken.Kind = css_lexer.THash\n\t\tcompact := compactHex(hex)\n\t\tif hex == expandHex(compact) {\n\t\t\ttoken.Text = fmt.Sprintf(\"%04x\", compact)\n\t\t} else {\n\t\t\ttoken.Text = fmt.Sprintf(\"%08x\", hex)\n\t\t}\n\t} else {\n\t\ttoken.Kind = css_lexer.TFunction\n\t\ttoken.Text = \"rgba\"\n\t\tcommaToken := p.commaToken()\n\t\tindex := hexA(hex) * 4\n\t\talpha := alphaFractionTable[index : index+4]\n\t\tif space := strings.IndexByte(alpha, ' '); space != -1 {\n\t\t\talpha = alpha[:space]\n\t\t}\n\t\ttoken.Children = &[]css_ast.Token{\n\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexR(hex))}, commaToken,\n\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexG(hex))}, commaToken,\n\t\t\t{Kind: css_lexer.TNumber, Text: strconv.Itoa(hexB(hex))}, commaToken,\n\t\t\t{Kind: css_lexer.TNumber, Text: alpha},\n\t\t}\n\t}\n\n\treturn token\n}\n\n// Every four characters in this table is the fraction for that index\nconst alphaFractionTable string = \"\" +\n\t\"0   .004.008.01 .016.02 .024.027.03 .035.04 .043.047.05 .055.06 \" +\n\t\".063.067.07 .075.08 .082.086.09 .094.098.1  .106.11 .114.118.12 \" +\n\t\".125.13 .133.137.14 .145.15 .153.157.16 .165.17 .173.176.18 .184\" +\n\t\".19 .192.196.2  .204.208.21 .216.22 .224.227.23 .235.24 .243.247\" +\n\t\".25 .255.26 .263.267.27 .275.28 .282.286.29 .294.298.3  .306.31 \" +\n\t\".314.318.32 .325.33 .333.337.34 .345.35 .353.357.36 .365.37 .373\" +\n\t\".376.38 .384.39 .392.396.4  .404.408.41 .416.42 .424.427.43 .435\" +\n\t\".44 .443.447.45 .455.46 .463.467.47 .475.48 .482.486.49 .494.498\" +\n\t\".5  .506.51 .514.518.52 .525.53 .533.537.54 .545.55 .553.557.56 \" +\n\t\".565.57 .573.576.58 .584.59 .592.596.6  .604.608.61 .616.62 .624\" +\n\t\".627.63 .635.64 .643.647.65 .655.66 .663.667.67 .675.68 .682.686\" +\n\t\".69 .694.698.7  .706.71 .714.718.72 .725.73 .733.737.74 .745.75 \" +\n\t\".753.757.76 .765.77 .773.776.78 .784.79 .792.796.8  .804.808.81 \" +\n\t\".816.82 .824.827.83 .835.84 .843.847.85 .855.86 .863.867.87 .875\" +\n\t\".88 .882.886.89 .894.898.9  .906.91 .914.918.92 .925.93 .933.937\" +\n\t\".94 .945.95 .953.957.96 .965.97 .973.976.98 .984.99 .992.9961   \"\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_font.go",
    "content": "package css_parser\n\nimport (\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\n// Specification: https://drafts.csswg.org/css-fonts/#font-prop\n// [ <font-style> || <font-variant-css2> || <font-weight> || <font-stretch-css3> ]? <font-size> [ / <line-height> ]? <font-family>\nfunc (p *parser) mangleFont(tokens []css_ast.Token) []css_ast.Token {\n\tvar result []css_ast.Token\n\n\t// Scan up to the font size\n\tpos := 0\n\tfor ; pos < len(tokens); pos++ {\n\t\ttoken := tokens[pos]\n\t\tif isFontSize(token) {\n\t\t\tbreak\n\t\t}\n\n\t\tswitch token.Kind {\n\t\tcase css_lexer.TIdent:\n\t\t\tswitch strings.ToLower(token.Text) {\n\t\t\tcase \"normal\":\n\t\t\t\t// \"All subproperties of the font property are first reset to their initial values\"\n\t\t\t\t// This implies that \"normal\" doesn't do anything. Also all of the optional values\n\t\t\t\t// contain \"normal\" as an option and they are unordered so it's impossible to say\n\t\t\t\t// what property \"normal\" corresponds to. Just drop these tokens to save space.\n\t\t\t\tcontinue\n\n\t\t\t// <font-style>\n\t\t\tcase \"italic\":\n\t\t\tcase \"oblique\":\n\t\t\t\tif pos+1 < len(tokens) && tokens[pos+1].IsAngle() {\n\t\t\t\t\tresult = append(result, token, tokens[pos+1])\n\t\t\t\t\tpos++\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t// <font-variant-css2>\n\t\t\tcase \"small-caps\":\n\n\t\t\t// <font-weight>\n\t\t\tcase \"bold\", \"bolder\", \"lighter\":\n\t\t\t\tresult = append(result, p.mangleFontWeight(token))\n\t\t\t\tcontinue\n\n\t\t\t// <font-stretch-css3>\n\t\t\tcase \"ultra-condensed\", \"extra-condensed\", \"condensed\", \"semi-condensed\",\n\t\t\t\t\"semi-expanded\", \"expanded\", \"extra-expanded\", \"ultra-expanded\":\n\n\t\t\tdefault:\n\t\t\t\t// All other tokens are unrecognized, so we bail if we hit one\n\t\t\t\treturn tokens\n\t\t\t}\n\t\t\tresult = append(result, token)\n\n\t\tcase css_lexer.TNumber:\n\t\t\t// \"Only values greater than or equal to 1, and less than or equal to\n\t\t\t// 1000, are valid, and all other values are invalid.\"\n\t\t\tif value, err := strconv.ParseFloat(token.Text, 64); err != nil || value < 1 || value > 1000 {\n\t\t\t\treturn tokens\n\t\t\t}\n\t\t\tresult = append(result, token)\n\n\t\tdefault:\n\t\t\t// All other tokens are unrecognized, so we bail if we hit one\n\t\t\treturn tokens\n\t\t}\n\t}\n\n\t// <font-size>\n\tif pos == len(tokens) {\n\t\treturn tokens\n\t}\n\tresult = append(result, tokens[pos])\n\tpos++\n\n\t// / <line-height>\n\tif pos < len(tokens) && tokens[pos].Kind == css_lexer.TDelimSlash {\n\t\tif pos+1 == len(tokens) {\n\t\t\treturn tokens\n\t\t}\n\t\tresult = append(result, tokens[pos], tokens[pos+1])\n\t\tpos += 2\n\n\t\t// Remove the whitespace around the \"/\" character\n\t\tif p.options.MinifyWhitespace {\n\t\t\tresult[len(result)-3].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\tresult[len(result)-2].Whitespace = 0\n\t\t\tresult[len(result)-1].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t}\n\t}\n\n\t// <font-family>\n\tif family, ok := p.mangleFontFamily(tokens[pos:]); ok {\n\t\treturn append(result, family...)\n\t}\n\treturn tokens\n}\n\nvar fontSizeKeywords = map[string]bool{\n\t// <absolute-size>: https://drafts.csswg.org/css-fonts/#valdef-font-size-absolute-size\n\t\"xx-small\":  true,\n\t\"x-small\":   true,\n\t\"small\":     true,\n\t\"medium\":    true,\n\t\"large\":     true,\n\t\"x-large\":   true,\n\t\"xx-large\":  true,\n\t\"xxx-large\": true,\n\n\t// <relative-size>: https://drafts.csswg.org/css-fonts/#valdef-font-size-relative-size\n\t\"larger\":  true,\n\t\"smaller\": true,\n}\n\n// Specification: https://drafts.csswg.org/css-fonts/#font-size-prop\nfunc isFontSize(token css_ast.Token) bool {\n\t// <length-percentage>\n\tif token.Kind == css_lexer.TDimension || token.Kind == css_lexer.TPercentage {\n\t\treturn true\n\t}\n\n\t// <absolute-size> or <relative-size>\n\tif token.Kind == css_lexer.TIdent {\n\t\t_, ok := fontSizeKeywords[strings.ToLower(token.Text)]\n\t\treturn ok\n\t}\n\n\treturn false\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_font_family.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\n// Specification: https://drafts.csswg.org/css-values-4/#common-keywords\nvar wideKeywords = map[string]bool{\n\t\"initial\": true,\n\t\"inherit\": true,\n\t\"unset\":   true,\n}\n\n// Specification: https://drafts.csswg.org/css-fonts/#generic-font-families\nvar genericFamilyNames = map[string]bool{\n\t\"serif\":         true,\n\t\"sans-serif\":    true,\n\t\"cursive\":       true,\n\t\"fantasy\":       true,\n\t\"monospace\":     true,\n\t\"system-ui\":     true,\n\t\"emoji\":         true,\n\t\"math\":          true,\n\t\"fangsong\":      true,\n\t\"ui-serif\":      true,\n\t\"ui-sans-serif\": true,\n\t\"ui-monospace\":  true,\n\t\"ui-rounded\":    true,\n}\n\n// Specification: https://drafts.csswg.org/css-fonts/#font-family-prop\nfunc (p *parser) mangleFontFamily(tokens []css_ast.Token) ([]css_ast.Token, bool) {\n\tresult, rest, ok := p.mangleFamilyNameOrGenericName(nil, tokens)\n\tif !ok {\n\t\treturn nil, false\n\t}\n\n\tfor len(rest) > 0 && rest[0].Kind == css_lexer.TComma {\n\t\tresult, rest, ok = p.mangleFamilyNameOrGenericName(append(result, rest[0]), rest[1:])\n\t\tif !ok {\n\t\t\treturn nil, false\n\t\t}\n\t}\n\n\tif len(rest) > 0 {\n\t\treturn nil, false\n\t}\n\n\treturn result, true\n}\n\nfunc (p *parser) mangleFamilyNameOrGenericName(result []css_ast.Token, tokens []css_ast.Token) ([]css_ast.Token, []css_ast.Token, bool) {\n\tif len(tokens) > 0 {\n\t\tt := tokens[0]\n\n\t\t// Handle <generic-family>\n\t\tif t.Kind == css_lexer.TIdent && genericFamilyNames[t.Text] {\n\t\t\treturn append(result, t), tokens[1:], true\n\t\t}\n\n\t\t// Handle <family-name>\n\t\tif t.Kind == css_lexer.TString {\n\t\t\t// \"If a sequence of identifiers is given as a <family-name>, the computed\n\t\t\t// value is the name converted to a string by joining all the identifiers\n\t\t\t// in the sequence by single spaces.\"\n\t\t\t//\n\t\t\t// More information: https://mathiasbynens.be/notes/unquoted-font-family\n\t\t\tnames := strings.Split(t.Text, \" \")\n\t\t\tfor _, name := range names {\n\t\t\t\tif !isValidCustomIdent(name, genericFamilyNames) {\n\t\t\t\t\treturn append(result, t), tokens[1:], true\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor i, name := range names {\n\t\t\t\tvar whitespace css_ast.WhitespaceFlags\n\t\t\t\tif i != 0 || !p.options.MinifyWhitespace {\n\t\t\t\t\twhitespace = css_ast.WhitespaceBefore\n\t\t\t\t}\n\t\t\t\tresult = append(result, css_ast.Token{\n\t\t\t\t\tKind:       css_lexer.TIdent,\n\t\t\t\t\tText:       name,\n\t\t\t\t\tWhitespace: whitespace,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn result, tokens[1:], true\n\t\t}\n\n\t\t// \"Font family names other than generic families must either be given\n\t\t// quoted as <string>s, or unquoted as a sequence of one or more\n\t\t// <custom-ident>.\"\n\t\tif t.Kind == css_lexer.TIdent {\n\t\t\tfor {\n\t\t\t\tif !isValidCustomIdent(t.Text, genericFamilyNames) {\n\t\t\t\t\treturn nil, nil, false\n\t\t\t\t}\n\t\t\t\tresult = append(result, t)\n\t\t\t\ttokens = tokens[1:]\n\t\t\t\tif len(tokens) == 0 || tokens[0].Kind != css_lexer.TIdent {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tt = tokens[0]\n\t\t\t}\n\t\t\treturn result, tokens, true\n\t\t}\n\t}\n\n\t// Anything other than the cases listed above causes us to bail\n\treturn nil, nil, false\n}\n\n// Specification: https://drafts.csswg.org/css-values-4/#custom-idents\nfunc isValidCustomIdent(text string, predefinedKeywords map[string]bool) bool {\n\tloweredText := strings.ToLower(text)\n\n\tif predefinedKeywords[loweredText] {\n\t\treturn false\n\t}\n\tif wideKeywords[loweredText] {\n\t\treturn false\n\t}\n\tif loweredText == \"default\" {\n\t\treturn false\n\t}\n\tif loweredText == \"\" {\n\t\treturn false\n\t}\n\n\t// validate if it contains characters which needs to be escaped\n\tif !css_lexer.WouldStartIdentifierWithoutEscapes(text) {\n\t\treturn false\n\t}\n\tfor _, c := range text {\n\t\tif !css_lexer.IsNameContinue(c) {\n\t\t\treturn false\n\t\t}\n\t}\n\n\treturn true\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_font_weight.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\nfunc (p *parser) mangleFontWeight(token css_ast.Token) css_ast.Token {\n\tif token.Kind != css_lexer.TIdent {\n\t\treturn token\n\t}\n\n\tswitch strings.ToLower(token.Text) {\n\tcase \"normal\":\n\t\ttoken.Text = \"400\"\n\t\ttoken.Kind = css_lexer.TNumber\n\tcase \"bold\":\n\t\ttoken.Text = \"700\"\n\t\ttoken.Kind = css_lexer.TNumber\n\t}\n\n\treturn token\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_decls_transform.go",
    "content": "package css_parser\n\nimport (\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\nfunc turnPercentIntoNumberIfShorter(t *css_ast.Token) {\n\tif t.Kind == css_lexer.TPercentage {\n\t\tif shifted, ok := shiftDot(t.PercentageValue(), -2); ok && len(shifted) < len(t.Text) {\n\t\t\tt.Kind = css_lexer.TNumber\n\t\t\tt.Text = shifted\n\t\t}\n\t}\n}\n\n// https://www.w3.org/TR/css-transforms-1/#two-d-transform-functions\n// https://drafts.csswg.org/css-transforms-2/#transform-functions\nfunc (p *parser) mangleTransforms(tokens []css_ast.Token) []css_ast.Token {\n\tfor i := range tokens {\n\t\tif token := &tokens[i]; token.Kind == css_lexer.TFunction {\n\t\t\tif args := *token.Children; css_ast.TokensAreCommaSeparated(args) {\n\t\t\t\tn := len(args)\n\n\t\t\t\tswitch strings.ToLower(token.Text) {\n\t\t\t\t////////////////////////////////////////////////////////////////////////////////\n\t\t\t\t// 2D transforms\n\n\t\t\t\tcase \"matrix\":\n\t\t\t\t\t// specifies a 2D transformation in the form of a transformation\n\t\t\t\t\t// matrix of the six values a, b, c, d, e, f.\n\t\t\t\t\tif n == 11 {\n\t\t\t\t\t\t// | a c 0 e |\n\t\t\t\t\t\t// | b d 0 f |\n\t\t\t\t\t\t// | 0 0 1 0 |\n\t\t\t\t\t\t// | 0 0 0 1 |\n\t\t\t\t\t\ta, b, c, d, e, f := args[0], args[2], args[4], args[6], args[8], args[10]\n\t\t\t\t\t\tif b.IsZero() && c.IsZero() && e.IsZero() && f.IsZero() {\n\t\t\t\t\t\t\t// | a 0 0 0 |\n\t\t\t\t\t\t\t// | 0 d 0 0 |\n\t\t\t\t\t\t\t// | 0 0 1 0 |\n\t\t\t\t\t\t\t// | 0 0 0 1 |\n\t\t\t\t\t\t\tif a.EqualIgnoringWhitespace(d) {\n\t\t\t\t\t\t\t\t// \"matrix(a, 0, 0, a, 0, 0)\" => \"scale(a)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scale\"\n\t\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t\t} else if d.IsOne() {\n\t\t\t\t\t\t\t\t// \"matrix(a, 0, 0, 1, 0, 0)\" => \"scaleX(a)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scaleX\"\n\t\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t\t} else if a.IsOne() {\n\t\t\t\t\t\t\t\t// \"matrix(1, 0, 0, d, 0, 0)\" => \"scaleY(d)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scaleY\"\n\t\t\t\t\t\t\t\t*token.Children = args[6:7]\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t// \"matrix(a, 0, 0, d, 0, 0)\" => \"scale(a, d)\"\n\t\t\t\t\t\t\t\ttoken.Text = \"scale\"\n\t\t\t\t\t\t\t\t*token.Children = append(args[:2], d)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Note: A \"matrix\" cannot be directly converted into a \"translate\"\n\t\t\t\t\t\t\t// because \"translate\" requires units while \"matrix\" requires no\n\t\t\t\t\t\t\t// units. I'm not sure exactly what the semantics are so I'm not\n\t\t\t\t\t\t\t// sure if you can just add \"px\" or not. Even if that did work,\n\t\t\t\t\t\t\t// you still couldn't substitute values containing \"var()\" since\n\t\t\t\t\t\t\t// units would still not be substituted in that case.\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translate\":\n\t\t\t\t\t// specifies a 2D translation by the vector [tx, ty], where tx is the\n\t\t\t\t\t// first translation-value parameter and ty is the optional second\n\t\t\t\t\t// translation-value parameter. If <ty> is not provided, ty has zero\n\t\t\t\t\t// as a value.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t} else if n == 3 {\n\t\t\t\t\t\ttx, ty := &args[0], &args[2]\n\t\t\t\t\t\ttx.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\tty.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\tif ty.IsZero() {\n\t\t\t\t\t\t\t// \"translate(tx, 0)\" => \"translate(tx)\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t} else if tx.IsZero() {\n\t\t\t\t\t\t\t// \"translate(0, ty)\" => \"translateY(ty)\"\n\t\t\t\t\t\t\ttoken.Text = \"translateY\"\n\t\t\t\t\t\t\t*token.Children = args[2:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translatex\":\n\t\t\t\t\t// specifies a translation by the given amount in the X direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\t// \"translateX(tx)\" => \"translate(tx)\"\n\t\t\t\t\t\ttoken.Text = \"translate\"\n\t\t\t\t\t\targs[0].TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translatey\":\n\t\t\t\t\t// specifies a translation by the given amount in the Y direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scale\":\n\t\t\t\t\t// specifies a 2D scale operation by the [sx,sy] scaling vector\n\t\t\t\t\t// described by the 2 parameters. If the second parameter is not\n\t\t\t\t\t// provided, it takes a value equal to the first. For example,\n\t\t\t\t\t// scale(1, 1) would leave an element unchanged, while scale(2, 2)\n\t\t\t\t\t// would cause it to appear twice as long in both the X and Y axes,\n\t\t\t\t\t// or four times its typical geometric size.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t} else if n == 3 {\n\t\t\t\t\t\tsx, sy := &args[0], &args[2]\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sx)\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sy)\n\t\t\t\t\t\tif sx.EqualIgnoringWhitespace(*sy) {\n\t\t\t\t\t\t\t// \"scale(s, s)\" => \"scale(s)\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t} else if sy.IsOne() {\n\t\t\t\t\t\t\t// \"scale(s, 1)\" => \"scaleX(s)\"\n\t\t\t\t\t\t\ttoken.Text = \"scaleX\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t} else if sx.IsOne() {\n\t\t\t\t\t\t\t// \"scale(1, s)\" => \"scaleY(s)\"\n\t\t\t\t\t\t\ttoken.Text = \"scaleY\"\n\t\t\t\t\t\t\t*token.Children = args[2:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scalex\":\n\t\t\t\t\t// specifies a 2D scale operation using the [sx,1] scaling vector,\n\t\t\t\t\t// where sx is given as the parameter.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scaley\":\n\t\t\t\t\t// specifies a 2D scale operation using the [1,sy] scaling vector,\n\t\t\t\t\t// where sy is given as the parameter.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotate\":\n\t\t\t\t\t// specifies a 2D rotation by the angle specified in the parameter\n\t\t\t\t\t// about the origin of the element, as defined by the\n\t\t\t\t\t// transform-origin property. For example, rotate(90deg) would\n\t\t\t\t\t// cause elements to appear rotated one-quarter of a turn in the\n\t\t\t\t\t// clockwise direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\t// Note: This is considered a 2D transform even though it's specified\n\t\t\t\t// in terms of a 3D transform because it doesn't trigger Safari's 3D\n\t\t\t\t// transform bugs.\n\t\t\t\tcase \"rotatez\":\n\t\t\t\t\t// same as rotate3d(0, 0, 1, <angle>), which is a 3d transform\n\t\t\t\t\t// equivalent to the 2d transform rotate(<angle>).\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\t// \"rotateZ(angle)\" => \"rotate(angle)\"\n\t\t\t\t\t\ttoken.Text = \"rotate\"\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"skew\":\n\t\t\t\t\t// specifies a 2D skew by [ax,ay] for X and Y. If the second\n\t\t\t\t\t// parameter is not provided, it has a zero value.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t} else if n == 3 {\n\t\t\t\t\t\tax, ay := &args[0], &args[2]\n\t\t\t\t\t\tax.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tay.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tif ay.IsZero() {\n\t\t\t\t\t\t\t// \"skew(ax, 0)\" => \"skew(ax)\"\n\t\t\t\t\t\t\t*token.Children = args[:1]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"skewx\":\n\t\t\t\t\t// specifies a 2D skew transformation along the X axis by the given\n\t\t\t\t\t// angle.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\t// \"skewX(ax)\" => \"skew(ax)\"\n\t\t\t\t\t\ttoken.Text = \"skew\"\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"skewy\":\n\t\t\t\t\t// specifies a 2D skew transformation along the Y axis by the given\n\t\t\t\t\t// angle.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\t\t////////////////////////////////////////////////////////////////////////////////\n\t\t\t\t\t// 3D transforms\n\n\t\t\t\t\t// Note: Safari has a bug where 3D transforms render differently than\n\t\t\t\t\t// other transforms. This means we should not minify a 3D transform\n\t\t\t\t\t// into a 2D transform or it will cause a rendering difference in\n\t\t\t\t\t// Safari.\n\n\t\t\t\tcase \"matrix3d\":\n\t\t\t\t\t// specifies a 3D transformation as a 4x4 homogeneous matrix of 16\n\t\t\t\t\t// values in column-major order.\n\t\t\t\t\tif n == 31 {\n\t\t\t\t\t\t// | m0 m4 m8  m12 |\n\t\t\t\t\t\t// | m1 m5 m9  m13 |\n\t\t\t\t\t\t// | m2 m6 m10 m14 |\n\t\t\t\t\t\t// | m3 m7 m11 m15 |\n\t\t\t\t\t\tmask := uint32(0)\n\t\t\t\t\t\tfor i := 0; i < 16; i++ {\n\t\t\t\t\t\t\tif arg := args[i*2]; arg.IsZero() {\n\t\t\t\t\t\t\t\tmask |= 1 << i\n\t\t\t\t\t\t\t} else if arg.IsOne() {\n\t\t\t\t\t\t\t\tmask |= (1 << 16) << i\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst onlyScale = 0b1000_0000_0000_0000_0111_1011_1101_1110\n\t\t\t\t\t\tif (mask & onlyScale) == onlyScale {\n\t\t\t\t\t\t\t// | m0 0  0   0 |\n\t\t\t\t\t\t\t// | 0  m5 0   0 |\n\t\t\t\t\t\t\t// | 0  0  m10 0 |\n\t\t\t\t\t\t\t// | 0  0  0   1 |\n\t\t\t\t\t\t\tsx, sy := args[0], args[10]\n\t\t\t\t\t\t\tif sx.IsOne() && sy.IsOne() {\n\t\t\t\t\t\t\t\ttoken.Text = \"scaleZ\"\n\t\t\t\t\t\t\t\t*token.Children = args[20:21]\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttoken.Text = \"scale3d\"\n\t\t\t\t\t\t\t\t*token.Children = append(append(args[0:2], args[10:12]...), args[20])\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Note: A \"matrix3d\" cannot be directly converted into a \"translate3d\"\n\t\t\t\t\t\t// because \"translate3d\" requires units while \"matrix3d\" requires no\n\t\t\t\t\t\t// units. I'm not sure exactly what the semantics are so I'm not\n\t\t\t\t\t\t// sure if you can just add \"px\" or not. Even if that did work,\n\t\t\t\t\t\t// you still couldn't substitute values containing \"var()\" since\n\t\t\t\t\t\t// units would still not be substituted in that case.\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translate3d\":\n\t\t\t\t\t// specifies a 3D translation by the vector [tx,ty,tz], with tx,\n\t\t\t\t\t// ty and tz being the first, second and third translation-value\n\t\t\t\t\t// parameters respectively.\n\t\t\t\t\tif n == 5 {\n\t\t\t\t\t\ttx, ty, tz := &args[0], &args[2], &args[4]\n\t\t\t\t\t\ttx.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\tty.TurnLengthOrPercentageIntoNumberIfZero()\n\t\t\t\t\t\ttz.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tif tx.IsZero() && ty.IsZero() {\n\t\t\t\t\t\t\t// \"translate3d(0, 0, tz)\" => \"translateZ(tz)\"\n\t\t\t\t\t\t\ttoken.Text = \"translateZ\"\n\t\t\t\t\t\t\t*token.Children = args[4:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"translatez\":\n\t\t\t\t\t// specifies a 3D translation by the vector [0,0,tz] with the given\n\t\t\t\t\t// amount in the Z direction.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scale3d\":\n\t\t\t\t\t// specifies a 3D scale operation by the [sx,sy,sz] scaling vector\n\t\t\t\t\t// described by the 3 parameters.\n\t\t\t\t\tif n == 5 {\n\t\t\t\t\t\tsx, sy, sz := &args[0], &args[2], &args[4]\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sx)\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sy)\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(sz)\n\t\t\t\t\t\tif sx.IsOne() && sy.IsOne() {\n\t\t\t\t\t\t\t// \"scale3d(1, 1, sz)\" => \"scaleZ(sz)\"\n\t\t\t\t\t\t\ttoken.Text = \"scaleZ\"\n\t\t\t\t\t\t\t*token.Children = args[4:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"scalez\":\n\t\t\t\t\t// specifies a 3D scale operation using the [1,1,sz] scaling vector,\n\t\t\t\t\t// where sz is given as the parameter.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\tturnPercentIntoNumberIfShorter(&args[0])\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotate3d\":\n\t\t\t\t\t// specifies a 3D rotation by the angle specified in last parameter\n\t\t\t\t\t// about the [x,y,z] direction vector described by the first three\n\t\t\t\t\t// parameters. A direction vector that cannot be normalized, such as\n\t\t\t\t\t// [0,0,0], will cause the rotation to not be applied.\n\t\t\t\t\tif n == 7 {\n\t\t\t\t\t\tx, y, z, angle := &args[0], &args[2], &args[4], &args[6]\n\t\t\t\t\t\tangle.TurnLengthIntoNumberIfZero()\n\t\t\t\t\t\tif x.IsOne() && y.IsZero() && z.IsZero() {\n\t\t\t\t\t\t\t// \"rotate3d(1, 0, 0, angle)\" => \"rotateX(angle)\"\n\t\t\t\t\t\t\ttoken.Text = \"rotateX\"\n\t\t\t\t\t\t\t*token.Children = args[6:]\n\t\t\t\t\t\t} else if x.IsZero() && y.IsOne() && z.IsZero() {\n\t\t\t\t\t\t\t// \"rotate3d(0, 1, 0, angle)\" => \"rotateY(angle)\"\n\t\t\t\t\t\t\ttoken.Text = \"rotateY\"\n\t\t\t\t\t\t\t*token.Children = args[6:]\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotatex\":\n\t\t\t\t\t// same as rotate3d(1, 0, 0, <angle>).\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"rotatey\":\n\t\t\t\t\t// same as rotate3d(0, 1, 0, <angle>).\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\n\t\t\t\tcase \"perspective\":\n\t\t\t\t\t// specifies a perspective projection matrix. This matrix scales\n\t\t\t\t\t// points in X and Y based on their Z value, scaling points with\n\t\t\t\t\t// positive Z values away from the origin, and those with negative Z\n\t\t\t\t\t// values towards the origin. Points on the z=0 plane are unchanged.\n\t\t\t\t\t// The parameter represents the distance of the z=0 plane from the\n\t\t\t\t\t// viewer.\n\t\t\t\t\tif n == 1 {\n\t\t\t\t\t\targs[0].TurnLengthIntoNumberIfZero()\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Trim whitespace at the ends\n\t\t\t\tif args := *token.Children; len(args) > 0 {\n\t\t\t\t\targs[0].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\t\targs[len(args)-1].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tokens\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_parser.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/compat\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\n// This is mostly a normal CSS parser with one exception: the addition of\n// support for parsing https://drafts.csswg.org/css-nesting-1/.\n\ntype parser struct {\n\tlog               logger.Log\n\tsource            logger.Source\n\ttokens            []css_lexer.Token\n\tlegalComments     []css_lexer.Comment\n\tstack             []css_lexer.T\n\timportRecords     []ast.ImportRecord\n\ttracker           logger.LineColumnTracker\n\tindex             int\n\tend               int\n\tlegalCommentIndex int\n\tprevError         logger.Loc\n\toptions           Options\n}\n\ntype Options struct {\n\tOriginalTargetEnv      string\n\tUnsupportedCSSFeatures compat.CSSFeature\n\tMinifySyntax           bool\n\tMinifyWhitespace       bool\n}\n\nfunc Parse(log logger.Log, source logger.Source, options Options) css_ast.AST {\n\tresult := css_lexer.Tokenize(log, source)\n\tp := parser{\n\t\tlog:           log,\n\t\tsource:        source,\n\t\ttracker:       logger.MakeLineColumnTracker(&source),\n\t\toptions:       options,\n\t\ttokens:        result.Tokens,\n\t\tlegalComments: result.LegalComments,\n\t\tprevError:     logger.Loc{Start: -1},\n\t}\n\tp.end = len(p.tokens)\n\trules := p.parseListOfRules(ruleContext{\n\t\tisTopLevel:     true,\n\t\tparseSelectors: true,\n\t})\n\tp.expect(css_lexer.TEndOfFile)\n\treturn css_ast.AST{\n\t\tRules:                rules,\n\t\tImportRecords:        p.importRecords,\n\t\tApproximateLineCount: result.ApproximateLineCount,\n\t\tSourceMapComment:     result.SourceMapComment,\n\t}\n}\n\nfunc (p *parser) advance() {\n\tif p.index < p.end {\n\t\tp.index++\n\t}\n}\n\nfunc (p *parser) at(index int) css_lexer.Token {\n\tif index < p.end {\n\t\treturn p.tokens[index]\n\t}\n\tif p.end < len(p.tokens) {\n\t\treturn css_lexer.Token{\n\t\t\tKind:  css_lexer.TEndOfFile,\n\t\t\tRange: logger.Range{Loc: p.tokens[p.end].Range.Loc},\n\t\t}\n\t}\n\treturn css_lexer.Token{\n\t\tKind:  css_lexer.TEndOfFile,\n\t\tRange: logger.Range{Loc: logger.Loc{Start: int32(len(p.source.Contents))}},\n\t}\n}\n\nfunc (p *parser) current() css_lexer.Token {\n\treturn p.at(p.index)\n}\n\nfunc (p *parser) next() css_lexer.Token {\n\treturn p.at(p.index + 1)\n}\n\nfunc (p *parser) raw() string {\n\tt := p.current()\n\treturn p.source.Contents[t.Range.Loc.Start:t.Range.End()]\n}\n\nfunc (p *parser) decoded() string {\n\treturn p.current().DecodedText(p.source.Contents)\n}\n\nfunc (p *parser) peek(kind css_lexer.T) bool {\n\treturn kind == p.current().Kind\n}\n\nfunc (p *parser) eat(kind css_lexer.T) bool {\n\tif p.peek(kind) {\n\t\tp.advance()\n\t\treturn true\n\t}\n\treturn false\n}\n\nfunc (p *parser) expect(kind css_lexer.T) bool {\n\tif p.eat(kind) {\n\t\treturn true\n\t}\n\tt := p.current()\n\tif (t.Flags & css_lexer.DidWarnAboutSingleLineComment) != 0 {\n\t\treturn false\n\t}\n\n\tvar text string\n\tvar suggestion string\n\n\texpected := kind.String()\n\tif strings.HasPrefix(expected, \"\\\"\") && strings.HasSuffix(expected, \"\\\"\") {\n\t\tsuggestion = expected[1 : len(expected)-1]\n\t}\n\n\tif (kind == css_lexer.TSemicolon || kind == css_lexer.TColon) && p.index > 0 && p.at(p.index-1).Kind == css_lexer.TWhitespace {\n\t\t// Have a nice error message for forgetting a trailing semicolon or colon\n\t\ttext = fmt.Sprintf(\"Expected %s\", expected)\n\t\tt = p.at(p.index - 1)\n\t} else {\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TEndOfFile, css_lexer.TWhitespace:\n\t\t\ttext = fmt.Sprintf(\"Expected %s but found %s\", expected, t.Kind.String())\n\t\t\tt.Range.Len = 0\n\t\tcase css_lexer.TBadURL, css_lexer.TBadString:\n\t\t\ttext = fmt.Sprintf(\"Expected %s but found %s\", expected, t.Kind.String())\n\t\tdefault:\n\t\t\ttext = fmt.Sprintf(\"Expected %s but found %q\", expected, p.raw())\n\t\t}\n\t}\n\n\tif t.Range.Loc.Start > p.prevError.Start {\n\t\tdata := p.tracker.MsgData(t.Range, text)\n\t\tdata.Location.Suggestion = suggestion\n\t\tp.log.AddMsg(logger.Msg{Kind: logger.Warning, Data: data})\n\t\tp.prevError = t.Range.Loc\n\t}\n\treturn false\n}\n\nfunc (p *parser) unexpected() {\n\tif t := p.current(); t.Range.Loc.Start > p.prevError.Start && (t.Flags&css_lexer.DidWarnAboutSingleLineComment) == 0 {\n\t\tvar text string\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TEndOfFile, css_lexer.TWhitespace:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %s\", t.Kind.String())\n\t\t\tt.Range.Len = 0\n\t\tcase css_lexer.TBadURL, css_lexer.TBadString:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %s\", t.Kind.String())\n\t\tdefault:\n\t\t\ttext = fmt.Sprintf(\"Unexpected %q\", p.raw())\n\t\t}\n\t\tp.log.Add(logger.Warning, &p.tracker, t.Range, text)\n\t\tp.prevError = t.Range.Loc\n\t}\n}\n\ntype ruleContext struct {\n\tisTopLevel     bool\n\tparseSelectors bool\n}\n\nfunc (p *parser) parseListOfRules(context ruleContext) []css_ast.Rule {\n\tatRuleContext := atRuleContext{}\n\tif context.isTopLevel {\n\t\tatRuleContext.charsetValidity = atRuleValid\n\t\tatRuleContext.importValidity = atRuleValid\n\t}\n\trules := []css_ast.Rule{}\n\tdidFindAtImport := false\n\nloop:\n\tfor {\n\t\t// If there are any legal comments immediately before the current token,\n\t\t// turn them all into comment rules and append them to the current rule list\n\t\tfor p.legalCommentIndex < len(p.legalComments) {\n\t\t\tcomment := p.legalComments[p.legalCommentIndex]\n\t\t\tif comment.TokenIndexAfter > uint32(p.index) {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tif comment.TokenIndexAfter == uint32(p.index) {\n\t\t\t\trules = append(rules, css_ast.Rule{Loc: comment.Loc, Data: &css_ast.RComment{Text: comment.Text}})\n\t\t\t}\n\t\t\tp.legalCommentIndex++\n\t\t}\n\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TEndOfFile:\n\t\t\tbreak loop\n\n\t\tcase css_lexer.TCloseBrace:\n\t\t\tif !context.isTopLevel {\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase css_lexer.TWhitespace:\n\t\t\tp.advance()\n\t\t\tcontinue\n\n\t\tcase css_lexer.TAtKeyword:\n\t\t\trule := p.parseAtRule(atRuleContext)\n\n\t\t\t// Disallow \"@charset\" and \"@import\" after other rules\n\t\t\tif context.isTopLevel {\n\t\t\t\tswitch r := rule.Data.(type) {\n\t\t\t\tcase *css_ast.RAtCharset:\n\t\t\t\t\t// This doesn't invalidate anything because it always comes first\n\n\t\t\t\tcase *css_ast.RAtImport:\n\t\t\t\t\tdidFindAtImport = true\n\t\t\t\t\tif atRuleContext.charsetValidity == atRuleValid {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\n\t\t\t\tcase *css_ast.RAtLayer:\n\t\t\t\t\tif atRuleContext.charsetValidity == atRuleValid {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\n\t\t\t\t\t// From the specification: \"Note: No @layer rules are allowed between\n\t\t\t\t\t// @import and @namespace rules. Any @layer rule that comes after an\n\t\t\t\t\t// @import or @namespace rule will cause any subsequent @import or\n\t\t\t\t\t// @namespace rules to be ignored.\"\n\t\t\t\t\tif atRuleContext.importValidity == atRuleValid && (r.Rules != nil || didFindAtImport) {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t\tatRuleContext.importValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\n\t\t\t\tdefault:\n\t\t\t\t\tif atRuleContext.importValidity == atRuleValid {\n\t\t\t\t\t\tatRuleContext.afterLoc = rule.Loc\n\t\t\t\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\t\t\t\tatRuleContext.importValidity = atRuleInvalidAfter\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\trules = append(rules, rule)\n\t\t\tcontinue\n\n\t\tcase css_lexer.TCDO, css_lexer.TCDC:\n\t\t\tif context.isTopLevel {\n\t\t\t\tp.advance()\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\tif atRuleContext.importValidity == atRuleValid {\n\t\t\tatRuleContext.afterLoc = p.current().Range.Loc\n\t\t\tatRuleContext.charsetValidity = atRuleInvalidAfter\n\t\t\tatRuleContext.importValidity = atRuleInvalidAfter\n\t\t}\n\n\t\tif context.parseSelectors {\n\t\t\trules = append(rules, p.parseSelectorRuleFrom(p.index, parseSelectorOpts{}))\n\t\t} else {\n\t\t\trules = append(rules, p.parseQualifiedRuleFrom(p.index, false /* isAlreadyInvalid */))\n\t\t}\n\t}\n\n\tif p.options.MinifySyntax {\n\t\trules = mangleRules(rules)\n\t}\n\treturn rules\n}\n\nfunc (p *parser) parseListOfDeclarations() (list []css_ast.Rule) {\n\tlist = []css_ast.Rule{}\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TWhitespace, css_lexer.TSemicolon:\n\t\t\tp.advance()\n\n\t\tcase css_lexer.TEndOfFile, css_lexer.TCloseBrace:\n\t\t\tlist = p.processDeclarations(list)\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tlist = mangleRules(list)\n\t\t\t}\n\t\t\treturn\n\n\t\tcase css_lexer.TAtKeyword:\n\t\t\tlist = append(list, p.parseAtRule(atRuleContext{\n\t\t\t\tisDeclarationList: true,\n\t\t\t\tallowNesting:      true,\n\t\t\t}))\n\n\t\tcase css_lexer.TDelimAmpersand:\n\t\t\t// Reference: https://drafts.csswg.org/css-nesting-1/\n\t\t\tlist = append(list, p.parseSelectorRuleFrom(p.index, parseSelectorOpts{allowNesting: true}))\n\n\t\tdefault:\n\t\t\tif p.shouldParseNestedSelector() {\n\t\t\t\tlist = append(list, p.parseSelectorRuleFrom(p.index, parseSelectorOpts{allowNesting: true}))\n\t\t\t} else {\n\t\t\t\tlist = append(list, p.parseDeclaration())\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (p *parser) shouldParseNestedSelector() bool {\n\tclone := *p\n\tclone.log = logger.Log{AddMsg: func(msg logger.Msg) {}}\n\t// Peek ahead to treat declarations that actually start a nested rule as selector rules.\n\tif _, ok := clone.parseSelectorList(parseSelectorOpts{allowNesting: true}); !ok {\n\t\treturn false\n\t}\n\treturn clone.peek(css_lexer.TOpenBrace)\n}\n\nfunc mangleRules(rules []css_ast.Rule) []css_ast.Rule {\n\ttype hashEntry struct {\n\t\tindices []uint32\n\t}\n\n\t// Remove empty rules\n\tn := 0\n\tfor _, rule := range rules {\n\t\tswitch r := rule.Data.(type) {\n\t\tcase *css_ast.RAtKeyframes:\n\t\t\t// Do not remove empty \"@keyframe foo {}\" rules. Even empty rules still\n\t\t\t// dispatch JavaScript animation events, so removing them changes\n\t\t\t// behavior: https://bugzilla.mozilla.org/show_bug.cgi?id=1004377.\n\n\t\tcase *css_ast.RAtLayer:\n\t\t\tif len(r.Rules) == 0 && len(r.Names) > 0 {\n\t\t\t\t// Do not remove empty \"@layer foo {}\" rules. The specification says:\n\t\t\t\t// \"Cascade layers are sorted by the order in which they first are\n\t\t\t\t// declared, with nested layers grouped within their parent layers\n\t\t\t\t// before any unlayered rules.\" So removing empty rules could change\n\t\t\t\t// the order in which they are first declared, and is therefore invalid.\n\t\t\t\t//\n\t\t\t\t// We can turn \"@layer foo {}\" into \"@layer foo;\" to be shorter. But\n\t\t\t\t// don't collapse anonymous \"@layer {}\" into \"@layer;\" because that is\n\t\t\t\t// a syntax error.\n\t\t\t\tr.Rules = nil\n\t\t\t} else if len(r.Rules) == 1 && len(r.Names) == 1 {\n\t\t\t\t// Only collapse layers if each layer has exactly one name\n\t\t\t\tif r2, ok := r.Rules[0].Data.(*css_ast.RAtLayer); ok && len(r2.Names) == 1 {\n\t\t\t\t\t// \"@layer a { @layer b {} }\" => \"@layer a.b;\"\n\t\t\t\t\t// \"@layer a { @layer b { c {} } }\" => \"@layer a.b { c {} }\"\n\t\t\t\t\tr.Names[0] = append(r.Names[0], r2.Names[0]...)\n\t\t\t\t\tr.Rules = r2.Rules\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase *css_ast.RKnownAt:\n\t\t\tif len(r.Rules) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\tcase *css_ast.RSelector:\n\t\t\tif len(r.Rules) == 0 {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\n\t\trules[n] = rule\n\t\tn++\n\t}\n\trules = rules[:n]\n\n\t// Remove duplicate rules, scanning from the back so we keep the last duplicate\n\tstart := n\n\tentries := make(map[uint32]hashEntry)\nskipRule:\n\tfor i := n - 1; i >= 0; i-- {\n\t\trule := rules[i]\n\n\t\t// Skip over preserved comments\n\t\tnext := i - 1\n\t\tfor next >= 0 {\n\t\t\tif _, ok := rules[next].Data.(*css_ast.RComment); !ok {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tnext--\n\t\t}\n\n\t\t// Merge adjacent selectors with the same content\n\t\t// \"a { color: red; } b { color: red; }\" => \"a, b { color: red; }\"\n\t\tif next >= 0 {\n\t\t\tif r, ok := rule.Data.(*css_ast.RSelector); ok {\n\t\t\t\tif prev, ok := rules[next].Data.(*css_ast.RSelector); ok && css_ast.RulesEqual(r.Rules, prev.Rules) &&\n\t\t\t\t\tisSafeSelectors(r.Selectors) && isSafeSelectors(prev.Selectors) {\n\t\t\t\tnextSelector:\n\t\t\t\t\tfor _, sel := range r.Selectors {\n\t\t\t\t\t\tfor _, prevSel := range prev.Selectors {\n\t\t\t\t\t\t\tif sel.Equal(prevSel) {\n\t\t\t\t\t\t\t\t// Don't add duplicate selectors more than once\n\t\t\t\t\t\t\t\tcontinue nextSelector\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tprev.Selectors = append(prev.Selectors, sel)\n\t\t\t\t\t}\n\t\t\t\t\tcontinue skipRule\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// For duplicate rules, omit all but the last copy\n\t\tif hash, ok := rule.Data.Hash(); ok {\n\t\t\tentry := entries[hash]\n\t\t\tfor _, index := range entry.indices {\n\t\t\t\tif rule.Data.Equal(rules[index].Data) {\n\t\t\t\t\tcontinue skipRule\n\t\t\t\t}\n\t\t\t}\n\t\t\tentry.indices = append(entry.indices, uint32(i))\n\t\t\tentries[hash] = entry\n\t\t}\n\n\t\tstart--\n\t\trules[start] = rule\n\t}\n\n\treturn rules[start:]\n}\n\n// Reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Element\nvar nonDeprecatedElementsSupportedByIE7 = map[string]bool{\n\t\"a\":          true,\n\t\"abbr\":       true,\n\t\"address\":    true,\n\t\"area\":       true,\n\t\"b\":          true,\n\t\"base\":       true,\n\t\"blockquote\": true,\n\t\"body\":       true,\n\t\"br\":         true,\n\t\"button\":     true,\n\t\"caption\":    true,\n\t\"cite\":       true,\n\t\"code\":       true,\n\t\"col\":        true,\n\t\"colgroup\":   true,\n\t\"dd\":         true,\n\t\"del\":        true,\n\t\"dfn\":        true,\n\t\"div\":        true,\n\t\"dl\":         true,\n\t\"dt\":         true,\n\t\"em\":         true,\n\t\"embed\":      true,\n\t\"fieldset\":   true,\n\t\"form\":       true,\n\t\"h1\":         true,\n\t\"h2\":         true,\n\t\"h3\":         true,\n\t\"h4\":         true,\n\t\"h5\":         true,\n\t\"h6\":         true,\n\t\"head\":       true,\n\t\"hr\":         true,\n\t\"html\":       true,\n\t\"i\":          true,\n\t\"iframe\":     true,\n\t\"img\":        true,\n\t\"input\":      true,\n\t\"ins\":        true,\n\t\"kbd\":        true,\n\t\"label\":      true,\n\t\"legend\":     true,\n\t\"li\":         true,\n\t\"link\":       true,\n\t\"map\":        true,\n\t\"menu\":       true,\n\t\"meta\":       true,\n\t\"noscript\":   true,\n\t\"object\":     true,\n\t\"ol\":         true,\n\t\"optgroup\":   true,\n\t\"option\":     true,\n\t\"p\":          true,\n\t\"param\":      true,\n\t\"pre\":        true,\n\t\"q\":          true,\n\t\"ruby\":       true,\n\t\"s\":          true,\n\t\"samp\":       true,\n\t\"script\":     true,\n\t\"select\":     true,\n\t\"small\":      true,\n\t\"span\":       true,\n\t\"strong\":     true,\n\t\"style\":      true,\n\t\"sub\":        true,\n\t\"sup\":        true,\n\t\"table\":      true,\n\t\"tbody\":      true,\n\t\"td\":         true,\n\t\"textarea\":   true,\n\t\"tfoot\":      true,\n\t\"th\":         true,\n\t\"thead\":      true,\n\t\"title\":      true,\n\t\"tr\":         true,\n\t\"u\":          true,\n\t\"ul\":         true,\n\t\"var\":        true,\n}\n\n// This only returns true if all of these selectors are considered \"safe\" which\n// means that they are very likely to work in any browser a user might reasonably\n// be using. We do NOT want to merge adjacent qualified rules with the same body\n// if any of the selectors are unsafe, since then browsers which don't support\n// that particular feature would ignore the entire merged qualified rule:\n//\n//   Input:\n//     a { color: red }\n//     b { color: red }\n//     input::-moz-placeholder { color: red }\n//\n//   Valid output:\n//     a, b { color: red }\n//     input::-moz-placeholder { color: red }\n//\n//   Invalid output:\n//     a, b, input::-moz-placeholder { color: red }\n//\n// This considers IE 7 and above to be a browser that a user could possibly use.\n// Versions of IE less than 6 are not considered.\nfunc isSafeSelectors(complexSelectors []css_ast.ComplexSelector) bool {\n\tfor _, complex := range complexSelectors {\n\t\tfor _, compound := range complex.Selectors {\n\t\t\tif compound.NestingSelector != css_ast.NestingSelectorNone {\n\t\t\t\t// Bail because this is an extension: https://drafts.csswg.org/css-nesting-1/\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif compound.Combinator != \"\" {\n\t\t\t\t// \"Before Internet Explorer 10, the combinator only works in standards mode\"\n\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\tif compound.TypeSelector != nil {\n\t\t\t\tif compound.TypeSelector.NamespacePrefix != nil {\n\t\t\t\t\t// Bail if we hit a namespace, which doesn't work in IE before version 9\n\t\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Type_selectors\n\t\t\t\t\treturn false\n\t\t\t\t}\n\n\t\t\t\tif compound.TypeSelector.Name.Kind == css_lexer.TIdent && !nonDeprecatedElementsSupportedByIE7[compound.TypeSelector.Name.Text] {\n\t\t\t\t\t// Bail if this element is either deprecated or not supported in IE 7\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor _, ss := range compound.SubclassSelectors {\n\t\t\t\tswitch s := ss.(type) {\n\t\t\t\tcase *css_ast.SSAttribute:\n\t\t\t\t\tif s.MatcherModifier != 0 {\n\t\t\t\t\t\t// Bail if we hit a case modifier, which doesn't work in IE at all\n\t\t\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors\n\t\t\t\t\t\treturn false\n\t\t\t\t\t}\n\n\t\t\t\tcase *css_ast.SSPseudoClass:\n\t\t\t\t\t// Bail if this pseudo class doesn't match a hard-coded list that's\n\t\t\t\t\t// known to work everywhere. For example, \":focus\" doesn't work in IE 7.\n\t\t\t\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes\n\t\t\t\t\tif s.Args == nil && !s.IsElement {\n\t\t\t\t\t\tswitch s.Name {\n\t\t\t\t\t\tcase \"active\", \"first-child\", \"hover\", \"link\", \"visited\":\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn true\n}\n\nfunc (p *parser) parseURLOrString() (string, logger.Range, bool) {\n\tt := p.current()\n\tswitch t.Kind {\n\tcase css_lexer.TString:\n\t\ttext := p.decoded()\n\t\tp.advance()\n\t\treturn text, t.Range, true\n\n\tcase css_lexer.TURL:\n\t\ttext := p.decoded()\n\t\tp.advance()\n\t\treturn text, t.Range, true\n\n\tcase css_lexer.TFunction:\n\t\tif p.decoded() == \"url\" {\n\t\t\tp.advance()\n\t\t\tt = p.current()\n\t\t\ttext := p.decoded()\n\t\t\tif p.expect(css_lexer.TString) && p.expect(css_lexer.TCloseParen) {\n\t\t\t\treturn text, t.Range, true\n\t\t\t}\n\t\t}\n\t}\n\n\treturn \"\", logger.Range{}, false\n}\n\nfunc (p *parser) expectURLOrString() (url string, r logger.Range, ok bool) {\n\turl, r, ok = p.parseURLOrString()\n\tif !ok {\n\t\tp.expect(css_lexer.TURL)\n\t}\n\treturn\n}\n\ntype atRuleKind uint8\n\nconst (\n\tatRuleUnknown atRuleKind = iota\n\tatRuleDeclarations\n\tatRuleInheritContext\n\tatRuleQualifiedOrEmpty\n\tatRuleEmpty\n)\n\nvar specialAtRules = map[string]atRuleKind{\n\t\"font-face\": atRuleDeclarations,\n\t\"page\":      atRuleDeclarations,\n\n\t// These go inside \"@page\": https://www.w3.org/TR/css-page-3/#syntax-page-selector\n\t\"bottom-center\":       atRuleDeclarations,\n\t\"bottom-left-corner\":  atRuleDeclarations,\n\t\"bottom-left\":         atRuleDeclarations,\n\t\"bottom-right-corner\": atRuleDeclarations,\n\t\"bottom-right\":        atRuleDeclarations,\n\t\"left-bottom\":         atRuleDeclarations,\n\t\"left-middle\":         atRuleDeclarations,\n\t\"left-top\":            atRuleDeclarations,\n\t\"right-bottom\":        atRuleDeclarations,\n\t\"right-middle\":        atRuleDeclarations,\n\t\"right-top\":           atRuleDeclarations,\n\t\"top-center\":          atRuleDeclarations,\n\t\"top-left-corner\":     atRuleDeclarations,\n\t\"top-left\":            atRuleDeclarations,\n\t\"top-right-corner\":    atRuleDeclarations,\n\t\"top-right\":           atRuleDeclarations,\n\n\t// These properties are very deprecated and appear to only be useful for\n\t// mobile versions of internet explorer (which may no longer exist?), but\n\t// they are used by the https://ant.design/ design system so we recognize\n\t// them to avoid the warning.\n\t//\n\t//   Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@viewport\n\t//   Discussion: https://github.com/w3c/csswg-drafts/issues/4766\n\t//\n\t\"viewport\":     atRuleDeclarations,\n\t\"-ms-viewport\": atRuleDeclarations,\n\n\t// This feature has been removed from the web because it's actively harmful.\n\t// However, there is one exception where \"@-moz-document url-prefix() {\" is\n\t// accepted by Firefox to basically be an \"if Firefox\" conditional rule.\n\t//\n\t//   Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@document\n\t//   Discussion: https://bugzilla.mozilla.org/show_bug.cgi?id=1035091\n\t//\n\t\"document\":      atRuleInheritContext,\n\t\"-moz-document\": atRuleInheritContext,\n\n\t// This is a new feature that changes how the CSS rule cascade works. It can\n\t// end in either a \"{}\" block or a \";\" rule terminator so we need this special\n\t// case to support both.\n\t//\n\t//   Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@layer\n\t//   Motivation: https://developer.chrome.com/blog/cascade-layers/\n\t//\n\t\"layer\": atRuleQualifiedOrEmpty,\n\n\t\"media\":    atRuleInheritContext,\n\t\"scope\":    atRuleInheritContext,\n\t\"supports\": atRuleInheritContext,\n\n\t// Reference: https://github.com/w3c/csswg-drafts/issues?q=is%3Aissue+label%3Acss-contain-3+\n\t\"container\": atRuleInheritContext,\n\n\t// Reference: https://drafts.csswg.org/css-transitions-2/#defining-before-change-style-the-starting-style-rule\n\t\"starting-style\": atRuleInheritContext,\n\n\t// Reference: https://drafts.csswg.org/css-nesting-1/\n\t\"nest\": atRuleDeclarations,\n}\n\ntype atRuleValidity uint8\n\nconst (\n\tatRuleInvalid atRuleValidity = iota\n\tatRuleValid\n\tatRuleInvalidAfter\n)\n\ntype atRuleContext struct {\n\tafterLoc          logger.Loc\n\tcharsetValidity   atRuleValidity\n\timportValidity    atRuleValidity\n\tisDeclarationList bool\n\tallowNesting      bool\n}\n\nfunc (p *parser) parseAtRule(context atRuleContext) css_ast.Rule {\n\t// Parse the name\n\tatToken := p.decoded()\n\tatRange := p.current().Range\n\tkind := specialAtRules[atToken]\n\tp.advance()\n\n\t// Parse the prelude\n\tpreludeStart := p.index\nabortRuleParser:\n\tswitch atToken {\n\tcase \"charset\":\n\t\tswitch context.charsetValidity {\n\t\tcase atRuleInvalid:\n\t\t\tp.log.Add(logger.Warning, &p.tracker, atRange, \"\\\"@charset\\\" must be the first rule in the file\")\n\n\t\tcase atRuleInvalidAfter:\n\t\t\tp.log.AddWithNotes(logger.Warning, &p.tracker, atRange, \"\\\"@charset\\\" must be the first rule in the file\",\n\t\t\t\t[]logger.MsgData{p.tracker.MsgData(logger.Range{Loc: context.afterLoc},\n\t\t\t\t\t\"This rule cannot come before a \\\"@charset\\\" rule\")})\n\n\t\tcase atRuleValid:\n\t\t\tkind = atRuleEmpty\n\t\t\tp.expect(css_lexer.TWhitespace)\n\t\t\tif p.peek(css_lexer.TString) {\n\t\t\t\tencoding := p.decoded()\n\t\t\t\tif !strings.EqualFold(encoding, \"UTF-8\") {\n\t\t\t\t\tp.log.Add(logger.Warning, &p.tracker, p.current().Range,\n\t\t\t\t\t\tfmt.Sprintf(\"\\\"UTF-8\\\" will be used instead of unsupported charset %q\", encoding))\n\t\t\t\t}\n\t\t\t\tp.advance()\n\t\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtCharset{Encoding: encoding}}\n\t\t\t}\n\t\t\tp.expect(css_lexer.TString)\n\t\t}\n\n\tcase \"import\":\n\t\tswitch context.importValidity {\n\t\tcase atRuleInvalid:\n\t\t\tp.log.Add(logger.Warning, &p.tracker, atRange, \"\\\"@import\\\" is only valid at the top level\")\n\n\t\tcase atRuleInvalidAfter:\n\t\t\tp.log.AddWithNotes(logger.Warning, &p.tracker, atRange, \"All \\\"@import\\\" rules must come first\",\n\t\t\t\t[]logger.MsgData{p.tracker.MsgData(logger.Range{Loc: context.afterLoc},\n\t\t\t\t\t\"This rule cannot come before an \\\"@import\\\" rule\")})\n\n\t\tcase atRuleValid:\n\t\t\tkind = atRuleEmpty\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\tif path, r, ok := p.expectURLOrString(); ok {\n\t\t\t\timportConditionsStart := p.index\n\t\t\t\tfor {\n\t\t\t\t\tif kind := p.current().Kind; kind == css_lexer.TSemicolon || kind == css_lexer.TOpenBrace ||\n\t\t\t\t\t\tkind == css_lexer.TCloseBrace || kind == css_lexer.TEndOfFile {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tp.parseComponentValue()\n\t\t\t\t}\n\t\t\t\tif p.current().Kind == css_lexer.TOpenBrace {\n\t\t\t\t\tbreak // Avoid parsing an invalid \"@import\" rule\n\t\t\t\t}\n\t\t\t\timportConditions := p.convertTokens(p.tokens[importConditionsStart:p.index])\n\t\t\t\tkind := ast.ImportAt\n\n\t\t\t\t// Insert or remove whitespace before the first token\n\t\t\t\tif len(importConditions) > 0 {\n\t\t\t\t\tkind = ast.ImportAtConditional\n\t\t\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\t\t\timportConditions[0].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\t\t} else {\n\t\t\t\t\t\timportConditions[0].Whitespace |= css_ast.WhitespaceBefore\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\t\timportRecordIndex := uint32(len(p.importRecords))\n\t\t\t\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\t\t\t\tKind:  kind,\n\t\t\t\t\tPath:  logger.Path{Text: path},\n\t\t\t\t\tRange: r,\n\t\t\t\t})\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtImport{\n\t\t\t\t\tImportRecordIndex: importRecordIndex,\n\t\t\t\t\tImportConditions:  importConditions,\n\t\t\t\t}}\n\t\t\t}\n\t\t}\n\n\tcase \"keyframes\", \"-webkit-keyframes\", \"-moz-keyframes\", \"-ms-keyframes\", \"-o-keyframes\":\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tvar name string\n\n\t\tif p.peek(css_lexer.TIdent) {\n\t\t\tname = p.decoded()\n\t\t\tp.advance()\n\t\t} else if !p.expect(css_lexer.TIdent) && !p.eat(css_lexer.TString) && !p.peek(css_lexer.TOpenBrace) {\n\t\t\t// Consider string names a syntax error even though they are allowed by\n\t\t\t// the specification and they work in Firefox because they do not work in\n\t\t\t// Chrome or Safari.\n\t\t\tbreak\n\t\t}\n\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tblockStart := p.index\n\n\t\tif p.expect(css_lexer.TOpenBrace) {\n\t\t\tvar blocks []css_ast.KeyframeBlock\n\n\t\tbadSyntax:\n\t\t\tfor {\n\t\t\t\tswitch p.current().Kind {\n\t\t\t\tcase css_lexer.TWhitespace:\n\t\t\t\t\tp.advance()\n\t\t\t\t\tcontinue\n\n\t\t\t\tcase css_lexer.TCloseBrace:\n\t\t\t\t\tp.advance()\n\t\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtKeyframes{\n\t\t\t\t\t\tAtToken: atToken,\n\t\t\t\t\t\tName:    name,\n\t\t\t\t\t\tBlocks:  blocks,\n\t\t\t\t\t}}\n\n\t\t\t\tcase css_lexer.TEndOfFile:\n\t\t\t\t\tbreak badSyntax\n\n\t\t\t\tcase css_lexer.TOpenBrace:\n\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\tbreak badSyntax\n\n\t\t\t\tdefault:\n\t\t\t\t\tvar selectors []string\n\n\t\t\t\tselectors:\n\t\t\t\t\tfor {\n\t\t\t\t\t\tt := p.current()\n\t\t\t\t\t\tswitch t.Kind {\n\t\t\t\t\t\tcase css_lexer.TWhitespace:\n\t\t\t\t\t\t\tp.advance()\n\t\t\t\t\t\t\tcontinue\n\n\t\t\t\t\t\tcase css_lexer.TOpenBrace:\n\t\t\t\t\t\t\tp.advance()\n\t\t\t\t\t\t\tbreak selectors\n\n\t\t\t\t\t\tcase css_lexer.TCloseBrace, css_lexer.TEndOfFile:\n\t\t\t\t\t\t\tp.expect(css_lexer.TOpenBrace)\n\t\t\t\t\t\t\tbreak badSyntax\n\n\t\t\t\t\t\tcase css_lexer.TIdent, css_lexer.TPercentage:\n\t\t\t\t\t\t\ttext := p.decoded()\n\t\t\t\t\t\t\tif t.Kind == css_lexer.TIdent {\n\t\t\t\t\t\t\t\tif text == \"from\" {\n\t\t\t\t\t\t\t\t\tif p.options.MinifySyntax {\n\t\t\t\t\t\t\t\t\t\ttext = \"0%\" // \"0%\" is equivalent to but shorter than \"from\"\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if text != \"to\" {\n\t\t\t\t\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if p.options.MinifySyntax && text == \"100%\" {\n\t\t\t\t\t\t\t\ttext = \"to\" // \"to\" is equivalent to but shorter than \"100%\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tselectors = append(selectors, text)\n\t\t\t\t\t\t\tp.advance()\n\n\t\t\t\t\t\t\t// Keyframe selectors are comma-separated\n\t\t\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\t\t\tif p.eat(css_lexer.TComma) {\n\t\t\t\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\t\t\t\tif k := p.current().Kind; k != css_lexer.TIdent && k != css_lexer.TPercentage {\n\t\t\t\t\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\t\t\t\t\tbreak badSyntax\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if k := p.current().Kind; k != css_lexer.TOpenBrace && k != css_lexer.TCloseBrace && k != css_lexer.TEndOfFile {\n\t\t\t\t\t\t\t\tp.expect(css_lexer.TComma)\n\t\t\t\t\t\t\t\tbreak badSyntax\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tp.expect(css_lexer.TPercentage)\n\t\t\t\t\t\t\tbreak badSyntax\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\trules := p.parseListOfDeclarations()\n\t\t\t\t\tp.expect(css_lexer.TCloseBrace)\n\n\t\t\t\t\t// \"@keyframes { from {} to { color: red } }\" => \"@keyframes { to { color: red } }\"\n\t\t\t\t\tif !p.options.MinifySyntax || len(rules) > 0 {\n\t\t\t\t\t\tblocks = append(blocks, css_ast.KeyframeBlock{\n\t\t\t\t\t\t\tSelectors: selectors,\n\t\t\t\t\t\t\tRules:     rules,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Otherwise, finish parsing the body and return an unknown rule\n\t\t\tfor !p.peek(css_lexer.TCloseBrace) && !p.peek(css_lexer.TEndOfFile) {\n\t\t\t\tp.parseComponentValue()\n\t\t\t}\n\t\t\tp.expect(css_lexer.TCloseBrace)\n\t\t\tprelude := p.convertTokens(p.tokens[preludeStart:blockStart])\n\t\t\tblock, _ := p.convertTokensHelper(p.tokens[blockStart:p.index], css_lexer.TEndOfFile, convertTokensOpts{allowImports: true})\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude, Block: block}}\n\t\t}\n\n\tcase \"nest\":\n\t\t// Reference: https://drafts.csswg.org/css-nesting-1/\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif kind := p.current().Kind; kind != css_lexer.TSemicolon && kind != css_lexer.TOpenBrace &&\n\t\t\tkind != css_lexer.TCloseBrace && kind != css_lexer.TEndOfFile {\n\t\t\treturn p.parseSelectorRuleFrom(preludeStart-1, parseSelectorOpts{atNestRange: atRange, allowNesting: context.allowNesting})\n\t\t}\n\n\tcase \"layer\":\n\t\t// Reference: https://developer.mozilla.org/en-US/docs/Web/CSS/@layer\n\n\t\t// Read the layer name list\n\t\tvar names [][]string\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.peek(css_lexer.TIdent) {\n\t\t\tfor {\n\t\t\t\tident, ok := p.expectValidLayerNameIdent()\n\t\t\t\tif !ok {\n\t\t\t\t\tbreak abortRuleParser\n\t\t\t\t}\n\t\t\t\tname := []string{ident}\n\t\t\t\tfor {\n\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\tif !p.eat(css_lexer.TDelimDot) {\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\t\tident, ok := p.expectValidLayerNameIdent()\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\tbreak abortRuleParser\n\t\t\t\t\t}\n\t\t\t\t\tname = append(name, ident)\n\t\t\t\t}\n\t\t\t\tnames = append(names, name)\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t\tif !p.eat(css_lexer.TComma) {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t\t}\n\t\t}\n\n\t\t// Read the optional block\n\t\tif len(names) <= 1 && p.eat(css_lexer.TOpenBrace) {\n\t\t\trules := p.parseListOfRules(ruleContext{\n\t\t\t\tparseSelectors: true,\n\t\t\t})\n\t\t\tp.expect(css_lexer.TCloseBrace)\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtLayer{Names: names, Rules: rules}}\n\t\t}\n\n\t\t// Handle lack of a block\n\t\tif len(names) >= 1 && p.eat(css_lexer.TSemicolon) {\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RAtLayer{Names: names}}\n\t\t}\n\n\t\t// Otherwise there's some kind of syntax error\n\t\tif kind := p.current().Kind; kind == css_lexer.TOpenBrace || kind == css_lexer.TCloseBrace || kind == css_lexer.TEndOfFile {\n\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t} else {\n\t\t\tp.unexpected()\n\t\t}\n\n\tdefault:\n\t\tif kind == atRuleUnknown && atToken == \"namespace\" {\n\t\t\t// CSS namespaces are a weird feature that appears to only really be\n\t\t\t// useful for styling XML. And the world has moved on from XHTML to\n\t\t\t// HTML5 so pretty much no one uses CSS namespaces anymore. They are\n\t\t\t// also complicated to support in a bundler because CSS namespaces are\n\t\t\t// file-scoped, which means:\n\t\t\t//\n\t\t\t// * Default namespaces can be different in different files, in which\n\t\t\t//   case some default namespaces would have to be converted to prefixed\n\t\t\t//   namespaces to avoid collisions.\n\t\t\t//\n\t\t\t// * Prefixed namespaces from different files can use the same name, in\n\t\t\t//   which case some prefixed namespaces would need to be renamed to\n\t\t\t//   avoid collisions.\n\t\t\t//\n\t\t\t// Instead of implementing all of that for an extremely obscure feature,\n\t\t\t// CSS namespaces are just explicitly not supported.\n\t\t\tp.log.Add(logger.Warning, &p.tracker, atRange, \"\\\"@namespace\\\" rules are not supported\")\n\t\t}\n\t}\n\n\t// Parse an unknown prelude\nprelude:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TOpenBrace, css_lexer.TEndOfFile:\n\t\t\tbreak prelude\n\n\t\tcase css_lexer.TSemicolon, css_lexer.TCloseBrace:\n\t\t\tprelude := p.convertTokens(p.tokens[preludeStart:p.index])\n\n\t\t\tswitch kind {\n\t\t\tcase atRuleQualifiedOrEmpty:\n\t\t\t\t// Parse a known at rule below\n\t\t\t\tbreak prelude\n\n\t\t\tcase atRuleEmpty, atRuleUnknown:\n\t\t\t\t// Parse an unknown at rule\n\t\t\t\tp.expect(css_lexer.TSemicolon)\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude}}\n\n\t\t\tdefault:\n\t\t\t\t// Report an error for rules that should have blocks\n\t\t\t\tp.expect(css_lexer.TOpenBrace)\n\t\t\t\tp.eat(css_lexer.TSemicolon)\n\t\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude}}\n\t\t\t}\n\n\t\tdefault:\n\t\t\tp.parseComponentValue()\n\t\t}\n\t}\n\tprelude := p.convertTokens(p.tokens[preludeStart:p.index])\n\tblockStart := p.index\n\n\tswitch kind {\n\tcase atRuleEmpty:\n\t\t// Report an error for rules that shouldn't have blocks\n\t\tp.expect(css_lexer.TSemicolon)\n\t\tp.parseBlock(css_lexer.TOpenBrace, css_lexer.TCloseBrace)\n\t\tblock := p.convertTokens(p.tokens[blockStart:p.index])\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude, Block: block}}\n\n\tcase atRuleDeclarations:\n\t\t// Parse known rules whose blocks always consist of declarations\n\t\tp.expect(css_lexer.TOpenBrace)\n\t\trules := p.parseListOfDeclarations()\n\t\tp.expect(css_lexer.TCloseBrace)\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude, Rules: rules}}\n\n\tcase atRuleInheritContext:\n\t\t// Parse known rules whose blocks consist of whatever the current context is\n\t\tp.expect(css_lexer.TOpenBrace)\n\t\tvar rules []css_ast.Rule\n\t\tif context.isDeclarationList {\n\t\t\trules = p.parseListOfDeclarations()\n\t\t} else {\n\t\t\trules = p.parseListOfRules(ruleContext{\n\t\t\t\tparseSelectors: true,\n\t\t\t})\n\t\t}\n\t\tp.expect(css_lexer.TCloseBrace)\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude, Rules: rules}}\n\n\tcase atRuleQualifiedOrEmpty:\n\t\tif p.eat(css_lexer.TOpenBrace) {\n\t\t\trules := p.parseListOfRules(ruleContext{\n\t\t\t\tparseSelectors: true,\n\t\t\t})\n\t\t\tp.expect(css_lexer.TCloseBrace)\n\t\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude, Rules: rules}}\n\t\t}\n\t\tp.expect(css_lexer.TSemicolon)\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RKnownAt{AtToken: atToken, Prelude: prelude}}\n\n\tdefault:\n\t\t// Otherwise, parse an unknown rule\n\t\tp.parseBlock(css_lexer.TOpenBrace, css_lexer.TCloseBrace)\n\t\tblock, _ := p.convertTokensHelper(p.tokens[blockStart:p.index], css_lexer.TEndOfFile, convertTokensOpts{allowImports: true})\n\t\treturn css_ast.Rule{Loc: atRange.Loc, Data: &css_ast.RUnknownAt{AtToken: atToken, Prelude: prelude, Block: block}}\n\t}\n}\n\nfunc (p *parser) expectValidLayerNameIdent() (string, bool) {\n\tr := p.current().Range\n\ttext := p.decoded()\n\tif !p.expect(css_lexer.TIdent) {\n\t\treturn \"\", false\n\t}\n\tswitch text {\n\tcase \"initial\", \"inherit\", \"unset\":\n\t\tp.log.Add(logger.Warning, &p.tracker, r, fmt.Sprintf(\"%q cannot be used as a layer name\", text))\n\t\tp.prevError = r.Loc\n\t\treturn \"\", false\n\t}\n\treturn text, true\n}\n\nfunc (p *parser) convertTokens(tokens []css_lexer.Token) []css_ast.Token {\n\tresult, _ := p.convertTokensHelper(tokens, css_lexer.TEndOfFile, convertTokensOpts{})\n\treturn result\n}\n\ntype convertTokensOpts struct {\n\tallowImports         bool\n\tverbatimWhitespace   bool\n\tisInsideCalcFunction bool\n}\n\nfunc (p *parser) convertTokensHelper(tokens []css_lexer.Token, close css_lexer.T, opts convertTokensOpts) ([]css_ast.Token, []css_lexer.Token) {\n\tvar result []css_ast.Token\n\tvar nextWhitespace css_ast.WhitespaceFlags\n\n\t// Enable verbatim whitespace mode when the first two non-whitespace tokens\n\t// are a CSS variable name followed by a colon. This is because it could be\n\t// a form of CSS variable usage, and removing whitespace could potentially\n\t// break this usage. For example, the following CSS is ignored by Chrome if\n\t// the whitespace isn't preserved:\n\t//\n\t//   @supports (--foo: ) {\n\t//     html { background: green; }\n\t//   }\n\t//\n\t// Strangely whitespace removal doesn't cause the declaration to be ignored\n\t// in Firefox or Safari, so there's definitely a browser bug somewhere.\n\tif !opts.verbatimWhitespace {\n\t\tfor i, t := range tokens {\n\t\t\tif t.Kind == css_lexer.TWhitespace {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif t.Kind == css_lexer.TIdent && strings.HasPrefix(t.DecodedText(p.source.Contents), \"--\") {\n\t\t\t\tfor _, t := range tokens[i+1:] {\n\t\t\t\t\tif t.Kind == css_lexer.TWhitespace {\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t\tif t.Kind == css_lexer.TColon {\n\t\t\t\t\t\topts.verbatimWhitespace = true\n\t\t\t\t\t}\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak\n\t\t}\n\t}\n\nloop:\n\tfor len(tokens) > 0 {\n\t\tt := tokens[0]\n\t\ttokens = tokens[1:]\n\t\tif t.Kind == close {\n\t\t\tbreak loop\n\t\t}\n\t\ttoken := css_ast.Token{\n\t\t\tKind:       t.Kind,\n\t\t\tText:       t.DecodedText(p.source.Contents),\n\t\t\tWhitespace: nextWhitespace,\n\t\t}\n\t\tnextWhitespace = 0\n\n\t\t// Warn about invalid \"+\" and \"-\" operators that break the containing \"calc()\"\n\t\tif opts.isInsideCalcFunction && t.Kind.IsNumeric() && len(result) > 0 && result[len(result)-1].Kind.IsNumeric() &&\n\t\t\t(strings.HasPrefix(token.Text, \"+\") || strings.HasPrefix(token.Text, \"-\")) {\n\t\t\t// \"calc(1+2)\" and \"calc(1-2)\" are invalid\n\t\t\tp.log.Add(logger.Warning, &p.tracker, logger.Range{Loc: t.Range.Loc, Len: 1},\n\t\t\t\tfmt.Sprintf(\"The %q operator only works if there is whitespace on both sides\", token.Text[:1]))\n\t\t}\n\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TWhitespace:\n\t\t\tif last := len(result) - 1; last >= 0 {\n\t\t\t\tresult[last].Whitespace |= css_ast.WhitespaceAfter\n\t\t\t}\n\t\t\tnextWhitespace = css_ast.WhitespaceBefore\n\t\t\tcontinue\n\n\t\tcase css_lexer.TDelimPlus, css_lexer.TDelimMinus:\n\t\t\t// Warn about invalid \"+\" and \"-\" operators that break the containing \"calc()\"\n\t\t\tif opts.isInsideCalcFunction && len(tokens) > 0 {\n\t\t\t\tif len(result) == 0 || result[len(result)-1].Kind == css_lexer.TComma {\n\t\t\t\t\t// \"calc(-(1 + 2))\" is invalid\n\t\t\t\t\tp.log.Add(logger.Warning, &p.tracker, t.Range,\n\t\t\t\t\t\tfmt.Sprintf(\"%q can only be used as an infix operator, not a prefix operator\", token.Text))\n\t\t\t\t} else if token.Whitespace != css_ast.WhitespaceBefore || tokens[0].Kind != css_lexer.TWhitespace {\n\t\t\t\t\t// \"calc(1- 2)\" and \"calc(1 -(2))\" are invalid\n\t\t\t\t\tp.log.Add(logger.Warning, &p.tracker, t.Range,\n\t\t\t\t\t\tfmt.Sprintf(\"The %q operator only works if there is whitespace on both sides\", token.Text))\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TNumber:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tif text, ok := mangleNumber(token.Text); ok {\n\t\t\t\t\ttoken.Text = text\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TPercentage:\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tif text, ok := mangleNumber(token.PercentageValue()); ok {\n\t\t\t\t\ttoken.Text = text + \"%\"\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TDimension:\n\t\t\ttoken.UnitOffset = t.UnitOffset\n\n\t\t\tif p.options.MinifySyntax {\n\t\t\t\tif text, ok := mangleNumber(token.DimensionValue()); ok {\n\t\t\t\t\ttoken.Text = text + token.DimensionUnit()\n\t\t\t\t\ttoken.UnitOffset = uint16(len(text))\n\t\t\t\t}\n\n\t\t\t\tif value, unit, ok := mangleDimension(token.DimensionValue(), token.DimensionUnit()); ok {\n\t\t\t\t\ttoken.Text = value + unit\n\t\t\t\t\ttoken.UnitOffset = uint16(len(value))\n\t\t\t\t}\n\t\t\t}\n\n\t\tcase css_lexer.TURL:\n\t\t\ttoken.ImportRecordIndex = uint32(len(p.importRecords))\n\t\t\tvar flags ast.ImportRecordFlags\n\t\t\tif !opts.allowImports {\n\t\t\t\tflags |= ast.IsUnused\n\t\t\t}\n\t\t\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\t\t\tKind:  ast.ImportURL,\n\t\t\t\tPath:  logger.Path{Text: token.Text},\n\t\t\t\tRange: t.Range,\n\t\t\t\tFlags: flags,\n\t\t\t})\n\t\t\ttoken.Text = \"\"\n\n\t\tcase css_lexer.TFunction:\n\t\t\tvar nested []css_ast.Token\n\t\t\toriginal := tokens\n\t\t\tnestedOpts := opts\n\t\t\tif token.Text == \"var\" {\n\t\t\t\t// CSS variables require verbatim whitespace for correctness\n\t\t\t\tnestedOpts.verbatimWhitespace = true\n\t\t\t}\n\t\t\tif token.Text == \"calc\" {\n\t\t\t\tnestedOpts.isInsideCalcFunction = true\n\t\t\t}\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseParen, nestedOpts)\n\t\t\ttoken.Children = &nested\n\n\t\t\t// Apply \"calc\" simplification rules when minifying\n\t\t\tif p.options.MinifySyntax && token.Text == \"calc\" {\n\t\t\t\ttoken = p.tryToReduceCalcExpression(token)\n\t\t\t}\n\n\t\t\t// Treat a URL function call with a string just like a URL token\n\t\t\tif token.Text == \"url\" && len(nested) == 1 && nested[0].Kind == css_lexer.TString {\n\t\t\t\ttoken.Kind = css_lexer.TURL\n\t\t\t\ttoken.Text = \"\"\n\t\t\t\ttoken.Children = nil\n\t\t\t\ttoken.ImportRecordIndex = uint32(len(p.importRecords))\n\t\t\t\tvar flags ast.ImportRecordFlags\n\t\t\t\tif !opts.allowImports {\n\t\t\t\t\tflags |= ast.IsUnused\n\t\t\t\t}\n\t\t\t\tp.importRecords = append(p.importRecords, ast.ImportRecord{\n\t\t\t\t\tKind:  ast.ImportURL,\n\t\t\t\t\tPath:  logger.Path{Text: nested[0].Text},\n\t\t\t\t\tRange: original[0].Range,\n\t\t\t\t\tFlags: flags,\n\t\t\t\t})\n\t\t\t}\n\n\t\tcase css_lexer.TOpenParen:\n\t\t\tvar nested []css_ast.Token\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseParen, opts)\n\t\t\ttoken.Children = &nested\n\n\t\tcase css_lexer.TOpenBrace:\n\t\t\tvar nested []css_ast.Token\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseBrace, opts)\n\n\t\t\t// Pretty-printing: insert leading and trailing whitespace when not minifying\n\t\t\tif !opts.verbatimWhitespace && !p.options.MinifyWhitespace && len(nested) > 0 {\n\t\t\t\tnested[0].Whitespace |= css_ast.WhitespaceBefore\n\t\t\t\tnested[len(nested)-1].Whitespace |= css_ast.WhitespaceAfter\n\t\t\t}\n\n\t\t\ttoken.Children = &nested\n\n\t\tcase css_lexer.TOpenBracket:\n\t\t\tvar nested []css_ast.Token\n\t\t\tnested, tokens = p.convertTokensHelper(tokens, css_lexer.TCloseBracket, opts)\n\t\t\ttoken.Children = &nested\n\t\t}\n\n\t\tresult = append(result, token)\n\t}\n\n\tif !opts.verbatimWhitespace {\n\t\tfor i := range result {\n\t\t\ttoken := &result[i]\n\n\t\t\t// Always remove leading and trailing whitespace\n\t\t\tif i == 0 {\n\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t}\n\t\t\tif i+1 == len(result) {\n\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t}\n\n\t\t\tswitch token.Kind {\n\t\t\tcase css_lexer.TComma:\n\t\t\t\t// Assume that whitespace can always be removed before a comma\n\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\tif i > 0 {\n\t\t\t\t\tresult[i-1].Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\t}\n\n\t\t\t\t// Assume whitespace can always be added after a comma\n\t\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\t\ttoken.Whitespace &= ^css_ast.WhitespaceAfter\n\t\t\t\t\tif i+1 < len(result) {\n\t\t\t\t\t\tresult[i+1].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\ttoken.Whitespace |= css_ast.WhitespaceAfter\n\t\t\t\t\tif i+1 < len(result) {\n\t\t\t\t\t\tresult[i+1].Whitespace |= css_ast.WhitespaceBefore\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Insert an explicit whitespace token if we're in verbatim mode and all\n\t// tokens were whitespace. In this case there is no token to attach the\n\t// whitespace before/after flags so this is the only way to represent this.\n\t// This is the only case where this function generates an explicit whitespace\n\t// token. It represents whitespace as flags in all other cases.\n\tif opts.verbatimWhitespace && len(result) == 0 && nextWhitespace == css_ast.WhitespaceBefore {\n\t\tresult = append(result, css_ast.Token{\n\t\t\tKind: css_lexer.TWhitespace,\n\t\t})\n\t}\n\n\treturn result, tokens\n}\n\nfunc shiftDot(text string, dotOffset int) (string, bool) {\n\t// This doesn't handle numbers with exponents\n\tif strings.ContainsAny(text, \"eE\") {\n\t\treturn \"\", false\n\t}\n\n\t// Handle a leading sign\n\tsign := \"\"\n\tif len(text) > 0 && (text[0] == '-' || text[0] == '+') {\n\t\tsign = text[:1]\n\t\ttext = text[1:]\n\t}\n\n\t// Remove the dot\n\tdot := strings.IndexByte(text, '.')\n\tif dot == -1 {\n\t\tdot = len(text)\n\t} else {\n\t\ttext = text[:dot] + text[dot+1:]\n\t}\n\n\t// Move the dot\n\tdot += dotOffset\n\n\t// Remove any leading zeros before the dot\n\tfor len(text) > 0 && dot > 0 && text[0] == '0' {\n\t\ttext = text[1:]\n\t\tdot--\n\t}\n\n\t// Remove any trailing zeros after the dot\n\tfor len(text) > 0 && len(text) > dot && text[len(text)-1] == '0' {\n\t\ttext = text[:len(text)-1]\n\t}\n\n\t// Does this number have no fractional component?\n\tif dot >= len(text) {\n\t\ttrailingZeros := strings.Repeat(\"0\", dot-len(text))\n\t\treturn fmt.Sprintf(\"%s%s%s\", sign, text, trailingZeros), true\n\t}\n\n\t// Potentially add leading zeros\n\tif dot < 0 {\n\t\ttext = strings.Repeat(\"0\", -dot) + text\n\t\tdot = 0\n\t}\n\n\t// Insert the dot again\n\treturn fmt.Sprintf(\"%s%s.%s\", sign, text[:dot], text[dot:]), true\n}\n\nfunc mangleDimension(value string, unit string) (string, string, bool) {\n\tconst msLen = 2\n\tconst sLen = 1\n\n\t// Mangle times: https://developer.mozilla.org/en-US/docs/Web/CSS/time\n\tif strings.EqualFold(unit, \"ms\") {\n\t\tif shifted, ok := shiftDot(value, -3); ok && len(shifted)+sLen < len(value)+msLen {\n\t\t\t// Convert \"ms\" to \"s\" if shorter\n\t\t\treturn shifted, \"s\", true\n\t\t}\n\t}\n\tif strings.EqualFold(unit, \"s\") {\n\t\tif shifted, ok := shiftDot(value, 3); ok && len(shifted)+msLen < len(value)+sLen {\n\t\t\t// Convert \"s\" to \"ms\" if shorter\n\t\t\treturn shifted, \"ms\", true\n\t\t}\n\t}\n\n\treturn \"\", \"\", false\n}\n\nfunc mangleNumber(t string) (string, bool) {\n\toriginal := t\n\n\tif dot := strings.IndexByte(t, '.'); dot != -1 {\n\t\t// Remove trailing zeros\n\t\tfor len(t) > 0 && t[len(t)-1] == '0' {\n\t\t\tt = t[:len(t)-1]\n\t\t}\n\n\t\t// Remove the decimal point if it's unnecessary\n\t\tif dot+1 == len(t) {\n\t\t\tt = t[:dot]\n\t\t\tif t == \"\" || t == \"+\" || t == \"-\" {\n\t\t\t\tt += \"0\"\n\t\t\t}\n\t\t} else {\n\t\t\t// Remove a leading zero\n\t\t\tif len(t) >= 3 && t[0] == '0' && t[1] == '.' && t[2] >= '0' && t[2] <= '9' {\n\t\t\t\tt = t[1:]\n\t\t\t} else if len(t) >= 4 && (t[0] == '+' || t[0] == '-') && t[1] == '0' && t[2] == '.' && t[3] >= '0' && t[3] <= '9' {\n\t\t\t\tt = t[0:1] + t[2:]\n\t\t\t}\n\t\t}\n\t}\n\n\treturn t, t != original\n}\n\nfunc (p *parser) parseSelectorRuleFrom(preludeStart int, opts parseSelectorOpts) css_ast.Rule {\n\t// Try parsing the prelude as a selector list\n\tif list, ok := p.parseSelectorList(opts); ok {\n\t\tselector := css_ast.RSelector{\n\t\t\tSelectors: list,\n\t\t\tHasAtNest: opts.atNestRange.Len != 0,\n\t\t}\n\t\tif p.expect(css_lexer.TOpenBrace) {\n\t\t\tselector.Rules = p.parseListOfDeclarations()\n\t\t\tp.expect(css_lexer.TCloseBrace)\n\n\t\t\t// Minify \"@nest\" when possible\n\t\t\tif p.options.MinifySyntax && selector.HasAtNest {\n\t\t\t\tallHaveNestPrefix := true\n\t\t\t\tfor _, complex := range selector.Selectors {\n\t\t\t\t\tif len(complex.Selectors) == 0 || complex.Selectors[0].NestingSelector != css_ast.NestingSelectorPrefix {\n\t\t\t\t\t\tallHaveNestPrefix = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif allHaveNestPrefix {\n\t\t\t\t\tselector.HasAtNest = false\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn css_ast.Rule{Loc: p.tokens[preludeStart].Range.Loc, Data: &selector}\n\t\t}\n\t}\n\n\t// Otherwise, parse a generic qualified rule\n\treturn p.parseQualifiedRuleFrom(preludeStart, true /* isAlreadyInvalid */)\n}\n\nfunc (p *parser) parseQualifiedRuleFrom(preludeStart int, isAlreadyInvalid bool) css_ast.Rule {\n\tpreludeLoc := p.tokens[preludeStart].Range.Loc\n\nloop:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TOpenBrace, css_lexer.TEndOfFile:\n\t\t\tbreak loop\n\n\t\tdefault:\n\t\t\tp.parseComponentValue()\n\t\t}\n\t}\n\n\tqualified := css_ast.RQualified{\n\t\tPrelude: p.convertTokens(p.tokens[preludeStart:p.index]),\n\t}\n\n\tif p.eat(css_lexer.TOpenBrace) {\n\t\tqualified.Rules = p.parseListOfDeclarations()\n\t\tp.expect(css_lexer.TCloseBrace)\n\t} else if !isAlreadyInvalid {\n\t\tp.expect(css_lexer.TOpenBrace)\n\t}\n\n\treturn css_ast.Rule{Loc: preludeLoc, Data: &qualified}\n}\n\nfunc (p *parser) parseDeclaration() css_ast.Rule {\n\t// Parse the key\n\tkeyStart := p.index\n\tkeyLoc := p.tokens[keyStart].Range.Loc\n\tok := false\n\tif p.expect(css_lexer.TIdent) {\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.expect(css_lexer.TColon) {\n\t\t\tok = true\n\t\t}\n\t}\n\n\t// Parse the value\n\tvalueStart := p.index\nstop:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TEndOfFile, css_lexer.TSemicolon, css_lexer.TCloseBrace:\n\t\t\tbreak stop\n\n\t\tdefault:\n\t\t\tp.parseComponentValue()\n\t\t}\n\t}\n\n\t// Stop now if this is not a valid declaration\n\tif !ok {\n\t\treturn css_ast.Rule{Loc: keyLoc, Data: &css_ast.RBadDeclaration{\n\t\t\tTokens: p.convertTokens(p.tokens[keyStart:p.index]),\n\t\t}}\n\t}\n\n\tkeyToken := p.tokens[keyStart]\n\tkeyText := keyToken.DecodedText(p.source.Contents)\n\tvalue := p.tokens[valueStart:p.index]\n\tverbatimWhitespace := strings.HasPrefix(keyText, \"--\")\n\n\t// Remove trailing \"!important\"\n\timportant := false\n\ti := len(value) - 1\n\tif i >= 0 && value[i].Kind == css_lexer.TWhitespace {\n\t\ti--\n\t}\n\tif i >= 0 && value[i].Kind == css_lexer.TIdent && strings.EqualFold(value[i].DecodedText(p.source.Contents), \"important\") {\n\t\ti--\n\t\tif i >= 0 && value[i].Kind == css_lexer.TWhitespace {\n\t\t\ti--\n\t\t}\n\t\tif i >= 0 && value[i].Kind == css_lexer.TDelimExclamation {\n\t\t\tvalue = value[:i]\n\t\t\timportant = true\n\t\t}\n\t}\n\n\tresult, _ := p.convertTokensHelper(value, css_lexer.TEndOfFile, convertTokensOpts{\n\t\tallowImports: true,\n\n\t\t// CSS variables require verbatim whitespace for correctness\n\t\tverbatimWhitespace: verbatimWhitespace,\n\t})\n\n\t// Insert or remove whitespace before the first token\n\tif !verbatimWhitespace && len(result) > 0 {\n\t\tif p.options.MinifyWhitespace {\n\t\t\tresult[0].Whitespace &= ^css_ast.WhitespaceBefore\n\t\t} else {\n\t\t\tresult[0].Whitespace |= css_ast.WhitespaceBefore\n\t\t}\n\t}\n\n\tkey := css_ast.KnownDeclarations[keyText]\n\n\t// Attempt to point out trivial typos\n\tif key == css_ast.DUnknown {\n\t\tif corrected, ok := css_ast.MaybeCorrectDeclarationTypo(keyText); ok {\n\t\t\tdata := p.tracker.MsgData(keyToken.Range, fmt.Sprintf(\"%q is not a known CSS property\", keyText))\n\t\t\tdata.Location.Suggestion = corrected\n\t\t\tp.log.AddMsg(logger.Msg{Kind: logger.Warning, Data: data,\n\t\t\t\tNotes: []logger.MsgData{{Text: fmt.Sprintf(\"Did you mean %q instead?\", corrected)}}})\n\t\t}\n\t}\n\n\treturn css_ast.Rule{Loc: keyLoc, Data: &css_ast.RDeclaration{\n\t\tKey:       key,\n\t\tKeyText:   keyText,\n\t\tKeyRange:  keyToken.Range,\n\t\tValue:     result,\n\t\tImportant: important,\n\t}}\n}\n\nfunc (p *parser) parseComponentValue() {\n\tswitch p.current().Kind {\n\tcase css_lexer.TFunction:\n\t\tp.parseBlock(css_lexer.TFunction, css_lexer.TCloseParen)\n\n\tcase css_lexer.TOpenParen:\n\t\tp.parseBlock(css_lexer.TOpenParen, css_lexer.TCloseParen)\n\n\tcase css_lexer.TOpenBrace:\n\t\tp.parseBlock(css_lexer.TOpenBrace, css_lexer.TCloseBrace)\n\n\tcase css_lexer.TOpenBracket:\n\t\tp.parseBlock(css_lexer.TOpenBracket, css_lexer.TCloseBracket)\n\n\tcase css_lexer.TEndOfFile:\n\t\tp.unexpected()\n\n\tdefault:\n\t\tp.advance()\n\t}\n}\n\nfunc (p *parser) parseBlock(open css_lexer.T, close css_lexer.T) {\n\tif p.expect(open) {\n\t\tfor !p.eat(close) {\n\t\t\tif p.peek(css_lexer.TEndOfFile) {\n\t\t\t\tp.expect(close)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tp.parseComponentValue()\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_parser_selector.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/compat\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\nfunc (p *parser) parseSelectorList(opts parseSelectorOpts) (list []css_ast.ComplexSelector, ok bool) {\n\t// Parse the first selector\n\tfirstRange := p.current().Range\n\tsel, good, firstHasNestPrefix := p.parseComplexSelector(opts)\n\tif !good {\n\t\treturn\n\t}\n\tlist = append(list, sel)\n\n\t// Parse the remaining selectors\n\tfor {\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif !p.eat(css_lexer.TComma) {\n\t\t\tbreak\n\t\t}\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tloc := p.current().Range.Loc\n\t\tsel, good, hasNestPrefix := p.parseComplexSelector(opts)\n\t\tif !good {\n\t\t\treturn\n\t\t}\n\t\tlist = append(list, sel)\n\n\t\t// Validate nest prefix consistency\n\t\tif firstHasNestPrefix && !hasNestPrefix && opts.atNestRange.Len == 0 {\n\t\t\tdata := p.tracker.MsgData(logger.Range{Loc: loc}, \"Every selector in a nested style rule must start with \\\"&\\\"\")\n\t\t\tdata.Location.Suggestion = \"&\"\n\t\t\tp.log.AddMsg(logger.Msg{\n\t\t\t\tKind:  logger.Warning,\n\t\t\t\tData:  data,\n\t\t\t\tNotes: []logger.MsgData{p.tracker.MsgData(firstRange, \"This is a nested style rule because of the \\\"&\\\" here:\")},\n\t\t\t})\n\t\t}\n\t}\n\n\tok = true\n\treturn\n}\n\ntype parseSelectorOpts struct {\n\tatNestRange  logger.Range\n\tallowNesting bool\n}\n\nfunc (p *parser) parseComplexSelector(opts parseSelectorOpts) (result css_ast.ComplexSelector, ok bool, hasNestPrefix bool) {\n\t// Parent\n\tloc := p.current().Range.Loc\n\tsel, good := p.parseCompoundSelector(opts)\n\tif !good {\n\t\treturn\n\t}\n\thasNestPrefix = sel.NestingSelector == css_ast.NestingSelectorPrefix\n\tisNestContaining := sel.NestingSelector != css_ast.NestingSelectorNone\n\tresult.Selectors = append(result.Selectors, sel)\n\n\tfor {\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.peek(css_lexer.TEndOfFile) || p.peek(css_lexer.TComma) || p.peek(css_lexer.TOpenBrace) {\n\t\t\tbreak\n\t\t}\n\n\t\t// Optional combinator\n\t\tcombinator := p.parseCombinator()\n\t\tif combinator != \"\" {\n\t\t\tp.eat(css_lexer.TWhitespace)\n\t\t}\n\n\t\t// Child\n\t\tsel, good := p.parseCompoundSelector(opts)\n\t\tif !good {\n\t\t\treturn\n\t\t}\n\t\tsel.Combinator = combinator\n\t\tresult.Selectors = append(result.Selectors, sel)\n\t\tif sel.NestingSelector != css_ast.NestingSelectorNone {\n\t\t\tisNestContaining = true\n\t\t}\n\t}\n\n\t// Validate nest selector consistency\n\tif opts.atNestRange.Len != 0 && !isNestContaining {\n\t\tp.log.AddWithNotes(logger.Warning, &p.tracker, logger.Range{Loc: loc}, \"Every selector in a nested style rule must contain \\\"&\\\"\",\n\t\t\t[]logger.MsgData{p.tracker.MsgData(opts.atNestRange, \"This is a nested style rule because of the \\\"@nest\\\" here:\")})\n\t}\n\n\tok = true\n\treturn\n}\n\nfunc (p *parser) nameToken() css_ast.NameToken {\n\treturn css_ast.NameToken{\n\t\tKind: p.current().Kind,\n\t\tText: p.decoded(),\n\t}\n}\n\nfunc (p *parser) maybeWarnAboutNesting(r logger.Range, opts parseSelectorOpts) {\n\tif !opts.allowNesting {\n\t\tp.log.Add(logger.Warning, &p.tracker, r, \"CSS nesting syntax cannot be used outside of a style rule\")\n\t} else if p.options.UnsupportedCSSFeatures.Has(compat.Nesting) {\n\t\ttext := \"CSS nesting syntax is not supported in the configured target environment\"\n\t\tif p.options.OriginalTargetEnv != \"\" {\n\t\t\ttext = fmt.Sprintf(\"%s (%s)\", text, p.options.OriginalTargetEnv)\n\t\t}\n\t\tp.log.Add(logger.Warning, &p.tracker, r, text)\n\t}\n}\n\nfunc (p *parser) parseCompoundSelector(opts parseSelectorOpts) (sel css_ast.CompoundSelector, ok bool) {\n\t// This is an extension: https://drafts.csswg.org/css-nesting-1/\n\tr := p.current().Range\n\tif p.eat(css_lexer.TDelimAmpersand) {\n\t\tsel.NestingSelector = css_ast.NestingSelectorPrefix\n\t\tp.maybeWarnAboutNesting(r, opts)\n\t}\n\n\t// Parse the type selector\n\tswitch p.current().Kind {\n\tcase css_lexer.TDelimBar, css_lexer.TIdent, css_lexer.TDelimAsterisk:\n\t\tnsName := css_ast.NamespacedName{}\n\t\tif !p.peek(css_lexer.TDelimBar) {\n\t\t\tnsName.Name = p.nameToken()\n\t\t\tp.advance()\n\t\t} else {\n\t\t\t// Hack: Create an empty \"identifier\" to represent this\n\t\t\tnsName.Name.Kind = css_lexer.TIdent\n\t\t}\n\t\tif p.eat(css_lexer.TDelimBar) {\n\t\t\tif !p.peek(css_lexer.TIdent) && !p.peek(css_lexer.TDelimAsterisk) {\n\t\t\t\tp.expect(css_lexer.TIdent)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tprefix := nsName.Name\n\t\t\tnsName.NamespacePrefix = &prefix\n\t\t\tnsName.Name = p.nameToken()\n\t\t\tp.advance()\n\t\t}\n\t\tsel.TypeSelector = &nsName\n\t}\n\n\t// Parse the subclass selectors\nsubclassSelectors:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.THash:\n\t\t\tif (p.current().Flags & css_lexer.IsID) == 0 {\n\t\t\t\tbreak subclassSelectors\n\t\t\t}\n\t\t\tname := p.decoded()\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, &css_ast.SSHash{Name: name})\n\t\t\tp.advance()\n\n\t\tcase css_lexer.TDelimDot:\n\t\t\tp.advance()\n\t\t\tname := p.decoded()\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, &css_ast.SSClass{Name: name})\n\t\t\tp.expect(css_lexer.TIdent)\n\n\t\tcase css_lexer.TOpenBracket:\n\t\t\tp.advance()\n\t\t\tattr, good := p.parseAttributeSelector()\n\t\t\tif !good {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, &attr)\n\n\t\tcase css_lexer.TColon:\n\t\t\tif p.next().Kind == css_lexer.TColon {\n\t\t\t\t// Special-case the start of the pseudo-element selector section\n\t\t\t\tfor p.current().Kind == css_lexer.TColon {\n\t\t\t\t\tisElement := p.next().Kind == css_lexer.TColon\n\t\t\t\t\tif isElement {\n\t\t\t\t\t\tp.advance()\n\t\t\t\t\t}\n\t\t\t\t\tpseudo := p.parsePseudoClassSelector()\n\n\t\t\t\t\t// https://www.w3.org/TR/selectors-4/#single-colon-pseudos\n\t\t\t\t\t// The four Level 2 pseudo-elements (::before, ::after, ::first-line,\n\t\t\t\t\t// and ::first-letter) may, for legacy reasons, be represented using\n\t\t\t\t\t// the <pseudo-class-selector> grammar, with only a single \":\"\n\t\t\t\t\t// character at their start.\n\t\t\t\t\tif p.options.MinifySyntax && isElement && len(pseudo.Args) == 0 {\n\t\t\t\t\t\tswitch pseudo.Name {\n\t\t\t\t\t\tcase \"before\", \"after\", \"first-line\", \"first-letter\":\n\t\t\t\t\t\t\tisElement = false\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tpseudo.IsElement = isElement\n\t\t\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, &pseudo)\n\t\t\t\t}\n\t\t\t\tbreak subclassSelectors\n\t\t\t}\n\t\t\tpseudo := p.parsePseudoClassSelector()\n\t\t\tsel.SubclassSelectors = append(sel.SubclassSelectors, &pseudo)\n\n\t\tcase css_lexer.TDelimAmpersand:\n\t\t\t// This is an extension: https://drafts.csswg.org/css-nesting-1/\n\t\t\tr := p.current().Range\n\t\t\tp.advance()\n\t\t\tif sel.NestingSelector == css_ast.NestingSelectorNone {\n\t\t\t\tsel.NestingSelector = css_ast.NestingSelectorPresentButNotPrefix\n\t\t\t\tp.maybeWarnAboutNesting(r, opts)\n\t\t\t}\n\n\t\tdefault:\n\t\t\tbreak subclassSelectors\n\t\t}\n\t}\n\n\t// The compound selector must be non-empty\n\tif sel.NestingSelector == css_ast.NestingSelectorNone && sel.TypeSelector == nil && len(sel.SubclassSelectors) == 0 {\n\t\tp.unexpected()\n\t\treturn\n\t}\n\n\tok = true\n\treturn\n}\n\nfunc (p *parser) parseAttributeSelector() (attr css_ast.SSAttribute, ok bool) {\n\t// Parse the namespaced name\n\tswitch p.current().Kind {\n\tcase css_lexer.TDelimBar, css_lexer.TDelimAsterisk:\n\t\t// \"[|x]\"\n\t\t// \"[*|x]\"\n\t\tif p.peek(css_lexer.TDelimAsterisk) {\n\t\t\tprefix := p.nameToken()\n\t\t\tp.advance()\n\t\t\tattr.NamespacedName.NamespacePrefix = &prefix\n\t\t} else {\n\t\t\t// \"[|attr]\" is equivalent to \"[attr]\". From the specification:\n\t\t\t// \"In keeping with the Namespaces in the XML recommendation, default\n\t\t\t// namespaces do not apply to attributes, therefore attribute selectors\n\t\t\t// without a namespace component apply only to attributes that have no\n\t\t\t// namespace (equivalent to |attr).\"\n\t\t}\n\t\tif !p.expect(css_lexer.TDelimBar) {\n\t\t\treturn\n\t\t}\n\t\tattr.NamespacedName.Name = p.nameToken()\n\t\tif !p.expect(css_lexer.TIdent) {\n\t\t\treturn\n\t\t}\n\n\tdefault:\n\t\t// \"[x]\"\n\t\t// \"[x|y]\"\n\t\tattr.NamespacedName.Name = p.nameToken()\n\t\tif !p.expect(css_lexer.TIdent) {\n\t\t\treturn\n\t\t}\n\t\tif p.next().Kind != css_lexer.TDelimEquals && p.eat(css_lexer.TDelimBar) {\n\t\t\tprefix := attr.NamespacedName.Name\n\t\t\tattr.NamespacedName.NamespacePrefix = &prefix\n\t\t\tattr.NamespacedName.Name = p.nameToken()\n\t\t\tif !p.expect(css_lexer.TIdent) {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Parse the optional matcher operator\n\tp.eat(css_lexer.TWhitespace)\n\tif p.eat(css_lexer.TDelimEquals) {\n\t\tattr.MatcherOp = \"=\"\n\t} else {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TDelimTilde:\n\t\t\tattr.MatcherOp = \"~=\"\n\t\tcase css_lexer.TDelimBar:\n\t\t\tattr.MatcherOp = \"|=\"\n\t\tcase css_lexer.TDelimCaret:\n\t\t\tattr.MatcherOp = \"^=\"\n\t\tcase css_lexer.TDelimDollar:\n\t\t\tattr.MatcherOp = \"$=\"\n\t\tcase css_lexer.TDelimAsterisk:\n\t\t\tattr.MatcherOp = \"*=\"\n\t\t}\n\t\tif attr.MatcherOp != \"\" {\n\t\t\tp.advance()\n\t\t\tp.expect(css_lexer.TDelimEquals)\n\t\t}\n\t}\n\n\t// Parse the optional matcher value\n\tif attr.MatcherOp != \"\" {\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif !p.peek(css_lexer.TString) && !p.peek(css_lexer.TIdent) {\n\t\t\tp.unexpected()\n\t\t}\n\t\tattr.MatcherValue = p.decoded()\n\t\tp.advance()\n\t\tp.eat(css_lexer.TWhitespace)\n\t\tif p.peek(css_lexer.TIdent) {\n\t\t\tif modifier := p.decoded(); len(modifier) == 1 {\n\t\t\t\tif c := modifier[0]; c == 'i' || c == 'I' || c == 's' || c == 'S' {\n\t\t\t\t\tattr.MatcherModifier = c\n\t\t\t\t\tp.advance()\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tp.expect(css_lexer.TCloseBracket)\n\tok = true\n\treturn\n}\n\nfunc (p *parser) parsePseudoClassSelector() css_ast.SSPseudoClass {\n\tp.advance()\n\n\tif p.peek(css_lexer.TFunction) {\n\t\ttext := p.decoded()\n\t\tp.advance()\n\t\targs := p.convertTokens(p.parseAnyValue())\n\t\tp.expect(css_lexer.TCloseParen)\n\t\treturn css_ast.SSPseudoClass{Name: text, Args: args}\n\t}\n\n\tname := p.decoded()\n\tsel := css_ast.SSPseudoClass{}\n\tif p.expect(css_lexer.TIdent) {\n\t\tsel.Name = name\n\t}\n\treturn sel\n}\n\nfunc (p *parser) parseAnyValue() []css_lexer.Token {\n\t// Reference: https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value\n\n\tp.stack = p.stack[:0] // Reuse allocated memory\n\tstart := p.index\n\nloop:\n\tfor {\n\t\tswitch p.current().Kind {\n\t\tcase css_lexer.TCloseParen, css_lexer.TCloseBracket, css_lexer.TCloseBrace:\n\t\t\tlast := len(p.stack) - 1\n\t\t\tif last < 0 || !p.peek(p.stack[last]) {\n\t\t\t\tbreak loop\n\t\t\t}\n\t\t\tp.stack = p.stack[:last]\n\n\t\tcase css_lexer.TSemicolon, css_lexer.TDelimExclamation:\n\t\t\tif len(p.stack) == 0 {\n\t\t\t\tbreak loop\n\t\t\t}\n\n\t\tcase css_lexer.TOpenParen, css_lexer.TFunction:\n\t\t\tp.stack = append(p.stack, css_lexer.TCloseParen)\n\n\t\tcase css_lexer.TOpenBracket:\n\t\t\tp.stack = append(p.stack, css_lexer.TCloseBracket)\n\n\t\tcase css_lexer.TOpenBrace:\n\t\t\tp.stack = append(p.stack, css_lexer.TCloseBrace)\n\t\t}\n\n\t\tp.advance()\n\t}\n\n\ttokens := p.tokens[start:p.index]\n\tif len(tokens) == 0 {\n\t\tp.unexpected()\n\t}\n\treturn tokens\n}\n\nfunc (p *parser) parseCombinator() string {\n\tswitch p.current().Kind {\n\tcase css_lexer.TDelimGreaterThan:\n\t\tp.advance()\n\t\treturn \">\"\n\n\tcase css_lexer.TDelimPlus:\n\t\tp.advance()\n\t\treturn \"+\"\n\n\tcase css_lexer.TDelimTilde:\n\t\tp.advance()\n\t\treturn \"~\"\n\n\tdefault:\n\t\treturn \"\"\n\t}\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_parser_test.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/compat\"\n\t\"github.com/withastro/compiler/lib/esbuild/config\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_printer\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n\t\"github.com/withastro/compiler/lib/esbuild/test\"\n)\n\nfunc expectParseError(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\tt.Run(contents, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug)\n\t\tParse(log, test.SourceForTest(contents), Options{})\n\t\tmsgs := log.Done()\n\t\ttext := \"\"\n\t\tfor _, msg := range msgs {\n\t\t\ttext += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text, expected)\n\t})\n}\n\nfunc expectPrintedCommon(t *testing.T, name string, contents string, expected string, options config.Options) {\n\tt.Helper()\n\tt.Run(name, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug)\n\t\ttree := Parse(log, test.SourceForTest(contents), Options{\n\t\t\tMinifySyntax:           options.MinifySyntax,\n\t\t\tMinifyWhitespace:       options.MinifyWhitespace,\n\t\t\tUnsupportedCSSFeatures: options.UnsupportedCSSFeatures,\n\t\t})\n\t\tmsgs := log.Done()\n\t\ttext := \"\"\n\t\tfor _, msg := range msgs {\n\t\t\tif msg.Kind == logger.Error {\n\t\t\t\ttext += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})\n\t\t\t}\n\t\t}\n\t\ttest.AssertEqualWithDiff(t, text, \"\")\n\t\tresult := css_printer.Print(tree, css_printer.Options{\n\t\t\tMinifyWhitespace: options.MinifyWhitespace,\n\t\t})\n\t\ttest.AssertEqualWithDiff(t, string(result.CSS), expected)\n\t})\n}\n\nfunc expectPrinted(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, config.Options{})\n}\n\nfunc expectPrintedLower(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangle]\", contents, expected, config.Options{\n\t\tUnsupportedCSSFeatures: ^compat.CSSFeature(0),\n\t})\n}\n\nfunc expectPrintedMinify(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [minify]\", contents, expected, config.Options{\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedMangle(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangle]\", contents, expected, config.Options{\n\t\tMinifySyntax: true,\n\t})\n}\n\nfunc expectPrintedLowerMangle(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangle]\", contents, expected, config.Options{\n\t\tUnsupportedCSSFeatures: ^compat.CSSFeature(0),\n\t\tMinifySyntax:           true,\n\t})\n}\n\nfunc expectPrintedMangleMinify(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [mangle, minify]\", contents, expected, config.Options{\n\t\tMinifySyntax:     true,\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc TestSingleLineComment(t *testing.T) {\n\texpectParseError(t, \"a, // a\\nb // b\\n{}\",\n\t\t\"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\"+\n\t\t\t\"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\")\n\texpectParseError(t, \"a, ///// a /////\\n{}\",\n\t\t\"<stdin>: WARNING: Comments in CSS use \\\"/* ... */\\\" instead of \\\"//\\\"\\n\")\n\n\texpectPrinted(t, \"a, // a\\nb // b\\n{}\", \"a, // a b // b {\\n}\\n\")\n\texpectPrinted(t, \"a, ///// a /////\\n{}\", \"a, ///// a ///// {\\n}\\n\")\n}\n\nfunc TestEscapes(t *testing.T) {\n\t// TIdent\n\texpectPrinted(t, \"a { value: id\\\\65nt }\", \"a {\\n  value: ident;\\n}\\n\")\n\texpectPrinted(t, \"a { value: \\\\69 dent }\", \"a {\\n  value: ident;\\n}\\n\")\n\texpectPrinted(t, \"a { value: \\\\69dent }\", \"a {\\n  value: \\u69DEnt;\\n}\\n\")\n\texpectPrinted(t, \"a { value: \\\\2cx }\", \"a {\\n  value: \\\\,x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: \\\\,x }\", \"a {\\n  value: \\\\,x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\\\2c }\", \"a {\\n  value: x\\\\,;\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\\\, }\", \"a {\\n  value: x\\\\,;\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\\\0 }\", \"a {\\n  value: x\\uFFFD;\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\\\1 }\", \"a {\\n  value: x\\\\\\x01;\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\x00 }\", \"a {\\n  value: x\\uFFFD;\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\x01 }\", \"a {\\n  value: x\\x01;\\n}\\n\")\n\n\t// THash\n\texpectPrinted(t, \"a { value: #0h\\\\61sh }\", \"a {\\n  value: #0hash;\\n}\\n\")\n\texpectPrinted(t, \"a { value: #\\\\30hash }\", \"a {\\n  value: #0hash;\\n}\\n\")\n\texpectPrinted(t, \"a { value: #\\\\2cx }\", \"a {\\n  value: #\\\\,x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: #\\\\,x }\", \"a {\\n  value: #\\\\,x;\\n}\\n\")\n\n\t// THashID\n\texpectPrinted(t, \"a { value: #h\\\\61sh }\", \"a {\\n  value: #hash;\\n}\\n\")\n\texpectPrinted(t, \"a { value: #\\\\68 ash }\", \"a {\\n  value: #hash;\\n}\\n\")\n\texpectPrinted(t, \"a { value: #\\\\68ash }\", \"a {\\n  value: #\\u068Ash;\\n}\\n\")\n\texpectPrinted(t, \"a { value: #x\\\\2c }\", \"a {\\n  value: #x\\\\,;\\n}\\n\")\n\texpectPrinted(t, \"a { value: #x\\\\, }\", \"a {\\n  value: #x\\\\,;\\n}\\n\")\n\n\t// TFunction\n\texpectPrinted(t, \"a { value: f\\\\6e() }\", \"a {\\n  value: fn();\\n}\\n\")\n\texpectPrinted(t, \"a { value: \\\\66n() }\", \"a {\\n  value: fn();\\n}\\n\")\n\texpectPrinted(t, \"a { value: \\\\2cx() }\", \"a {\\n  value: \\\\,x();\\n}\\n\")\n\texpectPrinted(t, \"a { value: \\\\,x() }\", \"a {\\n  value: \\\\,x();\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\\\2c() }\", \"a {\\n  value: x\\\\,();\\n}\\n\")\n\texpectPrinted(t, \"a { value: x\\\\,() }\", \"a {\\n  value: x\\\\,();\\n}\\n\")\n\n\t// TString\n\texpectPrinted(t, \"a { value: 'a\\\\62 c' }\", \"a {\\n  value: \\\"abc\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: 'a\\\\62c' }\", \"a {\\n  value: \\\"a\\u062C\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\\\61 bc' }\", \"a {\\n  value: \\\"abc\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\\\61bc' }\", \"a {\\n  value: \\\"\\u61BC\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\\\2c' }\", \"a {\\n  value: \\\",\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\\\,' }\", \"a {\\n  value: \\\",\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\\\0' }\", \"a {\\n  value: \\\"\\uFFFD\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\\\1' }\", \"a {\\n  value: \\\"\\x01\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\x00' }\", \"a {\\n  value: \\\"\\uFFFD\\\";\\n}\\n\")\n\texpectPrinted(t, \"a { value: '\\x01' }\", \"a {\\n  value: \\\"\\x01\\\";\\n}\\n\")\n\n\t// TURL\n\texpectPrinted(t, \"a { value: url(a\\\\62 c) }\", \"a {\\n  value: url(abc);\\n}\\n\")\n\texpectPrinted(t, \"a { value: url(a\\\\62c) }\", \"a {\\n  value: url(a\\u062C);\\n}\\n\")\n\texpectPrinted(t, \"a { value: url(\\\\61 bc) }\", \"a {\\n  value: url(abc);\\n}\\n\")\n\texpectPrinted(t, \"a { value: url(\\\\61bc) }\", \"a {\\n  value: url(\\u61BC);\\n}\\n\")\n\texpectPrinted(t, \"a { value: url(\\\\2c) }\", \"a {\\n  value: url(,);\\n}\\n\")\n\texpectPrinted(t, \"a { value: url(\\\\,) }\", \"a {\\n  value: url(,);\\n}\\n\")\n\n\t// TAtKeyword\n\texpectPrinted(t, \"a { value: @k\\\\65yword }\", \"a {\\n  value: @keyword;\\n}\\n\")\n\texpectPrinted(t, \"a { value: @\\\\6b eyword }\", \"a {\\n  value: @keyword;\\n}\\n\")\n\texpectPrinted(t, \"a { value: @\\\\6beyword }\", \"a {\\n  value: @\\u06BEyword;\\n}\\n\")\n\texpectPrinted(t, \"a { value: @\\\\2cx }\", \"a {\\n  value: @\\\\,x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: @\\\\,x }\", \"a {\\n  value: @\\\\,x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: @x\\\\2c }\", \"a {\\n  value: @x\\\\,;\\n}\\n\")\n\texpectPrinted(t, \"a { value: @x\\\\, }\", \"a {\\n  value: @x\\\\,;\\n}\\n\")\n\n\t// TDimension\n\texpectPrinted(t, \"a { value: 10\\\\65m }\", \"a {\\n  value: 10em;\\n}\\n\")\n\texpectPrinted(t, \"a { value: 10p\\\\32x }\", \"a {\\n  value: 10p2x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: 10e\\\\32x }\", \"a {\\n  value: 10\\\\65 2x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: 10\\\\32x }\", \"a {\\n  value: 10\\\\32x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: 10\\\\2cx }\", \"a {\\n  value: 10\\\\,x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: 10\\\\,x }\", \"a {\\n  value: 10\\\\,x;\\n}\\n\")\n\texpectPrinted(t, \"a { value: 10x\\\\2c }\", \"a {\\n  value: 10x\\\\,;\\n}\\n\")\n\texpectPrinted(t, \"a { value: 10x\\\\, }\", \"a {\\n  value: 10x\\\\,;\\n}\\n\")\n\n\t// RDeclaration\n\texpectPrintedMangle(t, \"a { c\\\\6flor: #f00 }\", \"a {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { \\\\63olor: #f00 }\", \"a {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { \\\\2color: #f00 }\", \"a {\\n  \\\\,olor: #f00;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { \\\\,olor: #f00 }\", \"a {\\n  \\\\,olor: #f00;\\n}\\n\")\n\n\t// RUnknownAt\n\texpectPrinted(t, \"@unknown;\", \"@unknown;\\n\")\n\texpectPrinted(t, \"@u\\\\6eknown;\", \"@unknown;\\n\")\n\texpectPrinted(t, \"@\\\\75nknown;\", \"@unknown;\\n\")\n\texpectPrinted(t, \"@u\\\\2cnknown;\", \"@u\\\\,nknown;\\n\")\n\texpectPrinted(t, \"@u\\\\,nknown;\", \"@u\\\\,nknown;\\n\")\n\texpectPrinted(t, \"@\\\\2cunknown;\", \"@\\\\,unknown;\\n\")\n\texpectPrinted(t, \"@\\\\,unknown;\", \"@\\\\,unknown;\\n\")\n\n\t// RAtKeyframes\n\texpectPrinted(t, \"@k\\\\65yframes abc { from {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes \\\\61 bc { from {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes a\\\\62 c { from {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes abc { \\\\66rom {} }\", \"@keyframes abc {\\n  from {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes a\\\\2c c { \\\\66rom {} }\", \"@keyframes a\\\\,c {\\n  from {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes a\\\\,c { \\\\66rom {} }\", \"@keyframes a\\\\,c {\\n  from {\\n  }\\n}\\n\")\n\n\t// RAtNamespace\n\texpectPrinted(t, \"@n\\\\61mespace ns 'path';\", \"@namespace ns \\\"path\\\";\\n\")\n\texpectPrinted(t, \"@namespace \\\\6es 'path';\", \"@namespace ns \\\"path\\\";\\n\")\n\texpectPrinted(t, \"@namespace ns 'p\\\\61th';\", \"@namespace ns \\\"path\\\";\\n\")\n\texpectPrinted(t, \"@namespace \\\\2cs 'p\\\\61th';\", \"@namespace \\\\,s \\\"path\\\";\\n\")\n\texpectPrinted(t, \"@namespace \\\\,s 'p\\\\61th';\", \"@namespace \\\\,s \\\"path\\\";\\n\")\n\n\t// CompoundSelector\n\texpectPrinted(t, \"* {}\", \"* {\\n}\\n\")\n\texpectPrinted(t, \"*|div {}\", \"*|div {\\n}\\n\")\n\texpectPrinted(t, \"\\\\2a {}\", \"\\\\* {\\n}\\n\")\n\texpectPrinted(t, \"\\\\2a|div {}\", \"\\\\*|div {\\n}\\n\")\n\texpectPrinted(t, \"\\\\2d {}\", \"\\\\- {\\n}\\n\")\n\texpectPrinted(t, \"\\\\2d- {}\", \"-- {\\n}\\n\")\n\texpectPrinted(t, \"-\\\\2d {}\", \"-- {\\n}\\n\")\n\texpectPrinted(t, \"\\\\2d 123 {}\", \"\\\\-123 {\\n}\\n\")\n\n\t// SSHash\n\texpectPrinted(t, \"#h\\\\61sh {}\", \"#hash {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\2chash {}\", \"#\\\\,hash {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\,hash {}\", \"#\\\\,hash {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\2d {}\", \"#\\\\- {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\2d- {}\", \"#-- {\\n}\\n\")\n\texpectPrinted(t, \"#-\\\\2d {}\", \"#-- {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\2d 123 {}\", \"#\\\\-123 {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\61hash {}\", \"#ahash {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\30hash {}\", \"#\\\\30hash {\\n}\\n\")\n\texpectPrinted(t, \"#0\\\\2chash {}\", \"#0\\\\,hash {\\n}\\n\")\n\texpectPrinted(t, \"#0\\\\,hash {}\", \"#0\\\\,hash {\\n}\\n\")\n\n\t// SSClass\n\texpectPrinted(t, \".cl\\\\61ss {}\", \".class {\\n}\\n\")\n\texpectPrinted(t, \".\\\\2c class {}\", \".\\\\,class {\\n}\\n\")\n\texpectPrinted(t, \".\\\\,class {}\", \".\\\\,class {\\n}\\n\")\n\n\t// SSPseudoClass\n\texpectPrinted(t, \":pseudocl\\\\61ss {}\", \":pseudoclass {\\n}\\n\")\n\texpectPrinted(t, \":pseudo\\\\2c class {}\", \":pseudo\\\\,class {\\n}\\n\")\n\texpectPrinted(t, \":pseudo\\\\,class {}\", \":pseudo\\\\,class {\\n}\\n\")\n\texpectPrinted(t, \":pseudo(cl\\\\61ss) {}\", \":pseudo(class) {\\n}\\n\")\n\texpectPrinted(t, \":pseudo(cl\\\\2css) {}\", \":pseudo(cl\\\\,ss) {\\n}\\n\")\n\texpectPrinted(t, \":pseudo(cl\\\\,ss) {}\", \":pseudo(cl\\\\,ss) {\\n}\\n\")\n\n\t// SSAttribute\n\texpectPrinted(t, \"[\\\\61ttr] {}\", \"[attr] {\\n}\\n\")\n\texpectPrinted(t, \"[\\\\2c attr] {}\", \"[\\\\,attr] {\\n}\\n\")\n\texpectPrinted(t, \"[\\\\,attr] {}\", \"[\\\\,attr] {\\n}\\n\")\n\texpectPrinted(t, \"[attr\\\\7e=x] {}\", \"[attr\\\\~=x] {\\n}\\n\")\n\texpectPrinted(t, \"[attr\\\\~=x] {}\", \"[attr\\\\~=x] {\\n}\\n\")\n\texpectPrinted(t, \"[attr=\\\\2c] {}\", \"[attr=\\\",\\\"] {\\n}\\n\")\n\texpectPrinted(t, \"[attr=\\\\,] {}\", \"[attr=\\\",\\\"] {\\n}\\n\")\n\texpectPrinted(t, \"[attr=\\\"-\\\"] {}\", \"[attr=\\\"-\\\"] {\\n}\\n\")\n\texpectPrinted(t, \"[attr=\\\"--\\\"] {}\", \"[attr=--] {\\n}\\n\")\n\texpectPrinted(t, \"[attr=\\\"-a\\\"] {}\", \"[attr=-a] {\\n}\\n\")\n\texpectPrinted(t, \"[\\\\6es|attr] {}\", \"[ns|attr] {\\n}\\n\")\n\texpectPrinted(t, \"[ns|\\\\61ttr] {}\", \"[ns|attr] {\\n}\\n\")\n\texpectPrinted(t, \"[\\\\2cns|attr] {}\", \"[\\\\,ns|attr] {\\n}\\n\")\n\texpectPrinted(t, \"[ns|\\\\2c attr] {}\", \"[ns|\\\\,attr] {\\n}\\n\")\n\texpectPrinted(t, \"[*|attr] {}\", \"[*|attr] {\\n}\\n\")\n\texpectPrinted(t, \"[\\\\2a|attr] {}\", \"[\\\\*|attr] {\\n}\\n\")\n}\n\nfunc TestString(t *testing.T) {\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\rb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\nb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\fb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\\\r\\nb' }\", \"a:after {\\n  content: \\\"ab\\\";\\n}\\n\")\n\texpectPrinted(t, \"a:after { content: 'a\\\\62 c' }\", \"a:after {\\n  content: \\\"abc\\\";\\n}\\n\")\n\n\texpectParseError(t, \"a:after { content: '\\r' }\",\n\t\t`<stdin>: ERROR: Unterminated string token\n<stdin>: ERROR: Unterminated string token\n<stdin>: WARNING: Expected \"}\" but found end of file\n`)\n\texpectParseError(t, \"a:after { content: '\\n' }\",\n\t\t`<stdin>: ERROR: Unterminated string token\n<stdin>: ERROR: Unterminated string token\n<stdin>: WARNING: Expected \"}\" but found end of file\n`)\n\texpectParseError(t, \"a:after { content: '\\f' }\",\n\t\t`<stdin>: ERROR: Unterminated string token\n<stdin>: ERROR: Unterminated string token\n<stdin>: WARNING: Expected \"}\" but found end of file\n`)\n\texpectParseError(t, \"a:after { content: '\\r\\n' }\",\n\t\t`<stdin>: ERROR: Unterminated string token\n<stdin>: ERROR: Unterminated string token\n<stdin>: WARNING: Expected \"}\" but found end of file\n`)\n\n\texpectPrinted(t, \"a:after { content: '\\\\1010101' }\", \"a:after {\\n  content: \\\"\\U001010101\\\";\\n}\\n\")\n\texpectPrinted(t, \"a:after { content: '\\\\invalid' }\", \"a:after {\\n  content: \\\"invalid\\\";\\n}\\n\")\n}\n\nfunc TestNumber(t *testing.T) {\n\tfor _, ext := range []string{\"\", \"%\", \"px+\"} {\n\t\texpectPrinted(t, \"a { width: .0\"+ext+\"; }\", \"a {\\n  width: .0\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: .00\"+ext+\"; }\", \"a {\\n  width: .00\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: .10\"+ext+\"; }\", \"a {\\n  width: .10\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: 0.\"+ext+\"; }\", \"a {\\n  width: 0.\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: 0.0\"+ext+\"; }\", \"a {\\n  width: 0.0\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: 0.1\"+ext+\"; }\", \"a {\\n  width: 0.1\"+ext+\";\\n}\\n\")\n\n\t\texpectPrinted(t, \"a { width: +.0\"+ext+\"; }\", \"a {\\n  width: +.0\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: +.00\"+ext+\"; }\", \"a {\\n  width: +.00\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: +.10\"+ext+\"; }\", \"a {\\n  width: +.10\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: +0.\"+ext+\"; }\", \"a {\\n  width: +0.\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: +0.0\"+ext+\"; }\", \"a {\\n  width: +0.0\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: +0.1\"+ext+\"; }\", \"a {\\n  width: +0.1\"+ext+\";\\n}\\n\")\n\n\t\texpectPrinted(t, \"a { width: -.0\"+ext+\"; }\", \"a {\\n  width: -.0\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: -.00\"+ext+\"; }\", \"a {\\n  width: -.00\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: -.10\"+ext+\"; }\", \"a {\\n  width: -.10\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: -0.\"+ext+\"; }\", \"a {\\n  width: -0.\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: -0.0\"+ext+\"; }\", \"a {\\n  width: -0.0\"+ext+\";\\n}\\n\")\n\t\texpectPrinted(t, \"a { width: -0.1\"+ext+\"; }\", \"a {\\n  width: -0.1\"+ext+\";\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { width: .0\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: .00\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: .10\"+ext+\"; }\", \"a {\\n  width: .1\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: 0.\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: 0.0\"+ext+\"; }\", \"a {\\n  width: 0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: 0.1\"+ext+\"; }\", \"a {\\n  width: .1\"+ext+\";\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { width: +.0\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: +.00\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: +.10\"+ext+\"; }\", \"a {\\n  width: +.1\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: +0.\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: +0.0\"+ext+\"; }\", \"a {\\n  width: +0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: +0.1\"+ext+\"; }\", \"a {\\n  width: +.1\"+ext+\";\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { width: -.0\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: -.00\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: -.10\"+ext+\"; }\", \"a {\\n  width: -.1\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: -0.\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: -0.0\"+ext+\"; }\", \"a {\\n  width: -0\"+ext+\";\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { width: -0.1\"+ext+\"; }\", \"a {\\n  width: -.1\"+ext+\";\\n}\\n\")\n\t}\n}\n\nfunc TestHexColor(t *testing.T) {\n\t// \"#RGBA\"\n\n\texpectPrinted(t, \"a { color: #1234 }\", \"a {\\n  color: #1234;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #123f }\", \"a {\\n  color: #123f;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #abcd }\", \"a {\\n  color: #abcd;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #abcf }\", \"a {\\n  color: #abcf;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #ABCD }\", \"a {\\n  color: #ABCD;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #ABCF }\", \"a {\\n  color: #ABCF;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #1234 }\", \"a {\\n  color: #1234;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #123f }\", \"a {\\n  color: #123;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #abcd }\", \"a {\\n  color: #abcd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #abcf }\", \"a {\\n  color: #abc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ABCD }\", \"a {\\n  color: #abcd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ABCF }\", \"a {\\n  color: #abc;\\n}\\n\")\n\n\t// \"#RRGGBB\"\n\n\texpectPrinted(t, \"a { color: #112233 }\", \"a {\\n  color: #112233;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #122233 }\", \"a {\\n  color: #122233;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #112333 }\", \"a {\\n  color: #112333;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #112234 }\", \"a {\\n  color: #112234;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #112233 }\", \"a {\\n  color: #123;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #122233 }\", \"a {\\n  color: #122233;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #112333 }\", \"a {\\n  color: #112333;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #112234 }\", \"a {\\n  color: #112234;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: #aabbcc }\", \"a {\\n  color: #aabbcc;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #abbbcc }\", \"a {\\n  color: #abbbcc;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabccc }\", \"a {\\n  color: #aabccc;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabbcd }\", \"a {\\n  color: #aabbcd;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #aabbcc }\", \"a {\\n  color: #abc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #abbbcc }\", \"a {\\n  color: #abbbcc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabccc }\", \"a {\\n  color: #aabccc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabbcd }\", \"a {\\n  color: #aabbcd;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: #AABBCC }\", \"a {\\n  color: #AABBCC;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #ABBBCC }\", \"a {\\n  color: #ABBBCC;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABCCC }\", \"a {\\n  color: #AABCCC;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABBCD }\", \"a {\\n  color: #AABBCD;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #AABBCC }\", \"a {\\n  color: #abc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ABBBCC }\", \"a {\\n  color: #abbbcc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABCCC }\", \"a {\\n  color: #aabccc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABBCD }\", \"a {\\n  color: #aabbcd;\\n}\\n\")\n\n\t// \"#RRGGBBAA\"\n\n\texpectPrinted(t, \"a { color: #11223344 }\", \"a {\\n  color: #11223344;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #12223344 }\", \"a {\\n  color: #12223344;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #11233344 }\", \"a {\\n  color: #11233344;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #11223444 }\", \"a {\\n  color: #11223444;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #11223345 }\", \"a {\\n  color: #11223345;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #11223344 }\", \"a {\\n  color: #1234;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #12223344 }\", \"a {\\n  color: #12223344;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #11233344 }\", \"a {\\n  color: #11233344;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #11223444 }\", \"a {\\n  color: #11223444;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #11223345 }\", \"a {\\n  color: #11223345;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: #aabbccdd }\", \"a {\\n  color: #aabbccdd;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #abbbccdd }\", \"a {\\n  color: #abbbccdd;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabcccdd }\", \"a {\\n  color: #aabcccdd;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabbcddd }\", \"a {\\n  color: #aabbcddd;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabbccde }\", \"a {\\n  color: #aabbccde;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #aabbccdd }\", \"a {\\n  color: #abcd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #abbbccdd }\", \"a {\\n  color: #abbbccdd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabcccdd }\", \"a {\\n  color: #aabcccdd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabbcddd }\", \"a {\\n  color: #aabbcddd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabbccde }\", \"a {\\n  color: #aabbccde;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: #AABBCCDD }\", \"a {\\n  color: #AABBCCDD;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #ABBBCCDD }\", \"a {\\n  color: #ABBBCCDD;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABCCCDD }\", \"a {\\n  color: #AABCCCDD;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABBCDDD }\", \"a {\\n  color: #AABBCDDD;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABBCCDE }\", \"a {\\n  color: #AABBCCDE;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #AABBCCDD }\", \"a {\\n  color: #abcd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ABBBCCDD }\", \"a {\\n  color: #abbbccdd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABCCCDD }\", \"a {\\n  color: #aabcccdd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABBCDDD }\", \"a {\\n  color: #aabbcddd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABBCCDE }\", \"a {\\n  color: #aabbccde;\\n}\\n\")\n\n\t// \"#RRGGBBFF\"\n\n\texpectPrinted(t, \"a { color: #112233ff }\", \"a {\\n  color: #112233ff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #122233ff }\", \"a {\\n  color: #122233ff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #112333ff }\", \"a {\\n  color: #112333ff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #112234ff }\", \"a {\\n  color: #112234ff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #112233ef }\", \"a {\\n  color: #112233ef;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #112233ff }\", \"a {\\n  color: #123;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #122233ff }\", \"a {\\n  color: #122233;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #112333ff }\", \"a {\\n  color: #112333;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #112234ff }\", \"a {\\n  color: #112234;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #112233ef }\", \"a {\\n  color: #112233ef;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: #aabbccff }\", \"a {\\n  color: #aabbccff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #abbbccff }\", \"a {\\n  color: #abbbccff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabcccff }\", \"a {\\n  color: #aabcccff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabbcdff }\", \"a {\\n  color: #aabbcdff;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #aabbccef }\", \"a {\\n  color: #aabbccef;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #aabbccff }\", \"a {\\n  color: #abc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #abbbccff }\", \"a {\\n  color: #abbbcc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabcccff }\", \"a {\\n  color: #aabccc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabbcdff }\", \"a {\\n  color: #aabbcd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #aabbccef }\", \"a {\\n  color: #aabbccef;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: #AABBCCFF }\", \"a {\\n  color: #AABBCCFF;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #ABBBCCFF }\", \"a {\\n  color: #ABBBCCFF;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABCCCFF }\", \"a {\\n  color: #AABCCCFF;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABBCDFF }\", \"a {\\n  color: #AABBCDFF;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #AABBCCEF }\", \"a {\\n  color: #AABBCCEF;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #AABBCCFF }\", \"a {\\n  color: #abc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ABBBCCFF }\", \"a {\\n  color: #abbbcc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABCCCFF }\", \"a {\\n  color: #aabccc;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABBCDFF }\", \"a {\\n  color: #aabbcd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #AABBCCEF }\", \"a {\\n  color: #aabbccef;\\n}\\n\")\n}\n\nfunc TestColorNames(t *testing.T) {\n\texpectPrinted(t, \"a { color: #f00 }\", \"a {\\n  color: #f00;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #f00f }\", \"a {\\n  color: #f00f;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #ff0000 }\", \"a {\\n  color: #ff0000;\\n}\\n\")\n\texpectPrinted(t, \"a { color: #ff0000ff }\", \"a {\\n  color: #ff0000ff;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: #f00 }\", \"a {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #f00e }\", \"a {\\n  color: #f00e;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #f00f }\", \"a {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ff0000 }\", \"a {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ff0000ef }\", \"a {\\n  color: #ff0000ef;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ff0000ff }\", \"a {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ffc0cb }\", \"a {\\n  color: pink;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ffc0cbef }\", \"a {\\n  color: #ffc0cbef;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: #ffc0cbff }\", \"a {\\n  color: pink;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: white }\", \"a {\\n  color: white;\\n}\\n\")\n\texpectPrinted(t, \"a { color: tUrQuOiSe }\", \"a {\\n  color: tUrQuOiSe;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: white }\", \"a {\\n  color: #fff;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: tUrQuOiSe }\", \"a {\\n  color: #40e0d0;\\n}\\n\")\n}\n\nfunc TestColorRGBA(t *testing.T) {\n\texpectPrintedMangle(t, \"a { color: rgba(1 2 3 / 0.5) }\", \"a {\\n  color: #01020380;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: rgba(1 2 3 / 50%) }\", \"a {\\n  color: #0102037f;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: rgba(1, 2, 3, 0.5) }\", \"a {\\n  color: #01020380;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: rgba(1, 2, 3, 50%) }\", \"a {\\n  color: #0102037f;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: rgba(1% 2% 3% / 0.5) }\", \"a {\\n  color: #03050880;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: rgba(1% 2% 3% / 50%) }\", \"a {\\n  color: #0305087f;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: rgba(1%, 2%, 3%, 0.5) }\", \"a {\\n  color: #03050880;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: rgba(1%, 2%, 3%, 50%) }\", \"a {\\n  color: #0305087f;\\n}\\n\")\n\n\texpectPrintedLowerMangle(t, \"a { color: rgb(1, 2, 3, 0.4) }\", \"a {\\n  color: rgba(1, 2, 3, .4);\\n}\\n\")\n\texpectPrintedLowerMangle(t, \"a { color: rgba(1, 2, 3, 40%) }\", \"a {\\n  color: rgba(1, 2, 3, .4);\\n}\\n\")\n\n\texpectPrintedLowerMangle(t, \"a { color: rgb(var(--x) var(--y) var(--z)) }\", \"a {\\n  color: rgb(var(--x) var(--y) var(--z));\\n}\\n\")\n}\n\nfunc TestColorHSLA(t *testing.T) {\n\texpectPrintedMangle(t, \".red { color: hsl(0, 100%, 50%) }\", \".red {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \".orange { color: hsl(30deg, 100%, 50%) }\", \".orange {\\n  color: #ff8000;\\n}\\n\")\n\texpectPrintedMangle(t, \".yellow { color: hsl(60 100% 50%) }\", \".yellow {\\n  color: #ff0;\\n}\\n\")\n\texpectPrintedMangle(t, \".green { color: hsl(120, 100%, 50%) }\", \".green {\\n  color: #0f0;\\n}\\n\")\n\texpectPrintedMangle(t, \".cyan { color: hsl(200grad, 100%, 50%) }\", \".cyan {\\n  color: #0ff;\\n}\\n\")\n\texpectPrintedMangle(t, \".blue { color: hsl(240, 100%, 50%) }\", \".blue {\\n  color: #00f;\\n}\\n\")\n\texpectPrintedMangle(t, \".purple { color: hsl(0.75turn 100% 50%) }\", \".purple {\\n  color: #7f00ff;\\n}\\n\")\n\texpectPrintedMangle(t, \".magenta { color: hsl(300, 100%, 50%) }\", \".magenta {\\n  color: #f0f;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { color: hsl(30 25% 50% / 50%) }\", \"a {\\n  color: #9f80607f;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: hsla(30 25% 50% / 50%) }\", \"a {\\n  color: #9f80607f;\\n}\\n\")\n\n\texpectPrintedLowerMangle(t, \"a { color: hsl(1, 2%, 3%, 0.4) }\", \"a {\\n  color: rgba(8, 8, 7, .4);\\n}\\n\")\n\texpectPrintedLowerMangle(t, \"a { color: hsla(1, 2%, 3%, 40%) }\", \"a {\\n  color: rgba(8, 8, 7, .4);\\n}\\n\")\n\n\texpectPrintedLowerMangle(t, \"a { color: hsl(var(--x) var(--y) var(--z)) }\", \"a {\\n  color: hsl(var(--x) var(--y) var(--z));\\n}\\n\")\n}\n\nfunc TestLowerColor(t *testing.T) {\n\texpectPrintedLower(t, \"a { color: rebeccapurple }\", \"a {\\n  color: #663399;\\n}\\n\")\n\n\texpectPrintedLower(t, \"a { color: #0123 }\", \"a {\\n  color: rgba(0, 17, 34, 0.2);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: #1230 }\", \"a {\\n  color: rgba(17, 34, 51, 0);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: #1234 }\", \"a {\\n  color: rgba(17, 34, 51, 0.267);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: #123f }\", \"a {\\n  color: rgba(17, 34, 51, 1);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: #12345678 }\", \"a {\\n  color: rgba(18, 52, 86, 0.471);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: #ff00007f }\", \"a {\\n  color: rgba(255, 0, 0, 0.498);\\n}\\n\")\n\n\texpectPrintedLower(t, \"a { color: rgb(1 2 3) }\", \"a {\\n  color: rgb(1, 2, 3);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsl(1 2% 3%) }\", \"a {\\n  color: hsl(1, 2%, 3%);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: rgba(1% 2% 3%) }\", \"a {\\n  color: rgb(1%, 2%, 3%);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsla(1deg 2% 3%) }\", \"a {\\n  color: hsl(1, 2%, 3%);\\n}\\n\")\n\n\texpectPrintedLower(t, \"a { color: hsla(200grad 2% 3%) }\", \"a {\\n  color: hsl(180, 2%, 3%);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsla(6.28319rad 2% 3%) }\", \"a {\\n  color: hsl(360, 2%, 3%);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsla(0.5turn 2% 3%) }\", \"a {\\n  color: hsl(180, 2%, 3%);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsla(+200grad 2% 3%) }\", \"a {\\n  color: hsl(180, 2%, 3%);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsla(-200grad 2% 3%) }\", \"a {\\n  color: hsl(-180, 2%, 3%);\\n}\\n\")\n\n\texpectPrintedLower(t, \"a { color: rgb(1 2 3 / 4) }\", \"a {\\n  color: rgba(1, 2, 3, 4);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: rgba(1% 2% 3% / 4%) }\", \"a {\\n  color: rgba(1%, 2%, 3%, 0.04);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsl(1 2% 3% / 4) }\", \"a {\\n  color: hsla(1, 2%, 3%, 4);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsla(1 2% 3% / 4%) }\", \"a {\\n  color: hsla(1, 2%, 3%, 0.04);\\n}\\n\")\n\n\texpectPrintedLower(t, \"a { color: rgb(1, 2, 3, 4) }\", \"a {\\n  color: rgba(1, 2, 3, 4);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: rgba(1%, 2%, 3%, 4%) }\", \"a {\\n  color: rgba(1%, 2%, 3%, 0.04);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: rgb(1%, 2%, 3%, 0.4%) }\", \"a {\\n  color: rgba(1%, 2%, 3%, 0.004);\\n}\\n\")\n\n\texpectPrintedLower(t, \"a { color: hsl(1, 2%, 3%, 4) }\", \"a {\\n  color: hsla(1, 2%, 3%, 4);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsla(1deg, 2%, 3%, 4%) }\", \"a {\\n  color: hsla(1, 2%, 3%, 0.04);\\n}\\n\")\n\texpectPrintedLower(t, \"a { color: hsl(1deg, 2%, 3%, 0.4%) }\", \"a {\\n  color: hsla(1, 2%, 3%, 0.004);\\n}\\n\")\n}\n\nfunc TestDeclaration(t *testing.T) {\n\texpectPrinted(t, \".decl {}\", \".decl {\\n}\\n\")\n\texpectPrinted(t, \".decl { a: b }\", \".decl {\\n  a: b;\\n}\\n\")\n\texpectPrinted(t, \".decl { a: b; }\", \".decl {\\n  a: b;\\n}\\n\")\n\texpectPrinted(t, \".decl { a: b; c: d }\", \".decl {\\n  a: b;\\n  c: d;\\n}\\n\")\n\texpectPrinted(t, \".decl { a: b; c: d; }\", \".decl {\\n  a: b;\\n  c: d;\\n}\\n\")\n\texpectParseError(t, \".decl { a { b: c; } }\", \"<stdin>: WARNING: Expected \\\":\\\"\\n\")\n\texpectPrinted(t, \".decl { & a { b: c; } }\", \".decl {\\n  & a {\\n    b: c;\\n  }\\n}\\n\")\n\n\t// See http://browserhacks.com/\n\texpectPrinted(t, \".selector { (;property: value;); }\", \".selector {\\n  (;property: value;);\\n}\\n\")\n\texpectPrinted(t, \".selector { [;property: value;]; }\", \".selector {\\n  [;property: value;];\\n}\\n\")\n\texpectPrinted(t, \".selector, {}\", \".selector, {\\n}\\n\")\n\texpectPrinted(t, \".selector\\\\ {}\", \".selector\\\\  {\\n}\\n\")\n\texpectPrinted(t, \".selector { property: value\\\\9; }\", \".selector {\\n  property: value\\\\\\t;\\n}\\n\")\n\texpectPrinted(t, \"@media \\\\0screen\\\\,screen\\\\9 {}\", \"@media \\uFFFDscreen\\\\,screen\\\\\\t {\\n}\\n\")\n}\n\nfunc TestSelector(t *testing.T) {\n\texpectPrinted(t, \"a{}\", \"a {\\n}\\n\")\n\texpectPrinted(t, \"a {}\", \"a {\\n}\\n\")\n\texpectPrinted(t, \"a b {}\", \"a b {\\n}\\n\")\n\n\texpectPrinted(t, \"a/**/b {}\", \"a b {\\n}\\n\")\n\texpectPrinted(t, \"a/**/.b {}\", \"a.b {\\n}\\n\")\n\texpectPrinted(t, \"a/**/:b {}\", \"a:b {\\n}\\n\")\n\texpectPrinted(t, \"a/**/[b] {}\", \"a[b] {\\n}\\n\")\n\texpectPrinted(t, \"a>/**/b {}\", \"a > b {\\n}\\n\")\n\texpectPrinted(t, \"a+/**/b {}\", \"a + b {\\n}\\n\")\n\texpectPrinted(t, \"a~/**/b {}\", \"a ~ b {\\n}\\n\")\n\n\texpectPrinted(t, \"[b]{}\", \"[b] {\\n}\\n\")\n\texpectPrinted(t, \"[b] {}\", \"[b] {\\n}\\n\")\n\texpectPrinted(t, \"a[b] {}\", \"a[b] {\\n}\\n\")\n\texpectPrinted(t, \"a [b] {}\", \"a [b] {\\n}\\n\")\n\texpectParseError(t, \"[] {}\", \"<stdin>: WARNING: Expected identifier but found \\\"]\\\"\\n\")\n\texpectParseError(t, \"[b {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"[b]] {}\", \"<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\texpectParseError(t, \"a[b {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"a[b]] {}\", \"<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\n\texpectPrinted(t, \"[|b]{}\", \"[b] {\\n}\\n\") // \"[|b]\" is equivalent to \"[b]\"\n\texpectPrinted(t, \"[*|b]{}\", \"[*|b] {\\n}\\n\")\n\texpectPrinted(t, \"[a|b]{}\", \"[a|b] {\\n}\\n\")\n\texpectPrinted(t, \"[a|b|=\\\"c\\\"]{}\", \"[a|b|=c] {\\n}\\n\")\n\texpectPrinted(t, \"[a|b |= \\\"c\\\"]{}\", \"[a|b|=c] {\\n}\\n\")\n\texpectParseError(t, \"[a||b] {}\", \"<stdin>: WARNING: Expected identifier but found \\\"|\\\"\\n\")\n\texpectParseError(t, \"[* | b] {}\", \"<stdin>: WARNING: Expected \\\"|\\\" but found whitespace\\n\")\n\texpectParseError(t, \"[a | b] {}\", \"<stdin>: WARNING: Expected \\\"=\\\" but found whitespace\\n\")\n\n\texpectPrinted(t, \"[b=\\\"c\\\"] {}\", \"[b=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b=\\\"c d\\\"] {}\", \"[b=\\\"c d\\\"] {\\n}\\n\")\n\texpectPrinted(t, \"[b=\\\"0c\\\"] {}\", \"[b=\\\"0c\\\"] {\\n}\\n\")\n\texpectPrinted(t, \"[b~=\\\"c\\\"] {}\", \"[b~=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b^=\\\"c\\\"] {}\", \"[b^=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b$=\\\"c\\\"] {}\", \"[b$=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b*=\\\"c\\\"] {}\", \"[b*=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b|=\\\"c\\\"] {}\", \"[b|=c] {\\n}\\n\")\n\texpectParseError(t, \"[b?=\\\"c\\\"] {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"?\\\"\\n\")\n\n\texpectPrinted(t, \"[b = \\\"c\\\"] {}\", \"[b=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b ~= \\\"c\\\"] {}\", \"[b~=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b ^= \\\"c\\\"] {}\", \"[b^=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b $= \\\"c\\\"] {}\", \"[b$=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b *= \\\"c\\\"] {}\", \"[b*=c] {\\n}\\n\")\n\texpectPrinted(t, \"[b |= \\\"c\\\"] {}\", \"[b|=c] {\\n}\\n\")\n\texpectParseError(t, \"[b ?= \\\"c\\\"] {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"?\\\"\\n\")\n\n\texpectPrinted(t, \"[b = \\\"c\\\" i] {}\", \"[b=c i] {\\n}\\n\")\n\texpectPrinted(t, \"[b = \\\"c\\\" I] {}\", \"[b=c I] {\\n}\\n\")\n\texpectPrinted(t, \"[b = \\\"c\\\" s] {}\", \"[b=c s] {\\n}\\n\")\n\texpectPrinted(t, \"[b = \\\"c\\\" S] {}\", \"[b=c S] {\\n}\\n\")\n\texpectParseError(t, \"[b i] {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"i\\\"\\n<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\texpectParseError(t, \"[b I] {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"I\\\"\\n<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\texpectParseError(t, \"[b s] {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"s\\\"\\n<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\texpectParseError(t, \"[b S] {}\", \"<stdin>: WARNING: Expected \\\"]\\\" but found \\\"S\\\"\\n<stdin>: WARNING: Unexpected \\\"]\\\"\\n\")\n\n\texpectPrinted(t, \"|b {}\", \"|b {\\n}\\n\")\n\texpectPrinted(t, \"|* {}\", \"|* {\\n}\\n\")\n\texpectPrinted(t, \"a|b {}\", \"a|b {\\n}\\n\")\n\texpectPrinted(t, \"a|* {}\", \"a|* {\\n}\\n\")\n\texpectPrinted(t, \"*|b {}\", \"*|b {\\n}\\n\")\n\texpectPrinted(t, \"*|* {}\", \"*|* {\\n}\\n\")\n\texpectParseError(t, \"a||b {}\", \"<stdin>: WARNING: Expected identifier but found \\\"|\\\"\\n\")\n\n\texpectPrinted(t, \"a+b {}\", \"a + b {\\n}\\n\")\n\texpectPrinted(t, \"a>b {}\", \"a > b {\\n}\\n\")\n\texpectPrinted(t, \"a+b {}\", \"a + b {\\n}\\n\")\n\texpectPrinted(t, \"a~b {}\", \"a ~ b {\\n}\\n\")\n\n\texpectPrinted(t, \"a + b {}\", \"a + b {\\n}\\n\")\n\texpectPrinted(t, \"a > b {}\", \"a > b {\\n}\\n\")\n\texpectPrinted(t, \"a + b {}\", \"a + b {\\n}\\n\")\n\texpectPrinted(t, \"a ~ b {}\", \"a ~ b {\\n}\\n\")\n\n\texpectPrinted(t, \"::b {}\", \"::b {\\n}\\n\")\n\texpectPrinted(t, \"*::b {}\", \"*::b {\\n}\\n\")\n\texpectPrinted(t, \"a::b {}\", \"a::b {\\n}\\n\")\n\texpectPrinted(t, \"::b(c) {}\", \"::b(c) {\\n}\\n\")\n\texpectPrinted(t, \"*::b(c) {}\", \"*::b(c) {\\n}\\n\")\n\texpectPrinted(t, \"a::b(c) {}\", \"a::b(c) {\\n}\\n\")\n\texpectPrinted(t, \"a:b:c {}\", \"a:b:c {\\n}\\n\")\n\texpectPrinted(t, \"a:b(:c) {}\", \"a:b(:c) {\\n}\\n\")\n\texpectPrinted(t, \"a: b {}\", \"a: b {\\n}\\n\")\n\n\texpectPrinted(t, \"#id {}\", \"#id {\\n}\\n\")\n\texpectPrinted(t, \"#--0 {}\", \"#--0 {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\-0 {}\", \"#\\\\-0 {\\n}\\n\")\n\texpectPrinted(t, \"#\\\\30 {}\", \"#\\\\30  {\\n}\\n\")\n\texpectPrinted(t, \"div#id {}\", \"div#id {\\n}\\n\")\n\texpectPrinted(t, \"div#--0 {}\", \"div#--0 {\\n}\\n\")\n\texpectPrinted(t, \"div#\\\\-0 {}\", \"div#\\\\-0 {\\n}\\n\")\n\texpectPrinted(t, \"div#\\\\30 {}\", \"div#\\\\30  {\\n}\\n\")\n\texpectParseError(t, \"#0 {}\", \"<stdin>: WARNING: Unexpected \\\"#0\\\"\\n\")\n\texpectParseError(t, \"#-0 {}\", \"<stdin>: WARNING: Unexpected \\\"#-0\\\"\\n\")\n\texpectParseError(t, \"div#0 {}\", \"<stdin>: WARNING: Unexpected \\\"#0\\\"\\n\")\n\texpectParseError(t, \"div#-0 {}\", \"<stdin>: WARNING: Unexpected \\\"#-0\\\"\\n\")\n\n\texpectPrinted(t, \"div::before::after::selection::first-line::first-letter {color:red}\",\n\t\t\"div::before::after::selection::first-line::first-letter {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"div::before::after::selection::first-line::first-letter {color:red}\",\n\t\t\"div:before:after::selection:first-line:first-letter {\\n  color: red;\\n}\\n\")\n\n\t// Make sure '-' and '\\\\' consume an ident-like token instead of a name\n\texpectParseError(t, \"_:-ms-lang(x) {}\", \"\")\n\texpectParseError(t, \"_:\\\\ms-lang(x) {}\", \"\")\n}\n\nfunc TestNestedSelector(t *testing.T) {\n\texpectPrinted(t, \"& {}\", \"& {\\n}\\n\")\n\texpectPrinted(t, \"& b {}\", \"& b {\\n}\\n\")\n\texpectPrinted(t, \"&:b {}\", \"&:b {\\n}\\n\")\n\texpectPrinted(t, \"&* {}\", \"&* {\\n}\\n\")\n\texpectPrinted(t, \"&|b {}\", \"&|b {\\n}\\n\")\n\texpectPrinted(t, \"&*|b {}\", \"&*|b {\\n}\\n\")\n\texpectPrinted(t, \"&a|b {}\", \"&a|b {\\n}\\n\")\n\texpectPrinted(t, \"&[a] {}\", \"&[a] {\\n}\\n\")\n\n\texpectPrinted(t, \"a { & {} }\", \"a {\\n  & {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { & b {} }\", \"a {\\n  & b {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { &:b {} }\", \"a {\\n  &:b {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { &* {} }\", \"a {\\n  &* {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { &|b {} }\", \"a {\\n  &|b {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { &*|b {} }\", \"a {\\n  &*|b {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { &a|b {} }\", \"a {\\n  &a|b {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { &[b] {} }\", \"a {\\n  &[b] {\\n  }\\n}\\n\")\n\n\texpectParseError(t, \"a { & b, c {} }\",\n\t\t\"<stdin>: WARNING: Every selector in a nested style rule must start with \\\"&\\\"\\n\"+\n\t\t\t\"<stdin>: NOTE: This is a nested style rule because of the \\\"&\\\" here:\\n\")\n\texpectParseError(t, \"a { & b, & c {} }\", \"\")\n\n\texpectParseError(t, \"a { b & {} }\", \"<stdin>: WARNING: Expected \\\":\\\"\\n\")\n\texpectParseError(t, \"a { @nest b & {} }\", \"\")\n\texpectParseError(t, \"a { @nest & b, c {} }\",\n\t\t\"<stdin>: WARNING: Every selector in a nested style rule must contain \\\"&\\\"\\n\"+\n\t\t\t\"<stdin>: NOTE: This is a nested style rule because of the \\\"@nest\\\" here:\\n\")\n\texpectParseError(t, \"a { @nest b &, c {} }\",\n\t\t\"<stdin>: WARNING: Every selector in a nested style rule must contain \\\"&\\\"\\n\"+\n\t\t\t\"<stdin>: NOTE: This is a nested style rule because of the \\\"@nest\\\" here:\\n\")\n\texpectPrinted(t, \"a { @nest b & { color: red } }\", \"a {\\n  @nest b & {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { @nest b& { color: red } }\", \"a {\\n  @nest b& {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { @nest b&[c] { color: red } }\", \"a {\\n  @nest b[c]& {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { @nest &[c] { color: red } }\", \"a {\\n  @nest &[c] {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"a { @nest [c]& { color: red } }\", \"a {\\n  @nest [c]& {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMinify(t, \"a { @nest b & { color: red } }\", \"a{@nest b &{color:red}}\")\n\texpectPrintedMinify(t, \"a { @nest b& { color: red } }\", \"a{@nest b&{color:red}}\")\n\n\t// Don't drop \"@nest\" for invalid rules\n\texpectParseError(t, \"a { @nest @invalid { color: red } }\", \"<stdin>: WARNING: Unexpected \\\"@invalid\\\"\\n\")\n\texpectPrinted(t, \"a { @nest @invalid { color: red } }\", \"a {\\n  @nest @invalid {\\n    color: red;\\n  }\\n}\\n\")\n\n\t// Check removal of \"@nest\" when minifying\n\texpectPrinted(t, \"a { @nest & b, & c { color: red } }\", \"a {\\n  @nest & b,\\n  & c {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"a { @nest & b, & c { color: red } }\", \"a {\\n  & b,\\n  & c {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"a { @nest b &, & c { color: red } }\", \"a {\\n  @nest b &,\\n  & c {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"a { @nest & b, c & { color: red } }\", \"a {\\n  @nest & b,\\n  c & {\\n    color: red;\\n  }\\n}\\n\")\n\n\toutside := \"<stdin>: WARNING: CSS nesting syntax cannot be used outside of a style rule\\n\"\n\texpectParseError(t, \"& a {}\", outside)\n\texpectParseError(t, \"@nest a & {}\", outside)\n\texpectParseError(t, \"@media screen { & a {} }\", outside)\n\texpectParseError(t, \"@media screen { @nest a & {} }\", outside)\n}\n\nfunc TestBadQualifiedRules(t *testing.T) {\n\texpectParseError(t, \"$bad: rule;\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectParseError(t, \"$bad { color: red }\", \"<stdin>: WARNING: Unexpected \\\"$\\\"\\n\")\n\texpectParseError(t, \"a { div.major { color: blue } color: red }\", \"<stdin>: WARNING: Expected \\\":\\\" but found \\\".\\\"\\n\")\n\texpectParseError(t, \"a { div:hover { color: blue } color: red }\", \"\")\n\texpectParseError(t, \"a { div:hover { color: blue }; color: red }\", \"\")\n\texpectParseError(t, \"a { div:hover { color: blue } ; color: red }\", \"\")\n\texpectParseError(t, \"! { x: {} }\", \"<stdin>: WARNING: Unexpected \\\"!\\\"\\n\")\n}\n\nfunc TestAtRule(t *testing.T) {\n\texpectPrinted(t, \"@unknown\", \"@unknown;\\n\")\n\texpectPrinted(t, \"@unknown;\", \"@unknown;\\n\")\n\texpectPrinted(t, \"@unknown{}\", \"@unknown {}\\n\")\n\texpectPrinted(t, \"@unknown x;\", \"@unknown x;\\n\")\n\texpectPrinted(t, \"@unknown{\\na: b;\\nc: d;\\n}\", \"@unknown { a: b; c: d; }\\n\")\n\n\texpectParseError(t, \"@unknown\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectParseError(t, \"@\", \"<stdin>: WARNING: Unexpected \\\"@\\\"\\n\")\n\texpectParseError(t, \"@;\", \"<stdin>: WARNING: Unexpected \\\"@\\\"\\n\")\n\texpectParseError(t, \"@{}\", \"<stdin>: WARNING: Unexpected \\\"@\\\"\\n\")\n\n\texpectPrinted(t, \"@viewport { width: 100vw }\", \"@viewport {\\n  width: 100vw;\\n}\\n\")\n\texpectPrinted(t, \"@-ms-viewport { width: 100vw }\", \"@-ms-viewport {\\n  width: 100vw;\\n}\\n\")\n\n\texpectPrinted(t, \"@document url(\\\"https://www.example.com/\\\") { h1 { color: green } }\",\n\t\t\"@document url(https://www.example.com/) {\\n  h1 {\\n    color: green;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@-moz-document url-prefix() { h1 { color: green } }\",\n\t\t\"@-moz-document url-prefix() {\\n  h1 {\\n    color: green;\\n  }\\n}\\n\")\n\n\t// https://www.w3.org/TR/css-page-3/#syntax-page-selector\n\texpectPrinted(t, `\n\t\t@page :first { margin: 0 }\n\t\t@page {\n\t\t\t@top-left-corner { content: 'tlc' }\n\t\t\t@top-left { content: 'tl' }\n\t\t\t@top-center { content: 'tc' }\n\t\t\t@top-right { content: 'tr' }\n\t\t\t@top-right-corner { content: 'trc' }\n\t\t\t@bottom-left-corner { content: 'blc' }\n\t\t\t@bottom-left { content: 'bl' }\n\t\t\t@bottom-center { content: 'bc' }\n\t\t\t@bottom-right { content: 'br' }\n\t\t\t@bottom-right-corner { content: 'brc' }\n\t\t\t@left-top { content: 'lt' }\n\t\t\t@left-middle { content: 'lm' }\n\t\t\t@left-bottom { content: 'lb' }\n\t\t\t@right-top { content: 'rt' }\n\t\t\t@right-middle { content: 'rm' }\n\t\t\t@right-bottom { content: 'rb' }\n\t\t}\n\t`, `@page :first {\n  margin: 0;\n}\n@page {\n  @top-left-corner {\n    content: \"tlc\";\n  }\n  @top-left {\n    content: \"tl\";\n  }\n  @top-center {\n    content: \"tc\";\n  }\n  @top-right {\n    content: \"tr\";\n  }\n  @top-right-corner {\n    content: \"trc\";\n  }\n  @bottom-left-corner {\n    content: \"blc\";\n  }\n  @bottom-left {\n    content: \"bl\";\n  }\n  @bottom-center {\n    content: \"bc\";\n  }\n  @bottom-right {\n    content: \"br\";\n  }\n  @bottom-right-corner {\n    content: \"brc\";\n  }\n  @left-top {\n    content: \"lt\";\n  }\n  @left-middle {\n    content: \"lm\";\n  }\n  @left-bottom {\n    content: \"lb\";\n  }\n  @right-top {\n    content: \"rt\";\n  }\n  @right-middle {\n    content: \"rm\";\n  }\n  @right-bottom {\n    content: \"rb\";\n  }\n}\n`)\n}\n\nfunc TestAtCharset(t *testing.T) {\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\";\", \"@charset \\\"UTF-8\\\";\\n\")\n\texpectPrinted(t, \"@charset 'UTF-8';\", \"@charset \\\"UTF-8\\\";\\n\")\n\n\texpectParseError(t, \"@charset \\\"utf-8\\\";\", \"\")\n\texpectParseError(t, \"@charset \\\"Utf-8\\\";\", \"\")\n\texpectParseError(t, \"@charset \\\"UTF-8\\\";\", \"\")\n\texpectParseError(t, \"@charset \\\"US-ASCII\\\";\", \"<stdin>: WARNING: \\\"UTF-8\\\" will be used instead of unsupported charset \\\"US-ASCII\\\"\\n\")\n\texpectParseError(t, \"@charset;\", \"<stdin>: WARNING: Expected whitespace but found \\\";\\\"\\n\")\n\texpectParseError(t, \"@charset ;\", \"<stdin>: WARNING: Expected string token but found \\\";\\\"\\n\")\n\texpectParseError(t, \"@charset\\\"UTF-8\\\";\", \"<stdin>: WARNING: Expected whitespace but found \\\"\\\\\\\"UTF-8\\\\\\\"\\\"\\n\")\n\texpectParseError(t, \"@charset \\\"UTF-8\\\"\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectParseError(t, \"@charset url(UTF-8);\", \"<stdin>: WARNING: Expected string token but found \\\"url(UTF-8)\\\"\\n\")\n\texpectParseError(t, \"@charset url(\\\"UTF-8\\\");\", \"<stdin>: WARNING: Expected string token but found \\\"url(\\\"\\n\")\n\texpectParseError(t, \"@charset \\\"UTF-8\\\" \", \"<stdin>: WARNING: Expected \\\";\\\" but found whitespace\\n\")\n\texpectParseError(t, \"@charset \\\"UTF-8\\\"{}\", \"<stdin>: WARNING: Expected \\\";\\\" but found \\\"{\\\"\\n\")\n\n\t// https://drafts.csswg.org/css-transitions-2/#defining-before-change-style-the-starting-style-rule\n\texpectPrinted(t, `\n\t@starting-style {\n\t\th1 {\n\t\t\tbackground-color: transparent;\n\t\t}\n\t\t@layer foo {\n\t\t\tdiv {\n\t\t\t\theight: 100px;\n\t\t\t}\n\t\t}\n\t}\n\t`, `@starting-style {\n  h1 {\n    background-color: transparent;\n  }\n  @layer foo {\n    div {\n      height: 100px;\n    }\n  }\n}\n`)\n\n\texpectPrintedMinify(t, `@starting-style {\n\th1 {\n\t\tbackground-color: transparent;\n\t}\n}`, \"@starting-style{h1{background-color:transparent}}\")\n}\n\nfunc TestAtImport(t *testing.T) {\n\texpectPrinted(t, \"@import\\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import \\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import \\\"foo.css\\\" ;\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url();\", \"@import \\\"\\\";\\n\")\n\texpectPrinted(t, \"@import url(foo.css);\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(foo.css) ;\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\");\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") ;\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") print;\", \"@import \\\"foo.css\\\" print;\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") screen and (orientation:landscape);\", \"@import \\\"foo.css\\\" screen and (orientation:landscape);\\n\")\n\n\texpectParseError(t, \"@import;\", \"<stdin>: WARNING: Expected URL token but found \\\";\\\"\\n\")\n\texpectParseError(t, \"@import ;\", \"<stdin>: WARNING: Expected URL token but found \\\";\\\"\\n\")\n\texpectParseError(t, \"@import \\\"foo.css\\\"\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectParseError(t, \"@import url(\\\"foo.css\\\";\", \"<stdin>: WARNING: Expected \\\")\\\" but found \\\";\\\"\\n\")\n\texpectParseError(t, \"@import noturl(\\\"foo.css\\\");\", \"<stdin>: WARNING: Expected URL token but found \\\"noturl(\\\"\\n\")\n\texpectParseError(t, \"@import url(\", `<stdin>: WARNING: Expected URL token but found bad URL token\n<stdin>: ERROR: Expected \")\" to end URL token\n<stdin>: WARNING: Expected \";\" but found end of file\n`)\n\n\texpectParseError(t, \"@import \\\"foo.css\\\" {}\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrinted(t, \"@import \\\"foo\\\"\\na { color: red }\\nb { color: blue }\", \"@import \\\"foo\\\" a { color: red }\\nb {\\n  color: blue;\\n}\\n\")\n\n\texpectParseError(t, \"a { @import \\\"foo.css\\\" }\", \"<stdin>: WARNING: \\\"@import\\\" is only valid at the top level\\n<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectPrinted(t, \"a { @import \\\"foo.css\\\" }\", \"a {\\n  @import \\\"foo.css\\\";\\n}\\n\")\n}\n\nfunc TestLegalComment(t *testing.T) {\n\texpectPrinted(t, \"/*!*/@import \\\"x\\\";\", \"/*!*/\\n@import \\\"x\\\";\\n\")\n\texpectPrinted(t, \"/*!*/@charset \\\"UTF-8\\\";\", \"/*!*/\\n@charset \\\"UTF-8\\\";\\n\")\n\texpectPrinted(t, \"/*!*/ @import \\\"x\\\";\", \"/*!*/\\n@import \\\"x\\\";\\n\")\n\texpectPrinted(t, \"/*!*/ @charset \\\"UTF-8\\\";\", \"/*!*/\\n@charset \\\"UTF-8\\\";\\n\")\n\texpectPrinted(t, \"/*!*/ @charset \\\"UTF-8\\\"; @import \\\"x\\\";\", \"/*!*/\\n@charset \\\"UTF-8\\\";\\n@import \\\"x\\\";\\n\")\n\texpectPrinted(t, \"/*!*/ @import \\\"x\\\"; @charset \\\"UTF-8\\\";\", \"/*!*/\\n@import \\\"x\\\";\\n@charset \\\"UTF-8\\\";\\n\")\n\n\texpectParseError(t, \"/*!*/ @import \\\"x\\\";\", \"\")\n\texpectParseError(t, \"/*!*/ @charset \\\"UTF-8\\\";\", \"\")\n\texpectParseError(t, \"/*!*/ @charset \\\"UTF-8\\\"; @import \\\"x\\\";\", \"\")\n\texpectParseError(t, \"/*!*/ @import \\\"x\\\"; @charset \\\"UTF-8\\\";\",\n\t\t\"<stdin>: WARNING: \\\"@charset\\\" must be the first rule in the file\\n\"+\n\t\t\t\"<stdin>: NOTE: This rule cannot come before a \\\"@charset\\\" rule\\n\")\n\n\texpectPrinted(t, \"@import \\\"x\\\";/*!*/\", \"@import \\\"x\\\";\\n/*!*/\\n\")\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\";/*!*/\", \"@charset \\\"UTF-8\\\";\\n/*!*/\\n\")\n\texpectPrinted(t, \"@import \\\"x\\\"; /*!*/\", \"@import \\\"x\\\";\\n/*!*/\\n\")\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\"; /*!*/\", \"@charset \\\"UTF-8\\\";\\n/*!*/\\n\")\n\n\texpectPrinted(t, \"/*! before */ a { --b: var(--c, /*!*/ /*!*/); } /*! after */\\n\", \"/*! before */\\na {\\n  --b: var(--c, );\\n}\\n/*! after */\\n\")\n}\n\nfunc TestAtKeyframes(t *testing.T) {\n\texpectPrinted(t, \"@keyframes {}\", \"@keyframes \\\"\\\" {\\n}\\n\")\n\texpectPrinted(t, \"@keyframes name{}\", \"@keyframes name {\\n}\\n\")\n\texpectPrinted(t, \"@keyframes name {}\", \"@keyframes name {\\n}\\n\")\n\texpectPrinted(t, \"@keyframes name{0%,50%{color:red}25%,75%{color:blue}}\",\n\t\t\"@keyframes name {\\n  0%, 50% {\\n    color: red;\\n  }\\n  25%, 75% {\\n    color: blue;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes name { 0%, 50% { color: red } 25%, 75% { color: blue } }\",\n\t\t\"@keyframes name {\\n  0%, 50% {\\n    color: red;\\n  }\\n  25%, 75% {\\n    color: blue;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes name{from{color:red}to{color:blue}}\",\n\t\t\"@keyframes name {\\n  from {\\n    color: red;\\n  }\\n  to {\\n    color: blue;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes name { from { color: red } to { color: blue } }\",\n\t\t\"@keyframes name {\\n  from {\\n    color: red;\\n  }\\n  to {\\n    color: blue;\\n  }\\n}\\n\")\n\n\texpectPrinted(t, \"@keyframes name { from { color: red } }\", \"@keyframes name {\\n  from {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes name { 100% { color: red } }\", \"@keyframes name {\\n  100% {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@keyframes name { from { color: red } }\", \"@keyframes name {\\n  0% {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@keyframes name { 100% { color: red } }\", \"@keyframes name {\\n  to {\\n    color: red;\\n  }\\n}\\n\")\n\n\texpectPrinted(t, \"@-webkit-keyframes name {}\", \"@-webkit-keyframes name {\\n}\\n\")\n\texpectPrinted(t, \"@-moz-keyframes name {}\", \"@-moz-keyframes name {\\n}\\n\")\n\texpectPrinted(t, \"@-ms-keyframes name {}\", \"@-ms-keyframes name {\\n}\\n\")\n\texpectPrinted(t, \"@-o-keyframes name {}\", \"@-o-keyframes name {\\n}\\n\")\n\n\texpectParseError(t, \"@keyframes {}\", \"<stdin>: WARNING: Expected identifier but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"@keyframes 'name' {}\", \"<stdin>: WARNING: Expected identifier but found \\\"'name'\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 0% 100% {} }\", \"<stdin>: WARNING: Expected \\\",\\\" but found \\\"100%\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { {} 0% {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 100 {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"100\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { into {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"into\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1,2 {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"1\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1, 2 {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"1\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1 ,2 {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"1\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1%, {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1%, x {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"x\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1%, ! {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"!\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { .x {} }\", \"<stdin>: WARNING: Expected percentage but found \\\".\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { {} }\", \"<stdin>: WARNING: Expected percentage but found \\\"{\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1% }\", \"<stdin>: WARNING: Expected \\\"{\\\" but found \\\"}\\\"\\n\")\n\texpectParseError(t, \"@keyframes name { 1%\", \"<stdin>: WARNING: Expected \\\"{\\\" but found end of file\\n\")\n\texpectParseError(t, \"@keyframes name { 1%,,2% {} }\", \"<stdin>: WARNING: Expected percentage but found \\\",\\\"\\n\")\n\texpectParseError(t, \"@keyframes name {\", \"<stdin>: WARNING: Expected \\\"}\\\" but found end of file\\n\")\n\n\texpectPrinted(t, \"@keyframes x { 1%, {} } @keyframes z { 1% {} }\", \"@keyframes x { 1%, {} }\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes x { .y {} } @keyframes z { 1% {} }\", \"@keyframes x { .y {} }\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes x { x {} } @keyframes z { 1% {} }\", \"@keyframes x {\\n  x {\\n  }\\n}\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes x { {} } @keyframes z { 1% {} }\", \"@keyframes x { {} }\\n@keyframes z {\\n  1% {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes x { 1% {}\", \"@keyframes x { 1% {} }\\n\")\n\texpectPrinted(t, \"@keyframes x { 1% {\", \"@keyframes x { 1% {} }\\n\")\n\texpectPrinted(t, \"@keyframes x { 1%\", \"@keyframes x { 1% }\\n\")\n\texpectPrinted(t, \"@keyframes x {\", \"@keyframes x {}\\n\")\n}\n\nfunc TestAtRuleValidation(t *testing.T) {\n\texpectParseError(t, \"a {} b {} c {} @charset \\\"UTF-8\\\";\",\n\t\t\"<stdin>: WARNING: \\\"@charset\\\" must be the first rule in the file\\n\"+\n\t\t\t\"<stdin>: NOTE: This rule cannot come before a \\\"@charset\\\" rule\\n\")\n\n\texpectParseError(t, \"a {} b {} c {} @import \\\"foo\\\";\",\n\t\t\"<stdin>: WARNING: All \\\"@import\\\" rules must come first\\n\"+\n\t\t\t\"<stdin>: NOTE: This rule cannot come before an \\\"@import\\\" rule\\n\")\n}\n\nfunc TestAtLayer(t *testing.T) {\n\texpectParseError(t, \"@layer a, b;\", \"\")\n\texpectParseError(t, \"@layer a {}\", \"\")\n\texpectParseError(t, \"@layer {}\", \"\")\n\texpectParseError(t, \"@layer a, b {}\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectParseError(t, \"@layer;\", \"<stdin>: WARNING: Unexpected \\\";\\\"\\n\")\n\texpectParseError(t, \"@layer , b {}\", \"<stdin>: WARNING: Unexpected \\\",\\\"\\n\")\n\texpectParseError(t, \"@layer a\", \"<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectParseError(t, \"@layer a { @layer b }\", \"<stdin>: WARNING: Expected \\\";\\\"\\n\")\n\texpectParseError(t, \"@layer a b\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n<stdin>: WARNING: Expected \\\";\\\" but found end of file\\n\")\n\texpectParseError(t, \"@layer a b ;\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n\")\n\texpectParseError(t, \"@layer a b {}\", \"<stdin>: WARNING: Unexpected \\\"b\\\"\\n\")\n\n\texpectPrinted(t, \"@layer a, b;\", \"@layer a, b;\\n\")\n\texpectPrinted(t, \"@layer a {}\", \"@layer a {\\n}\\n\")\n\texpectPrinted(t, \"@layer {}\", \"@layer {\\n}\\n\")\n\texpectPrinted(t, \"@layer foo { div { color: red } }\", \"@layer foo {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\n\t// Check semicolon error recovery\n\texpectPrinted(t, \"@layer\", \"@layer;\\n\")\n\texpectPrinted(t, \"@layer a\", \"@layer a;\\n\")\n\texpectPrinted(t, \"@layer a { @layer }\", \"@layer a {\\n  @layer;\\n}\\n\")\n\texpectPrinted(t, \"@layer a { @layer b }\", \"@layer a {\\n  @layer b;\\n}\\n\")\n\n\t// Check mangling\n\texpectPrintedMangle(t, \"@layer foo { div {} }\", \"@layer foo;\\n\")\n\texpectPrintedMangle(t, \"@layer foo { div { color: yellow } }\", \"@layer foo {\\n  div {\\n    color: #ff0;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@layer a { @layer b {} }\", \"@layer a.b;\\n\")\n\texpectPrintedMangle(t, \"@layer a { @layer {} }\", \"@layer a {\\n  @layer {\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@layer { @layer a {} }\", \"@layer {\\n  @layer a;\\n}\\n\")\n\texpectPrintedMangle(t, \"@layer a.b { @layer c.d {} }\", \"@layer a.b.c.d;\\n\")\n\texpectPrintedMangle(t, \"@layer a.b { @layer c.d {} @layer e.f {} }\", \"@layer a.b {\\n  @layer c.d;\\n  @layer e.f;\\n}\\n\")\n\texpectPrintedMangle(t, \"@layer a.b { @layer c.d { e { f: g } } }\", \"@layer a.b.c.d {\\n  e {\\n    f: g;\\n  }\\n}\\n\")\n\n\t// Invalid layer names should not be merged, since that causes the rule to\n\t// become invalid. It would be a change in semantics if we merged an invalid\n\t// rule with a valid rule since then the other valid rule would be invalid.\n\texpectParseError(t, \"@layer foo { @layer initial; }\", \"<stdin>: WARNING: \\\"initial\\\" cannot be used as a layer name\\n\")\n\texpectParseError(t, \"@layer foo { @layer inherit; }\", \"<stdin>: WARNING: \\\"inherit\\\" cannot be used as a layer name\\n\")\n\texpectParseError(t, \"@layer foo { @layer unset; }\", \"<stdin>: WARNING: \\\"unset\\\" cannot be used as a layer name\\n\")\n\texpectParseError(t, \"@layer initial { @layer foo; }\", \"<stdin>: WARNING: \\\"initial\\\" cannot be used as a layer name\\n\")\n\texpectParseError(t, \"@layer inherit { @layer foo; }\", \"<stdin>: WARNING: \\\"inherit\\\" cannot be used as a layer name\\n\")\n\texpectParseError(t, \"@layer unset { @layer foo; }\", \"<stdin>: WARNING: \\\"unset\\\" cannot be used as a layer name\\n\")\n\texpectPrintedMangle(t, \"@layer foo { @layer initial { a { b: c } } }\", \"@layer foo {\\n  @layer initial {\\n    a {\\n      b: c;\\n    }\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@layer initial { @layer foo { a { b: c } } }\", \"@layer initial {\\n  @layer foo {\\n    a {\\n      b: c;\\n    }\\n  }\\n}\\n\")\n\n\t// Order matters here. Do not drop the first \"@layer a;\" or the order will be changed.\n\texpectPrintedMangle(t, \"@layer a; @layer b; @layer a;\", \"@layer a;\\n@layer b;\\n@layer a;\\n\")\n\n\t// Validate ordering with \"@layer\" and \"@import\"\n\texpectParseError(t, \"@layer a; @import url(b);\", \"\")\n\texpectParseError(t, \"@layer a; @layer b; @import url(c);\", \"\")\n\texpectParseError(t, \"@layer a {} @import url(b);\",\n\t\t\"<stdin>: WARNING: All \\\"@import\\\" rules must come first\\n<stdin>: NOTE: This rule cannot come before an \\\"@import\\\" rule\\n\")\n\texpectParseError(t, \"@import url(a); @layer b; @import url(c);\",\n\t\t\"<stdin>: WARNING: All \\\"@import\\\" rules must come first\\n<stdin>: NOTE: This rule cannot come before an \\\"@import\\\" rule\\n\")\n\texpectParseError(t, \"@layer a; @charset \\\"UTF-8\\\";\",\n\t\t\"<stdin>: WARNING: \\\"@charset\\\" must be the first rule in the file\\n<stdin>: NOTE: This rule cannot come before a \\\"@charset\\\" rule\\n\")\n}\n\nfunc TestEmptyRule(t *testing.T) {\n\texpectPrinted(t, \"div {}\", \"div {\\n}\\n\")\n\texpectPrinted(t, \"@media screen {}\", \"@media screen {\\n}\\n\")\n\texpectPrinted(t, \"@page { @top-left {} }\", \"@page {\\n  @top-left {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes test { from {} to {} }\", \"@keyframes test {\\n  from {\\n  }\\n  to {\\n  }\\n}\\n\")\n\n\texpectPrintedMangle(t, \"div {}\", \"\")\n\texpectPrintedMangle(t, \"@media screen {}\", \"\")\n\texpectPrintedMangle(t, \"@page { @top-left {} }\", \"\")\n\texpectPrintedMangle(t, \"@keyframes test { from {} to {} }\", \"@keyframes test {\\n}\\n\")\n\n\texpectPrinted(t, \"$invalid {}\", \"$invalid {\\n}\\n\")\n\texpectPrinted(t, \"@page { color: red; @top-left {} }\", \"@page {\\n  color: red;\\n  @top-left {\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes test { from {} to { color: red } }\", \"@keyframes test {\\n  from {\\n  }\\n  to {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@keyframes test { from { color: red } to {} }\", \"@keyframes test {\\n  from {\\n    color: red;\\n  }\\n  to {\\n  }\\n}\\n\")\n\n\texpectPrintedMangle(t, \"$invalid {}\", \"$invalid {\\n}\\n\")\n\texpectPrintedMangle(t, \"@page { color: red; @top-left {} }\", \"@page {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"@keyframes test { from {} to { color: red } }\", \"@keyframes test {\\n  to {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@keyframes test { from { color: red } to {} }\", \"@keyframes test {\\n  0% {\\n    color: red;\\n  }\\n}\\n\")\n\n\texpectPrintedMangleMinify(t, \"$invalid {}\", \"$invalid{}\")\n\texpectPrintedMangleMinify(t, \"@page { color: red; @top-left {} }\", \"@page{color:red}\")\n\texpectPrintedMangleMinify(t, \"@keyframes test { from {} to { color: red } }\", \"@keyframes test{to{color:red}}\")\n\texpectPrintedMangleMinify(t, \"@keyframes test { from { color: red } to {} }\", \"@keyframes test{0%{color:red}}\")\n}\n\nfunc TestMarginAndPaddingAndInset(t *testing.T) {\n\tfor _, x := range []string{\"margin\", \"padding\", \"inset\"} {\n\t\txTop := x + \"-top\"\n\t\txRight := x + \"-right\"\n\t\txBottom := x + \"-bottom\"\n\t\txLeft := x + \"-left\"\n\t\tif x == \"inset\" {\n\t\t\txTop = \"top\"\n\t\t\txRight = \"right\"\n\t\t\txBottom = \"bottom\"\n\t\t\txLeft = \"left\"\n\t\t}\n\n\t\texpectPrinted(t, \"a { \"+x+\": 0 1px 0 1px }\", \"a {\\n  \"+x+\": 0 1px 0 1px;\\n}\\n\")\n\t\texpectPrinted(t, \"a { \"+x+\": 0 1px 0px 1px }\", \"a {\\n  \"+x+\": 0 1px 0px 1px;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 0px }\", \"a {\\n  \"+xTop+\": 0;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 0px }\", \"a {\\n  \"+xRight+\": 0;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 0px }\", \"a {\\n  \"+xBottom+\": 0;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 0px }\", \"a {\\n  \"+xLeft+\": 0;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px }\", \"a {\\n  \"+xTop+\": 1px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px }\", \"a {\\n  \"+xRight+\": 1px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px }\", \"a {\\n  \"+xBottom+\": 1px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px }\", \"a {\\n  \"+xLeft+\": 1px;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 0 0 }\", \"a {\\n  \"+x+\": 0 1px 0 0;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2px 1px }\", \"a {\\n  \"+x+\": 0 1px 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 0 1px }\", \"a {\\n  \"+x+\": 0 1px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 0 0 0 }\", \"a {\\n  \"+x+\": 0;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 0 0 0 !important }\", \"a {\\n  \"+x+\": 0 !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 0px 1px }\", \"a {\\n  \"+x+\": 0 1px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1 0px 1px }\", \"a {\\n  \"+x+\": 0 1 0px 1px;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xTop+\": 5px }\", \"a {\\n  \"+x+\": 5px 2px 3px 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xRight+\": 5px }\", \"a {\\n  \"+x+\": 1px 5px 3px 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xBottom+\": 5px }\", \"a {\\n  \"+x+\": 1px 2px 5px 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xLeft+\": 5px }\", \"a {\\n  \"+x+\": 1px 2px 3px 5px;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 5px; \"+x+\": 1px 2px 3px 4px }\", \"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": 2px }\", \"a {\\n  \"+xTop+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px; \"+xRight+\": 2px }\", \"a {\\n  \"+xRight+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px; \"+xBottom+\": 2px }\", \"a {\\n  \"+xBottom+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2px }\", \"a {\\n  \"+xLeft+\": 2px;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+x+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+x+\": 1px;\\n  \"+x+\": 2px !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xTop+\": 1px;\\n  \"+xTop+\": 2px !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px; \"+xRight+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xRight+\": 1px;\\n  \"+xRight+\": 2px !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px; \"+xBottom+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xBottom+\": 1px;\\n  \"+xBottom+\": 2px !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1px;\\n  \"+xLeft+\": 2px !important;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px !important; \"+x+\": 2px }\",\n\t\t\t\"a {\\n  \"+x+\": 1px !important;\\n  \"+x+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px !important; \"+xTop+\": 2px }\",\n\t\t\t\"a {\\n  \"+xTop+\": 1px !important;\\n  \"+xTop+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xRight+\": 1px !important; \"+xRight+\": 2px }\",\n\t\t\t\"a {\\n  \"+xRight+\": 1px !important;\\n  \"+xRight+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xBottom+\": 1px !important; \"+xBottom+\": 2px }\",\n\t\t\t\"a {\\n  \"+xBottom+\": 1px !important;\\n  \"+xBottom+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px !important; \"+xLeft+\": 2px }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1px !important;\\n  \"+xLeft+\": 2px;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": }\", \"a {\\n  \"+xTop+\": 1px;\\n  \"+xTop+\":;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xTop+\": 1px; \"+xTop+\": 2px 3px }\", \"a {\\n  \"+xTop+\": 1px;\\n  \"+xTop+\": 2px 3px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xLeft+\": -4px; \"+xRight+\": -2px }\", \"a {\\n  \"+x+\": 1px -2px 3px -4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px; \"+xTop+\": 5px }\", \"a {\\n  \"+x+\": 5px 2px 1px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+xTop+\": 5px }\", \"a {\\n  \"+x+\": 5px 1px 1px;\\n}\\n\")\n\n\t\t// This doesn't collapse because if the \"calc\" has an error it\n\t\t// will be ignored and the original rule will show through\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xRight+\": calc(1px + var(--x)) }\",\n\t\t\t\"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n  \"+xRight+\": calc(1px + var(--x));\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xRight+\": 2px; \"+xTop+\": 3px; \"+xBottom+\": 4px }\", \"a {\\n  \"+x+\": 3px 2px 4px 1px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px; \"+xRight+\": 5px !important }\",\n\t\t\t\"a {\\n  \"+x+\": 1px 2px 3px 4px;\\n  \"+xRight+\": 5px !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px 2px 3px 4px !important; \"+xRight+\": 5px }\",\n\t\t\t\"a {\\n  \"+x+\": 1px 2px 3px 4px !important;\\n  \"+xRight+\": 5px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px !important; \"+xRight+\": 2px; \"+xTop+\": 3px !important; \"+xBottom+\": 4px }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1px !important;\\n  \"+xRight+\": 2px;\\n  \"+xTop+\": 3px !important;\\n  \"+xBottom+\": 4px;\\n}\\n\")\n\n\t\t// This should not be changed because \"--x\" and \"--z\" could be empty\n\t\texpectPrintedMangle(t, \"a { \"+x+\": var(--x) var(--y) var(--z) var(--y) }\", \"a {\\n  \"+x+\": var(--x) var(--y) var(--z) var(--y);\\n}\\n\")\n\n\t\t// Don't merge different units\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+x+\": 2px; }\", \"a {\\n  \"+x+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 1px; \"+x+\": 2vw; }\", \"a {\\n  \"+x+\": 1px;\\n  \"+x+\": 2vw;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2px; }\", \"a {\\n  \"+xLeft+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1px; \"+xLeft+\": 2vw; }\", \"a {\\n  \"+xLeft+\": 1px;\\n  \"+xLeft+\": 2vw;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+x+\": 4px; }\", \"a {\\n  \"+x+\": 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+x+\": 4vw; }\", \"a {\\n  \"+x+\": 0 1px 2cm 3%;\\n  \"+x+\": 4vw;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+xLeft+\": 4px; }\", \"a {\\n  \"+x+\": 0 1px 2cm 4px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+x+\": 0 1px 2cm 3%; \"+xLeft+\": 4vw; }\", \"a {\\n  \"+x+\": 0 1px 2cm 3%;\\n  \"+xLeft+\": 4vw;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1Q; \"+xRight+\": 2Q; \"+xTop+\": 3Q; \"+xBottom+\": 4Q; }\", \"a {\\n  \"+x+\": 3Q 2Q 4Q 1Q;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+xLeft+\": 1Q; \"+xRight+\": 2Q; \"+xTop+\": 3Q; \"+xBottom+\": 0; }\",\n\t\t\t\"a {\\n  \"+xLeft+\": 1Q;\\n  \"+xRight+\": 2Q;\\n  \"+xTop+\": 3Q;\\n  \"+xBottom+\": 0;\\n}\\n\")\n\t}\n\n\t// \"auto\" is the only keyword allowed in a quad, and only for \"margin\" and \"inset\" not for \"padding\"\n\texpectPrintedMangle(t, \"a { margin: 1px auto 3px 4px; margin-left: auto }\", \"a {\\n  margin: 1px auto 3px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { inset: 1px auto 3px 4px; left: auto }\", \"a {\\n  inset: 1px auto 3px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { padding: 1px auto 3px 4px; padding-left: auto }\", \"a {\\n  padding: 1px auto 3px 4px;\\n  padding-left: auto;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { margin: auto; margin-left: 1px }\", \"a {\\n  margin: auto auto auto 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { inset: auto; left: 1px }\", \"a {\\n  inset: auto auto auto 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { padding: auto; padding-left: 1px }\", \"a {\\n  padding: auto;\\n  padding-left: 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { margin: inherit; margin-left: 1px }\", \"a {\\n  margin: inherit;\\n  margin-left: 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { inset: inherit; left: 1px }\", \"a {\\n  inset: inherit;\\n  left: 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { padding: inherit; padding-left: 1px }\", \"a {\\n  padding: inherit;\\n  padding-left: 1px;\\n}\\n\")\n\n\texpectPrintedLowerMangle(t, \"a { top: 0; right: 0; bottom: 0; left: 0; }\", \"a {\\n  top: 0;\\n  right: 0;\\n  bottom: 0;\\n  left: 0;\\n}\\n\")\n}\n\nfunc TestBorderRadius(t *testing.T) {\n\texpectPrinted(t, \"a { border-top-left-radius: 0 0 }\", \"a {\\n  border-top-left-radius: 0 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0 0 }\", \"a {\\n  border-top-left-radius: 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0 0px }\", \"a {\\n  border-top-left-radius: 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0 1px }\", \"a {\\n  border-top-left-radius: 0 1px;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0; border-radius: 1px }\", \"a {\\n  border-radius: 1px;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 3px 4px }\", \"a {\\n  border-radius: 1px 2px 3px 4px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 1px 3px }\", \"a {\\n  border-radius: 1px 2px 1px 3px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 3px 2px }\", \"a {\\n  border-radius: 1px 2px 3px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px 1px 2px }\", \"a {\\n  border-radius: 1px 2px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px 1px 1px 1px }\", \"a {\\n  border-radius: 1px;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 3px 4px }\", \"a {\\n  border-radius: 0 / 1px 2px 3px 4px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 1px 3px }\", \"a {\\n  border-radius: 0 / 1px 2px 1px 3px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 3px 2px }\", \"a {\\n  border-radius: 0 / 1px 2px 3px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px 1px 2px }\", \"a {\\n  border-radius: 0 / 1px 2px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 1px 1px 1px }\", \"a {\\n  border-radius: 0 / 1px;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { border-radius: 1px 2px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 2px 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 1px 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 0 0 / 3px 1px 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0/1px 2px; border-top-left-radius: 3px; }\", \"a {\\n  border-radius: 3px 0 0 / 3px 2px 1px;\\n}\\n\")\n\n\tfor _, x := range []string{\"\", \"-top-left\", \"-top-right\", \"-bottom-left\", \"-bottom-right\"} {\n\t\ty := \"border\" + x + \"-radius\"\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px; \"+y+\": 2px }\",\n\t\t\t\"a {\\n  \"+y+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px !important; \"+y+\": 2px }\",\n\t\t\t\"a {\\n  \"+y+\": 1px !important;\\n  \"+y+\": 2px;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px; \"+y+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+y+\": 1px;\\n  \"+y+\": 2px !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { \"+y+\": 1px !important; \"+y+\": 2px !important }\",\n\t\t\t\"a {\\n  \"+y+\": 2px !important;\\n}\\n\")\n\n\t\texpectPrintedMangle(t, \"a { border-radius: 1px; \"+y+\": 2px !important; }\",\n\t\t\t\"a {\\n  border-radius: 1px;\\n  \"+y+\": 2px !important;\\n}\\n\")\n\t\texpectPrintedMangle(t, \"a { border-radius: 1px !important; \"+y+\": 2px; }\",\n\t\t\t\"a {\\n  border-radius: 1px !important;\\n  \"+y+\": 2px;\\n}\\n\")\n\t}\n\n\texpectPrintedMangle(t, \"a { border-top-left-radius: ; border-radius: 1px }\",\n\t\t\"a {\\n  border-top-left-radius:;\\n  border-radius: 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1px; border-radius: / }\",\n\t\t\"a {\\n  border-top-left-radius: 1px;\\n  border-radius: /;\\n}\\n\")\n\n\texpectPrintedMangleMinify(t, \"a { border-radius: 1px 2px 3px 4px; border-top-right-radius: 5px; }\", \"a{border-radius:1px 5px 3px 4px}\")\n\texpectPrintedMangleMinify(t, \"a { border-radius: 1px 2px 3px 4px; border-top-right-radius: 5px 6px; }\", \"a{border-radius:1px 5px 3px 4px/1px 6px 3px 4px}\")\n\n\t// These should not be changed because \"--x\" and \"--z\" could be empty\n\texpectPrintedMangle(t, \"a { border-radius: var(--x) var(--y) var(--z) var(--y) }\", \"a {\\n  border-radius: var(--x) var(--y) var(--z) var(--y);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0 / var(--x) var(--y) var(--z) var(--y) }\", \"a {\\n  border-radius: 0 / var(--x) var(--y) var(--z) var(--y);\\n}\\n\")\n\n\t// \"inherit\" should not be merged\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-top-left-radius: 0 }\", \"a {\\n  border-radius: 0 1px 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: inherit; border-top-left-radius: 0 }\", \"a {\\n  border-radius: inherit;\\n  border-top-left-radius: 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0; border-top-left-radius: inherit }\", \"a {\\n  border-radius: 0;\\n  border-top-left-radius: inherit;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 0; border-radius: inherit }\", \"a {\\n  border-top-left-radius: 0;\\n  border-radius: inherit;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: inherit; border-radius: 0 }\", \"a {\\n  border-top-left-radius: inherit;\\n  border-radius: 0;\\n}\\n\")\n\n\t// Don't merge different units\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-radius: 2px; }\", \"a {\\n  border-radius: 2px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1px; border-top-left-radius: 2px; }\", \"a {\\n  border-radius: 2px 1px 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1px; border-radius: 2px; }\", \"a {\\n  border-radius: 2px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1px; border-top-left-radius: 2px; }\", \"a {\\n  border-top-left-radius: 2px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1rem; border-radius: 1vw; }\", \"a {\\n  border-radius: 1rem;\\n  border-radius: 1vw;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 1rem; border-top-left-radius: 1vw; }\", \"a {\\n  border-radius: 1rem;\\n  border-top-left-radius: 1vw;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1rem; border-radius: 1vw; }\", \"a {\\n  border-top-left-radius: 1rem;\\n  border-radius: 1vw;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-top-left-radius: 1rem; border-top-left-radius: 1vw; }\", \"a {\\n  border-top-left-radius: 1rem;\\n  border-top-left-radius: 1vw;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0; border-top-left-radius: 2px; }\", \"a {\\n  border-radius: 2px 0 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { border-radius: 0; border-top-left-radius: 2rem; }\", \"a {\\n  border-radius: 0;\\n  border-top-left-radius: 2rem;\\n}\\n\")\n}\n\nfunc TestBoxShadow(t *testing.T) {\n\texpectPrinted(t, \"a { box-shadow: inset 0px 0px 0px 0px black }\", \"a {\\n  box-shadow: inset 0px 0px 0px 0px black;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px 0px inset black }\", \"a {\\n  box-shadow: 0 0 inset #000;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px 0px black inset }\", \"a {\\n  box-shadow: 0 0 #000 inset;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: black 0px 0px 0px 0px inset }\", \"a {\\n  box-shadow: #000 0 0 inset;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: inset 0px 0px 0px 0px black }\", \"a {\\n  box-shadow: inset 0 0 #000;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: inset black 0px 0px 0px 0px }\", \"a {\\n  box-shadow: inset #000 0 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: black inset 0px 0px 0px 0px }\", \"a {\\n  box-shadow: #000 inset 0 0;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: yellow 1px 0px 0px 1px inset }\", \"a {\\n  box-shadow: #ff0 1px 0 0 1px inset;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: yellow 1px 0px 1px 0px inset }\", \"a {\\n  box-shadow: #ff0 1px 0 1px inset;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: rebeccapurple, yellow, black }\", \"a {\\n  box-shadow:\\n    #639,\\n    #ff0,\\n    #000;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px var(--foo) black }\", \"a {\\n  box-shadow: 0 0 0 var(--foo) #000;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: 0px 0px 0px 0px var(--foo) black }\", \"a {\\n  box-shadow: 0 0 0 0 var(--foo) #000;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: calc(1px + var(--foo)) 0px 0px 0px black }\", \"a {\\n  box-shadow: calc(1px + var(--foo)) 0 0 0 #000;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { box-shadow: inset 0px 0px 0px 0px 0px magenta; }\", \"a {\\n  box-shadow: inset 0 0 0 0 0 #f0f;\\n}\\n\")\n\texpectPrintedMangleMinify(t, \"a { box-shadow: rebeccapurple , yellow , black }\", \"a{box-shadow:#639,#ff0,#000}\")\n\texpectPrintedMangleMinify(t, \"a { box-shadow: rgb(255, 0, 17) 0 0 1 inset }\", \"a{box-shadow:#f01 0 0 1 inset}\")\n}\n\nfunc TestDeduplicateRules(t *testing.T) {\n\texpectPrinted(t, \"a { color: red; color: green; color: red }\",\n\t\t\"a {\\n  color: red;\\n  color: green;\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red; color: green; color: red }\",\n\t\t\"a {\\n  color: green;\\n  color: red;\\n}\\n\")\n\n\texpectPrinted(t, \"a { color: red } a { color: green } a { color: red }\",\n\t\t\"a {\\n  color: red;\\n}\\na {\\n  color: green;\\n}\\na {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a { color: green } a { color: red }\",\n\t\t\"a {\\n  color: green;\\n}\\na {\\n  color: red;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"@media screen { a { color: red } } @media screen { a { color: red } }\",\n\t\t\"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } } @media screen { & a { color: red } }\",\n\t\t\"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  & a {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } } @media screen { a[x] { color: red } }\",\n\t\t\"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  a[x] {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } } @media screen { a.x { color: red } }\",\n\t\t\"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  a.x {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } } @media screen { a#x { color: red } }\",\n\t\t\"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  a#x {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@media screen { a { color: red } } @media screen { a:x { color: red } }\",\n\t\t\"@media screen {\\n  a {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  a:x {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@media screen { a:x { color: red } } @media screen { a:x(y) { color: red } }\",\n\t\t\"@media screen {\\n  a:x {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  a:x(y) {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMangle(t, \"@media screen { a b { color: red } } @media screen { a + b { color: red } }\",\n\t\t\"@media screen {\\n  a b {\\n    color: red;\\n  }\\n}\\n@media screen {\\n  a + b {\\n    color: red;\\n  }\\n}\\n\")\n}\n\nfunc TestMangleTime(t *testing.T) {\n\texpectPrintedMangle(t, \"a { animation: b 1s }\", \"a {\\n  animation: b 1s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1.s }\", \"a {\\n  animation: b 1s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1.0s }\", \"a {\\n  animation: b 1s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1.02s }\", \"a {\\n  animation: b 1.02s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .1s }\", \"a {\\n  animation: b .1s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .01s }\", \"a {\\n  animation: b .01s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .001s }\", \"a {\\n  animation: b 1ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .0012s }\", \"a {\\n  animation: b 1.2ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b -.001s }\", \"a {\\n  animation: b -1ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b -.0012s }\", \"a {\\n  animation: b -1.2ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .0001s }\", \"a {\\n  animation: b .1ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .00012s }\", \"a {\\n  animation: b .12ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .000123s }\", \"a {\\n  animation: b .123ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .01S }\", \"a {\\n  animation: b .01S;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b .001S }\", \"a {\\n  animation: b 1ms;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { animation: b 1ms }\", \"a {\\n  animation: b 1ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 10ms }\", \"a {\\n  animation: b 10ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 100ms }\", \"a {\\n  animation: b .1s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 120ms }\", \"a {\\n  animation: b .12s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 123ms }\", \"a {\\n  animation: b 123ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1000ms }\", \"a {\\n  animation: b 1s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1200ms }\", \"a {\\n  animation: b 1.2s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1230ms }\", \"a {\\n  animation: b 1.23s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1234ms }\", \"a {\\n  animation: b 1234ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b -100ms }\", \"a {\\n  animation: b -.1s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b -120ms }\", \"a {\\n  animation: b -.12s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 120mS }\", \"a {\\n  animation: b .12s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 120Ms }\", \"a {\\n  animation: b .12s;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 123mS }\", \"a {\\n  animation: b 123mS;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 123Ms }\", \"a {\\n  animation: b 123Ms;\\n}\\n\")\n\n\t// Mangling times with exponents is not currently supported\n\texpectPrintedMangle(t, \"a { animation: b 1e3ms }\", \"a {\\n  animation: b 1e3ms;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { animation: b 1E3ms }\", \"a {\\n  animation: b 1E3ms;\\n}\\n\")\n}\n\nfunc TestCalc(t *testing.T) {\n\texpectParseError(t, \"a { b: calc(+(2)) }\", \"<stdin>: WARNING: \\\"+\\\" can only be used as an infix operator, not a prefix operator\\n\")\n\texpectParseError(t, \"a { b: calc(-(2)) }\", \"<stdin>: WARNING: \\\"-\\\" can only be used as an infix operator, not a prefix operator\\n\")\n\texpectParseError(t, \"a { b: calc(*(2)) }\", \"\")\n\texpectParseError(t, \"a { b: calc(/(2)) }\", \"\")\n\n\texpectParseError(t, \"a { b: calc(1 + 2) }\", \"\")\n\texpectParseError(t, \"a { b: calc(1 - 2) }\", \"\")\n\texpectParseError(t, \"a { b: calc(1 * 2) }\", \"\")\n\texpectParseError(t, \"a { b: calc(1 / 2) }\", \"\")\n\n\texpectParseError(t, \"a { b: calc(1+ 2) }\", \"<stdin>: WARNING: The \\\"+\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectParseError(t, \"a { b: calc(1- 2) }\", \"<stdin>: WARNING: The \\\"-\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectParseError(t, \"a { b: calc(1* 2) }\", \"\")\n\texpectParseError(t, \"a { b: calc(1/ 2) }\", \"\")\n\n\texpectParseError(t, \"a { b: calc(1 +2) }\", \"<stdin>: WARNING: The \\\"+\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectParseError(t, \"a { b: calc(1 -2) }\", \"<stdin>: WARNING: The \\\"-\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectParseError(t, \"a { b: calc(1 *2) }\", \"\")\n\texpectParseError(t, \"a { b: calc(1 /2) }\", \"\")\n\n\texpectParseError(t, \"a { b: calc(1 +(2)) }\", \"<stdin>: WARNING: The \\\"+\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectParseError(t, \"a { b: calc(1 -(2)) }\", \"<stdin>: WARNING: The \\\"-\\\" operator only works if there is whitespace on both sides\\n\")\n\texpectParseError(t, \"a { b: calc(1 *(2)) }\", \"\")\n\texpectParseError(t, \"a { b: calc(1 /(2)) }\", \"\")\n}\n\nfunc TestMinifyCalc(t *testing.T) {\n\texpectPrintedMangleMinify(t, \"a { b: calc(x + y) }\", \"a{b:calc(x + y)}\")\n\texpectPrintedMangleMinify(t, \"a { b: calc(x - y) }\", \"a{b:calc(x - y)}\")\n\texpectPrintedMangleMinify(t, \"a { b: calc(x * y) }\", \"a{b:calc(x*y)}\")\n\texpectPrintedMangleMinify(t, \"a { b: calc(x / y) }\", \"a{b:calc(x/y)}\")\n}\n\nfunc TestMangleCalc(t *testing.T) {\n\texpectPrintedMangle(t, \"a { b: calc(1) }\", \"a {\\n  b: 1;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc((1)) }\", \"a {\\n  b: 1;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(calc(1)) }\", \"a {\\n  b: 1;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x + y * z) }\", \"a {\\n  b: calc(x + y * z);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x * y + z) }\", \"a {\\n  b: calc(x * y + z);\\n}\\n\")\n\n\t// Test sum\n\texpectPrintedMangle(t, \"a { b: calc(2 + 3) }\", \"a {\\n  b: 5;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(6 - 2) }\", \"a {\\n  b: 4;\\n}\\n\")\n\n\t// Test product\n\texpectPrintedMangle(t, \"a { b: calc(2 * 3) }\", \"a {\\n  b: 6;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(6 / 2) }\", \"a {\\n  b: 3;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(2px * 3 + 4px * 5) }\", \"a {\\n  b: 26px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(2 * 3px + 4 * 5px) }\", \"a {\\n  b: 26px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(2px * 3 - 4px * 5) }\", \"a {\\n  b: -14px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(2 * 3px - 4 * 5px) }\", \"a {\\n  b: -14px;\\n}\\n\")\n\n\t// Test negation\n\texpectPrintedMangle(t, \"a { b: calc(x + 1) }\", \"a {\\n  b: calc(x + 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x - 1) }\", \"a {\\n  b: calc(x - 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x + -1) }\", \"a {\\n  b: calc(x - 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x - -1) }\", \"a {\\n  b: calc(x + 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(1 + x) }\", \"a {\\n  b: calc(1 + x);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(1 - x) }\", \"a {\\n  b: calc(1 - x);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(-1 + x) }\", \"a {\\n  b: calc(-1 + x);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(-1 - x) }\", \"a {\\n  b: calc(-1 - x);\\n}\\n\")\n\n\t// Test inversion\n\texpectPrintedMangle(t, \"a { b: calc(x * 4) }\", \"a {\\n  b: calc(x * 4);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x / 4) }\", \"a {\\n  b: calc(x / 4);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x * 0.25) }\", \"a {\\n  b: calc(x / 4);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(x / 0.25) }\", \"a {\\n  b: calc(x * 4);\\n}\\n\")\n\n\t// Test operator precedence\n\texpectPrintedMangle(t, \"a { b: calc((a + b) + c) }\", \"a {\\n  b: calc(a + b + c);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(a + (b + c)) }\", \"a {\\n  b: calc(a + b + c);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc((a - b) - c) }\", \"a {\\n  b: calc(a - b - c);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(a - (b - c)) }\", \"a {\\n  b: calc(a - (b - c));\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc((a * b) * c) }\", \"a {\\n  b: calc(a * b * c);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(a * (b * c)) }\", \"a {\\n  b: calc(a * b * c);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc((a / b) / c) }\", \"a {\\n  b: calc(a / b / c);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(a / (b / c)) }\", \"a {\\n  b: calc(a / (b / c));\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(a + b * c / d - e) }\", \"a {\\n  b: calc(a + b * c / d - e);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc((a + ((b * c) / d)) - e) }\", \"a {\\n  b: calc(a + b * c / d - e);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc((a + b) * c / (d - e)) }\", \"a {\\n  b: calc((a + b) * c / (d - e));\\n}\\n\")\n\n\t// Using \"var()\" should bail because it can expand to any number of tokens\n\texpectPrintedMangle(t, \"a { b: calc(1px - x + 2px) }\", \"a {\\n  b: calc(3px - x);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(1px - var(x) + 2px) }\", \"a {\\n  b: calc(1px - var(x) + 2px);\\n}\\n\")\n\n\t// Test values that can't be accurately represented as decimals\n\texpectPrintedMangle(t, \"a { b: calc(100% / 1) }\", \"a {\\n  b: 100%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 2) }\", \"a {\\n  b: 50%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 3) }\", \"a {\\n  b: calc(100% / 3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 4) }\", \"a {\\n  b: 25%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 5) }\", \"a {\\n  b: 20%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 6) }\", \"a {\\n  b: calc(100% / 6);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 7) }\", \"a {\\n  b: calc(100% / 7);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 8) }\", \"a {\\n  b: 12.5%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 9) }\", \"a {\\n  b: calc(100% / 9);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 10) }\", \"a {\\n  b: 10%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 100) }\", \"a {\\n  b: 1%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 1000) }\", \"a {\\n  b: .1%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 10000) }\", \"a {\\n  b: .01%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 100000) }\", \"a {\\n  b: .001%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / 1000000) }\", \"a {\\n  b: calc(100% / 1000000);\\n}\\n\") // This actually ends up as \"100% * (1 / 1000000)\" which is less precise\n\texpectPrintedMangle(t, \"a { b: calc(100% / -1000000) }\", \"a {\\n  b: calc(100% / -1000000);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(100% / -100000) }\", \"a {\\n  b: -.001%;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(3 * (2px + 1em / 7)) }\", \"a {\\n  b: calc(3 * (2px + 1em / 7));\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(3 * (2px + 1em / 8)) }\", \"a {\\n  b: calc(3 * (2px + .125em));\\n}\\n\")\n\n\t// Non-finite numbers\n\texpectPrintedMangle(t, \"a { b: calc(0px / 0) }\", \"a {\\n  b: calc(0px / 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / 0) }\", \"a {\\n  b: calc(1px / 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(-1px / 0) }\", \"a {\\n  b: calc(-1px / 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(nan) }\", \"a {\\n  b: calc(nan);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(infinity) }\", \"a {\\n  b: calc(infinity);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(-infinity) }\", \"a {\\n  b: calc(-infinity);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / nan) }\", \"a {\\n  b: calc(1px / nan);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / infinity) }\", \"a {\\n  b: 0px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { b: calc(1px / -infinity) }\", \"a {\\n  b: -0px;\\n}\\n\")\n}\n\nfunc TestTransform(t *testing.T) {\n\texpectPrintedMangle(t, \"a { transform: matrix(1, 0, 0, 1, 0, 0) }\", \"a {\\n  transform: scale(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: matrix(2, 0, 0, 1, 0, 0) }\", \"a {\\n  transform: scaleX(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: matrix(1, 0, 0, 2, 0, 0) }\", \"a {\\n  transform: scaleY(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: matrix(2, 0, 0, 3, 0, 0) }\", \"a {\\n  transform: scale(2, 3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: matrix(2, 0, 0, 2, 0, 0) }\", \"a {\\n  transform: scale(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: matrix(1, 0, 0, 1, 1, 2) }\", \"a {\\n  transform: matrix(1, 0, 0, 1, 1, 2);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: translate(0, 0) }\", \"a {\\n  transform: translate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(0px, 0px) }\", \"a {\\n  transform: translate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(0%, 0%) }\", \"a {\\n  transform: translate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 0) }\", \"a {\\n  transform: translate(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 0px) }\", \"a {\\n  transform: translate(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 0%) }\", \"a {\\n  transform: translate(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(0, 1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(0px, 1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(0%, 1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(1px, 2px) }\", \"a {\\n  transform: translate(1px, 2px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate(40%, 60%) }\", \"a {\\n  transform: translate(40%, 60%);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: translateX(0) }\", \"a {\\n  transform: translate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateX(0px) }\", \"a {\\n  transform: translate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateX(0%) }\", \"a {\\n  transform: translate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateX(1px) }\", \"a {\\n  transform: translate(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateX(50%) }\", \"a {\\n  transform: translate(50%);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: translateY(0) }\", \"a {\\n  transform: translateY(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateY(0px) }\", \"a {\\n  transform: translateY(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateY(0%) }\", \"a {\\n  transform: translateY(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateY(1px) }\", \"a {\\n  transform: translateY(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateY(50%) }\", \"a {\\n  transform: translateY(50%);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: scale(1) }\", \"a {\\n  transform: scale(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(100%) }\", \"a {\\n  transform: scale(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(10%) }\", \"a {\\n  transform: scale(.1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(99%) }\", \"a {\\n  transform: scale(99%);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(1, 1) }\", \"a {\\n  transform: scale(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(100%, 1) }\", \"a {\\n  transform: scale(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(10%, 0.1) }\", \"a {\\n  transform: scale(.1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(99%, 0.99) }\", \"a {\\n  transform: scale(99%, .99);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(60%, 40%) }\", \"a {\\n  transform: scale(.6, .4);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(3, 1) }\", \"a {\\n  transform: scaleX(3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(300%, 1) }\", \"a {\\n  transform: scaleX(3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(1, 3) }\", \"a {\\n  transform: scaleY(3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale(1, 300%) }\", \"a {\\n  transform: scaleY(3);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: scaleX(1) }\", \"a {\\n  transform: scaleX(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleX(2) }\", \"a {\\n  transform: scaleX(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleX(300%) }\", \"a {\\n  transform: scaleX(3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleX(99%) }\", \"a {\\n  transform: scaleX(99%);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: scaleY(1) }\", \"a {\\n  transform: scaleY(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleY(2) }\", \"a {\\n  transform: scaleY(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleY(300%) }\", \"a {\\n  transform: scaleY(3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleY(99%) }\", \"a {\\n  transform: scaleY(99%);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: rotate(0) }\", \"a {\\n  transform: rotate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotate(0deg) }\", \"a {\\n  transform: rotate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotate(1deg) }\", \"a {\\n  transform: rotate(1deg);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: skew(0) }\", \"a {\\n  transform: skew(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skew(0deg) }\", \"a {\\n  transform: skew(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg, 0) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg, 0deg) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skew(0, 1deg) }\", \"a {\\n  transform: skew(0, 1deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skew(0deg, 1deg) }\", \"a {\\n  transform: skew(0, 1deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skew(1deg, 2deg) }\", \"a {\\n  transform: skew(1deg, 2deg);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: skewX(0) }\", \"a {\\n  transform: skew(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skewX(0deg) }\", \"a {\\n  transform: skew(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skewX(1deg) }\", \"a {\\n  transform: skew(1deg);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: skewY(0) }\", \"a {\\n  transform: skewY(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skewY(0deg) }\", \"a {\\n  transform: skewY(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: skewY(1deg) }\", \"a {\\n  transform: skewY(1deg);\\n}\\n\")\n\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2) }\",\n\t\t\"a {\\n  transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 3, 4, 1) }\",\n\t\t\"a {\\n  transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 3, 4, 1);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: matrix3d(1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scaleZ(1);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(2, 1, 1);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(1, 2, 1);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(2, 2, 1);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(2, 3, 1);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scaleZ(2);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1) }\",\n\t\t\"a {\\n  transform: scale3d(1, 2, 3);\\n}\\n\")\n\texpectPrintedMangle(t,\n\t\t\"a { transform: matrix3d(2, 3, 0, 0, 4, 5, 0, 0, 0, 0, 1, 0, 6, 7, 0, 1) }\",\n\t\t\"a {\\n  transform: matrix3d(2, 3, 0, 0, 4, 5, 0, 0, 0, 0, 1, 0, 6, 7, 0, 1);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: translate3d(0, 0, 0) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0%, 0%, 0) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0px, 0px, 0px) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 0px, 0px) }\", \"a {\\n  transform: translate3d(1px, 0, 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0px, 1px, 0px) }\", \"a {\\n  transform: translate3d(0, 1px, 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0px, 0px, 1px) }\", \"a {\\n  transform: translateZ(1px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 2px, 3px) }\", \"a {\\n  transform: translate3d(1px, 2px, 3px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 0, 3px) }\", \"a {\\n  transform: translate3d(1px, 0, 3px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(0, 2px, 3px) }\", \"a {\\n  transform: translate3d(0, 2px, 3px);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(1px, 2px, 0px) }\", \"a {\\n  transform: translate3d(1px, 2px, 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translate3d(40%, 60%, 0px) }\", \"a {\\n  transform: translate3d(40%, 60%, 0);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: translateZ(0) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateZ(0px) }\", \"a {\\n  transform: translateZ(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: translateZ(1px) }\", \"a {\\n  transform: translateZ(1px);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 1, 1) }\", \"a {\\n  transform: scaleZ(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(2, 1, 1) }\", \"a {\\n  transform: scale3d(2, 1, 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 2, 1) }\", \"a {\\n  transform: scale3d(1, 2, 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 1, 2) }\", \"a {\\n  transform: scaleZ(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1, 2, 3) }\", \"a {\\n  transform: scale3d(1, 2, 3);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(2, 3, 1) }\", \"a {\\n  transform: scale3d(2, 3, 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(2, 2, 1) }\", \"a {\\n  transform: scale3d(2, 2, 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(3, 300%, 100.00%) }\", \"a {\\n  transform: scale3d(3, 3, 1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scale3d(1%, 2%, 3%) }\", \"a {\\n  transform: scale3d(1%, 2%, 3%);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: scaleZ(1) }\", \"a {\\n  transform: scaleZ(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(100%) }\", \"a {\\n  transform: scaleZ(1);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(2) }\", \"a {\\n  transform: scaleZ(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(200%) }\", \"a {\\n  transform: scaleZ(2);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: scaleZ(99%) }\", \"a {\\n  transform: scaleZ(99%);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 0, 0) }\", \"a {\\n  transform: rotate3d(0, 0, 0, 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 0, 0deg) }\", \"a {\\n  transform: rotate3d(0, 0, 0, 0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 0, 45deg) }\", \"a {\\n  transform: rotate3d(0, 0, 0, 45deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(1, 0, 0, 45deg) }\", \"a {\\n  transform: rotateX(45deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 1, 0, 45deg) }\", \"a {\\n  transform: rotateY(45deg);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotate3d(0, 0, 1, 45deg) }\", \"a {\\n  transform: rotate3d(0, 0, 1, 45deg);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: rotateX(0) }\", \"a {\\n  transform: rotateX(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotateX(0deg) }\", \"a {\\n  transform: rotateX(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotateX(1deg) }\", \"a {\\n  transform: rotateX(1deg);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: rotateY(0) }\", \"a {\\n  transform: rotateY(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotateY(0deg) }\", \"a {\\n  transform: rotateY(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotateY(1deg) }\", \"a {\\n  transform: rotateY(1deg);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: rotateZ(0) }\", \"a {\\n  transform: rotate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotateZ(0deg) }\", \"a {\\n  transform: rotate(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: rotateZ(1deg) }\", \"a {\\n  transform: rotate(1deg);\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { transform: perspective(0) }\", \"a {\\n  transform: perspective(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: perspective(0px) }\", \"a {\\n  transform: perspective(0);\\n}\\n\")\n\texpectPrintedMangle(t, \"a { transform: perspective(1px) }\", \"a {\\n  transform: perspective(1px);\\n}\\n\")\n}\n\nfunc TestMangleAlpha(t *testing.T) {\n\talphas := []string{\n\t\t\"0\", \".004\", \".008\", \".01\", \".016\", \".02\", \".024\", \".027\", \".03\", \".035\", \".04\", \".043\", \".047\", \".05\", \".055\", \".06\",\n\t\t\".063\", \".067\", \".07\", \".075\", \".08\", \".082\", \".086\", \".09\", \".094\", \".098\", \".1\", \".106\", \".11\", \".114\", \".118\", \".12\",\n\t\t\".125\", \".13\", \".133\", \".137\", \".14\", \".145\", \".15\", \".153\", \".157\", \".16\", \".165\", \".17\", \".173\", \".176\", \".18\", \".184\",\n\t\t\".19\", \".192\", \".196\", \".2\", \".204\", \".208\", \".21\", \".216\", \".22\", \".224\", \".227\", \".23\", \".235\", \".24\", \".243\", \".247\",\n\t\t\".25\", \".255\", \".26\", \".263\", \".267\", \".27\", \".275\", \".28\", \".282\", \".286\", \".29\", \".294\", \".298\", \".3\", \".306\", \".31\",\n\t\t\".314\", \".318\", \".32\", \".325\", \".33\", \".333\", \".337\", \".34\", \".345\", \".35\", \".353\", \".357\", \".36\", \".365\", \".37\", \".373\",\n\t\t\".376\", \".38\", \".384\", \".39\", \".392\", \".396\", \".4\", \".404\", \".408\", \".41\", \".416\", \".42\", \".424\", \".427\", \".43\", \".435\",\n\t\t\".44\", \".443\", \".447\", \".45\", \".455\", \".46\", \".463\", \".467\", \".47\", \".475\", \".48\", \".482\", \".486\", \".49\", \".494\", \".498\",\n\t\t\".5\", \".506\", \".51\", \".514\", \".518\", \".52\", \".525\", \".53\", \".533\", \".537\", \".54\", \".545\", \".55\", \".553\", \".557\", \".56\",\n\t\t\".565\", \".57\", \".573\", \".576\", \".58\", \".584\", \".59\", \".592\", \".596\", \".6\", \".604\", \".608\", \".61\", \".616\", \".62\", \".624\",\n\t\t\".627\", \".63\", \".635\", \".64\", \".643\", \".647\", \".65\", \".655\", \".66\", \".663\", \".667\", \".67\", \".675\", \".68\", \".682\", \".686\",\n\t\t\".69\", \".694\", \".698\", \".7\", \".706\", \".71\", \".714\", \".718\", \".72\", \".725\", \".73\", \".733\", \".737\", \".74\", \".745\", \".75\",\n\t\t\".753\", \".757\", \".76\", \".765\", \".77\", \".773\", \".776\", \".78\", \".784\", \".79\", \".792\", \".796\", \".8\", \".804\", \".808\", \".81\",\n\t\t\".816\", \".82\", \".824\", \".827\", \".83\", \".835\", \".84\", \".843\", \".847\", \".85\", \".855\", \".86\", \".863\", \".867\", \".87\", \".875\",\n\t\t\".88\", \".882\", \".886\", \".89\", \".894\", \".898\", \".9\", \".906\", \".91\", \".914\", \".918\", \".92\", \".925\", \".93\", \".933\", \".937\",\n\t\t\".94\", \".945\", \".95\", \".953\", \".957\", \".96\", \".965\", \".97\", \".973\", \".976\", \".98\", \".984\", \".99\", \".992\", \".996\",\n\t}\n\n\tfor i, alpha := range alphas {\n\t\texpectPrintedLowerMangle(t, fmt.Sprintf(\"a { color: #%08X }\", i), \"a {\\n  color: rgba(0, 0, 0, \"+alpha+\");\\n}\\n\")\n\t}\n\n\t// An alpha value of 100% does not use \"rgba(...)\"\n\texpectPrintedLowerMangle(t, \"a { color: #000000FF }\", \"a {\\n  color: #000;\\n}\\n\")\n}\n\nfunc TestMangleDuplicateSelectorRules(t *testing.T) {\n\texpectPrinted(t, \"a { color: red } b { color: red }\", \"a {\\n  color: red;\\n}\\nb {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } div {} b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: red } b { color: red }\", \"a,\\ndiv,\\nb {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: red } a { color: red }\", \"a,\\ndiv {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: blue } b { color: red }\", \"a {\\n  color: red;\\n}\\ndiv {\\n  color: #00f;\\n}\\nb {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } div { color: blue } a { color: red }\", \"div {\\n  color: #00f;\\n}\\na {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red; color: red } b { color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } b { color: red; color: red }\", \"a,\\nb {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } b { color: blue }\", \"a {\\n  color: red;\\n}\\nb {\\n  color: #00f;\\n}\\n\")\n\n\t// Do not merge duplicates if they are \"unsafe\"\n\texpectPrintedMangle(t, \"a { color: red } unknown { color: red }\", \"a {\\n  color: red;\\n}\\nunknown {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"unknown { color: red } a { color: red }\", \"unknown {\\n  color: red;\\n}\\na {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } video { color: red }\", \"a {\\n  color: red;\\n}\\nvideo {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"video { color: red } a { color: red }\", \"video {\\n  color: red;\\n}\\na {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a:last-child { color: red }\", \"a {\\n  color: red;\\n}\\na:last-child {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a[b=c i] { color: red }\", \"a {\\n  color: red;\\n}\\na[b=c i] {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } & { color: red }\", \"a {\\n  color: red;\\n}\\n& {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a + b { color: red }\", \"a {\\n  color: red;\\n}\\na + b {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a|b { color: red }\", \"a {\\n  color: red;\\n}\\na|b {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a::hover { color: red }\", \"a {\\n  color: red;\\n}\\na::hover {\\n  color: red;\\n}\\n\")\n\n\t// Still merge duplicates if they are \"safe\"\n\texpectPrintedMangle(t, \"a { color: red } a:hover { color: red }\", \"a,\\na:hover {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a[b=c] { color: red }\", \"a,\\na[b=c] {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a#id { color: red }\", \"a,\\na#id {\\n  color: red;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { color: red } a.cls { color: red }\", \"a,\\na.cls {\\n  color: red;\\n}\\n\")\n\n\t// Skip over comments\n\texpectPrintedMangle(t, \"c { color: green } a { color: red } /*!x*/ /*!y*/ b { color: blue }\", \"c {\\n  color: green;\\n}\\na {\\n  color: red;\\n}\\n/*!x*/\\n/*!y*/\\nb {\\n  color: #00f;\\n}\\n\")\n\texpectPrintedMangle(t, \"c { color: green } a { color: red } /*!x*/ /*!y*/ b { color: red }\", \"c {\\n  color: green;\\n}\\na,\\nb {\\n  color: red;\\n}\\n/*!x*/\\n/*!y*/\\n\")\n\texpectPrintedMangle(t, \"c { color: green } a { color: red } /*!x*/ /*!y*/ a { color: red }\", \"c {\\n  color: green;\\n}\\na {\\n  color: red;\\n}\\n/*!x*/\\n/*!y*/\\n\")\n}\n\nfunc TestFontWeight(t *testing.T) {\n\texpectPrintedMangle(t, \"a { font-weight: normal }\", \"a {\\n  font-weight: 400;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font-weight: bold }\", \"a {\\n  font-weight: 700;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font-weight: 400 }\", \"a {\\n  font-weight: 400;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font-weight: bolder }\", \"a {\\n  font-weight: bolder;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font-weight: var(--var) }\", \"a {\\n  font-weight: var(--var);\\n}\\n\")\n\n\texpectPrintedMangleMinify(t, \"a { font-weight: normal }\", \"a{font-weight:400}\")\n}\n\nfunc TestFontFamily(t *testing.T) {\n\texpectPrintedMangle(t, \"a {font-family: aaa }\", \"a {\\n  font-family: aaa;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: serif }\", \"a {\\n  font-family: serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'serif' }\", \"a {\\n  font-family: \\\"serif\\\";\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: aaa bbb, serif }\", \"a {\\n  font-family: aaa bbb, serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa', serif }\", \"a {\\n  font-family: aaa, serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: '\\\"', serif }\", \"a {\\n  font-family: '\\\"', serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa ', serif }\", \"a {\\n  font-family: \\\"aaa \\\", serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', serif }\", \"a {\\n  font-family: aaa bbb, serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', 'ccc ddd' }\", \"a {\\n  font-family: aaa bbb, ccc ddd;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa  bbb', serif }\", \"a {\\n  font-family: \\\"aaa  bbb\\\", serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa serif' }\", \"a {\\n  font-family: \\\"aaa serif\\\";\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', var(--var) }\", \"a {\\n  font-family: \\\"aaa bbb\\\", var(--var);\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', }\", \"a {\\n  font-family: \\\"aaa bbb\\\", ;\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: , 'aaa bbb' }\", \"a {\\n  font-family: , \\\"aaa bbb\\\";\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa',, 'bbb' }\", \"a {\\n  font-family:\\n    \\\"aaa\\\",,\\n    \\\"bbb\\\";\\n}\\n\")\n\texpectPrintedMangle(t, \"a {font-family: 'aaa bbb', x serif }\", \"a {\\n  font-family: \\\"aaa bbb\\\", x serif;\\n}\\n\")\n\n\texpectPrintedMangleMinify(t, \"a {font-family: 'aaa bbb', serif }\", \"a{font-family:aaa bbb,serif}\")\n\texpectPrintedMangleMinify(t, \"a {font-family: 'aaa bbb', 'ccc ddd' }\", \"a{font-family:aaa bbb,ccc ddd}\")\n}\n\nfunc TestFont(t *testing.T) {\n\texpectPrintedMangle(t, \"a { font: caption }\", \"a {\\n  font: caption;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: normal 1px }\", \"a {\\n  font: normal 1px;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: normal bold }\", \"a {\\n  font: normal bold;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: 1rem 'aaa bbb' }\", \"a {\\n  font: 1rem aaa bbb;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: 1rem/1.2 'aaa bbb' }\", \"a {\\n  font: 1rem/1.2 aaa bbb;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: normal 1rem 'aaa bbb' }\", \"a {\\n  font: 1rem aaa bbb;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: normal 1rem 'aaa bbb', serif }\", \"a {\\n  font: 1rem aaa bbb, serif;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: italic small-caps bold ultra-condensed 1rem/1.2 'aaa bbb' }\", \"a {\\n  font: italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: oblique 1px 'aaa bbb' }\", \"a {\\n  font: oblique 1px aaa bbb;\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: oblique 45deg 1px 'aaa bbb' }\", \"a {\\n  font: oblique 45deg 1px aaa bbb;\\n}\\n\")\n\n\texpectPrintedMangle(t, \"a { font: var(--var) 'aaa bbb' }\", \"a {\\n  font: var(--var) \\\"aaa bbb\\\";\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: normal var(--var) 'aaa bbb' }\", \"a {\\n  font: normal var(--var) \\\"aaa bbb\\\";\\n}\\n\")\n\texpectPrintedMangle(t, \"a { font: normal 1rem var(--var), 'aaa bbb' }\", \"a {\\n  font: normal 1rem var(--var), \\\"aaa bbb\\\";\\n}\\n\")\n\n\texpectPrintedMangleMinify(t, \"a { font: italic small-caps bold ultra-condensed 1rem/1.2 'aaa bbb' }\", \"a{font:italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb}\")\n\texpectPrintedMangleMinify(t, \"a { font: italic small-caps bold ultra-condensed 1rem / 1.2 'aaa bbb' }\", \"a{font:italic small-caps 700 ultra-condensed 1rem/1.2 aaa bbb}\")\n}\n\nfunc TestWarningUnexpectedCloseBrace(t *testing.T) {\n\texpectParseError(t, \".red {\\n  color: red;\\n}\\n}\\n.blue {\\n  color: blue;\\n}\\n.green {\\n color: green;\\n}\\n\",\n\t\t`<stdin>: WARNING: Unexpected \"}\"\n`)\n\texpectPrinted(t, \".red {\\n  color: red;\\n}\\n}\\n.blue {\\n  color: blue;\\n}\\n.green {\\n color: green;\\n}\\n\",\n\t\t`.red {\n  color: red;\n}\n} .blue {\n  color: blue;\n}\n.green {\n  color: green;\n}\n`)\n}\n\nfunc TestPropertyTypoWarning(t *testing.T) {\n\texpectParseError(t, \"a { z-idnex: 0 }\", \"<stdin>: WARNING: \\\"z-idnex\\\" is not a known CSS property\\nNOTE: Did you mean \\\"z-index\\\" instead?\\n\")\n\texpectParseError(t, \"a { x-index: 0 }\", \"<stdin>: WARNING: \\\"x-index\\\" is not a known CSS property\\nNOTE: Did you mean \\\"z-index\\\" instead?\\n\")\n\n\t// CSS variables should not be corrected\n\texpectParseError(t, \"a { --index: 0 }\", \"\")\n\n\t// Short names should not be corrected (\"alt\" is actually valid in WebKit, and should not become \"all\")\n\texpectParseError(t, \"a { alt: \\\"\\\" }\", \"\")\n}\n"
  },
  {
    "path": "lib/esbuild/css_parser/css_reduce_calc.go",
    "content": "package css_parser\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\nfunc (p *parser) tryToReduceCalcExpression(token css_ast.Token) css_ast.Token {\n\tif term := tryToParseCalcTerm(*token.Children); term != nil {\n\t\twhitespace := css_ast.WhitespaceBefore | css_ast.WhitespaceAfter\n\t\tif p.options.MinifyWhitespace {\n\t\t\twhitespace = 0\n\t\t}\n\t\tterm = term.partiallySimplify()\n\t\tif result, ok := term.convertToToken(whitespace); ok {\n\t\t\tif result.Kind == css_lexer.TOpenParen {\n\t\t\t\tresult.Kind = css_lexer.TFunction\n\t\t\t\tresult.Text = \"calc\"\n\t\t\t}\n\t\t\treturn result\n\t\t}\n\t}\n\treturn token\n}\n\n// See: https://www.w3.org/TR/css-values-4/#calc-internal\ntype calcTerm interface {\n\tconvertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool)\n\tpartiallySimplify() calcTerm\n}\n\ntype calcSum struct {\n\tterms []calcTerm\n}\n\ntype calcProduct struct {\n\tterms []calcTerm\n}\n\ntype calcNegate struct {\n\tterm calcTerm\n}\n\ntype calcInvert struct {\n\tterm calcTerm\n}\n\ntype calcNumeric struct {\n\tunit   string\n\tnumber float64\n}\n\ntype calcValue struct {\n\ttoken                css_ast.Token\n\tisInvalidPlusOrMinus bool\n}\n\nfunc floatToStringForCalc(a float64) (string, bool) {\n\t// Handle non-finite cases\n\tif math.IsNaN(a) || math.IsInf(a, 0) {\n\t\treturn \"\", false\n\t}\n\n\t// Print the number as a string\n\ttext := fmt.Sprintf(\"%.05f\", a)\n\tfor text[len(text)-1] == '0' {\n\t\ttext = text[:len(text)-1]\n\t}\n\tif text[len(text)-1] == '.' {\n\t\ttext = text[:len(text)-1]\n\t}\n\tif strings.HasPrefix(text, \"0.\") {\n\t\ttext = text[1:]\n\t} else if strings.HasPrefix(text, \"-0.\") {\n\t\ttext = \"-\" + text[2:]\n\t}\n\n\t// Bail if the number is not exactly represented\n\tif number, err := strconv.ParseFloat(text, 64); err != nil || number != a {\n\t\treturn \"\", false\n\t}\n\n\treturn text, true\n}\n\nfunc (c *calcSum) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttokens := make([]css_ast.Token, 0, len(c.terms)*2)\n\n\t// ALGORITHM DEVIATION: Avoid parenthesizing product nodes inside sum nodes\n\tif product, ok := c.terms[0].(*calcProduct); ok {\n\t\ttoken, ok := product.convertToToken(whitespace)\n\t\tif !ok {\n\t\t\treturn css_ast.Token{}, false\n\t\t}\n\t\ttokens = append(tokens, *token.Children...)\n\t} else {\n\t\ttoken, ok := c.terms[0].convertToToken(whitespace)\n\t\tif !ok {\n\t\t\treturn css_ast.Token{}, false\n\t\t}\n\t\ttokens = append(tokens, token)\n\t}\n\n\tfor _, term := range c.terms[1:] {\n\t\t// If child is a Negate node, append \" - \" to s, then serialize the Negate’s child and append the result to s.\n\t\tif negate, ok := term.(*calcNegate); ok {\n\t\t\ttoken, ok := negate.term.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, css_ast.Token{\n\t\t\t\tKind:       css_lexer.TDelimMinus,\n\t\t\t\tText:       \"-\",\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t}, token)\n\t\t\tcontinue\n\t\t}\n\n\t\t// If child is a negative numeric value, append \" - \" to s, then serialize the negation of child as normal and append the result to s.\n\t\tif numeric, ok := term.(*calcNumeric); ok && numeric.number < 0 {\n\t\t\tclone := *numeric\n\t\t\tclone.number = -clone.number\n\t\t\ttoken, ok := clone.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, css_ast.Token{\n\t\t\t\tKind:       css_lexer.TDelimMinus,\n\t\t\t\tText:       \"-\",\n\t\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t\t}, token)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Otherwise, append \" + \" to s, then serialize child and append the result to s.\n\t\ttokens = append(tokens, css_ast.Token{\n\t\t\tKind:       css_lexer.TDelimPlus,\n\t\t\tText:       \"+\",\n\t\t\tWhitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter,\n\t\t})\n\n\t\t// ALGORITHM DEVIATION: Avoid parenthesizing product nodes inside sum nodes\n\t\tif product, ok := term.(*calcProduct); ok {\n\t\t\ttoken, ok := product.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, *token.Children...)\n\t\t} else {\n\t\t\ttoken, ok := term.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, token)\n\t\t}\n\t}\n\n\treturn css_ast.Token{\n\t\tKind:     css_lexer.TOpenParen,\n\t\tText:     \"(\",\n\t\tChildren: &tokens,\n\t}, true\n}\n\nfunc (c *calcProduct) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttokens := make([]css_ast.Token, 0, len(c.terms)*2)\n\ttoken, ok := c.terms[0].convertToToken(whitespace)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\ttokens = append(tokens, token)\n\n\tfor _, term := range c.terms[1:] {\n\t\t// If child is an Invert node, append \" / \" to s, then serialize the Invert’s child and append the result to s.\n\t\tif invert, ok := term.(*calcInvert); ok {\n\t\t\ttoken, ok := invert.term.convertToToken(whitespace)\n\t\t\tif !ok {\n\t\t\t\treturn css_ast.Token{}, false\n\t\t\t}\n\t\t\ttokens = append(tokens, css_ast.Token{\n\t\t\t\tKind:       css_lexer.TDelimSlash,\n\t\t\t\tText:       \"/\",\n\t\t\t\tWhitespace: whitespace,\n\t\t\t}, token)\n\t\t\tcontinue\n\t\t}\n\n\t\t// Otherwise, append \" * \" to s, then serialize child and append the result to s.\n\t\ttoken, ok := term.convertToToken(whitespace)\n\t\tif !ok {\n\t\t\treturn css_ast.Token{}, false\n\t\t}\n\t\ttokens = append(tokens, css_ast.Token{\n\t\t\tKind:       css_lexer.TDelimAsterisk,\n\t\t\tText:       \"*\",\n\t\t\tWhitespace: whitespace,\n\t\t}, token)\n\t}\n\n\treturn css_ast.Token{\n\t\tKind:     css_lexer.TOpenParen,\n\t\tText:     \"(\",\n\t\tChildren: &tokens,\n\t}, true\n}\n\nfunc (c *calcNegate) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttoken, ok := c.term.convertToToken(whitespace)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\treturn css_ast.Token{\n\t\tKind: css_lexer.TOpenParen,\n\t\tText: \"(\",\n\t\tChildren: &[]css_ast.Token{\n\t\t\t{Kind: css_lexer.TNumber, Text: \"-1\"},\n\t\t\t{Kind: css_lexer.TDelimSlash, Text: \"*\", Whitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter},\n\t\t\ttoken,\n\t\t},\n\t}, true\n}\n\nfunc (c *calcInvert) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-serialize\n\ttoken, ok := c.term.convertToToken(whitespace)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\treturn css_ast.Token{\n\t\tKind: css_lexer.TOpenParen,\n\t\tText: \"(\",\n\t\tChildren: &[]css_ast.Token{\n\t\t\t{Kind: css_lexer.TNumber, Text: \"1\"},\n\t\t\t{Kind: css_lexer.TDelimSlash, Text: \"/\", Whitespace: css_ast.WhitespaceBefore | css_ast.WhitespaceAfter},\n\t\t\ttoken,\n\t\t},\n\t}, true\n}\n\nfunc (c *calcNumeric) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\ttext, ok := floatToStringForCalc(c.number)\n\tif !ok {\n\t\treturn css_ast.Token{}, false\n\t}\n\tif c.unit == \"\" {\n\t\treturn css_ast.Token{\n\t\t\tKind: css_lexer.TNumber,\n\t\t\tText: text,\n\t\t}, true\n\t} else if c.unit == \"%\" {\n\t\treturn css_ast.Token{\n\t\t\tKind: css_lexer.TPercentage,\n\t\t\tText: text + \"%\",\n\t\t}, true\n\t} else {\n\t\treturn css_ast.Token{\n\t\t\tKind:       css_lexer.TDimension,\n\t\t\tText:       text + c.unit,\n\t\t\tUnitOffset: uint16(len(text)),\n\t\t}, true\n\t}\n}\n\nfunc (c *calcValue) convertToToken(whitespace css_ast.WhitespaceFlags) (css_ast.Token, bool) {\n\tt := c.token\n\tt.Whitespace = 0\n\treturn t, true\n}\n\nfunc (c *calcSum) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\t// For each of root’s children that are Sum nodes, replace them with their children.\n\tterms := make([]calcTerm, 0, len(c.terms))\n\tfor _, term := range c.terms {\n\t\tterm = term.partiallySimplify()\n\t\tif sum, ok := term.(*calcSum); ok {\n\t\t\tterms = append(terms, sum.terms...)\n\t\t} else {\n\t\t\tterms = append(terms, term)\n\t\t}\n\t}\n\n\t// For each set of root’s children that are numeric values with identical units, remove\n\t// those children and replace them with a single numeric value containing the sum of the\n\t// removed nodes, and with the same unit. (E.g. combine numbers, combine percentages,\n\t// combine px values, etc.)\n\tfor i := 0; i < len(terms); i++ {\n\t\tterm := terms[i]\n\t\tif numeric, ok := term.(*calcNumeric); ok {\n\t\t\tend := i + 1\n\t\t\tfor j := end; j < len(terms); j++ {\n\t\t\t\tterm2 := terms[j]\n\t\t\t\tif numeric2, ok := term2.(*calcNumeric); ok && numeric2.unit == numeric.unit {\n\t\t\t\t\tnumeric.number += numeric2.number\n\t\t\t\t} else {\n\t\t\t\t\tterms[end] = term2\n\t\t\t\t\tend++\n\t\t\t\t}\n\t\t\t}\n\t\t\tterms = terms[:end]\n\t\t}\n\t}\n\n\t// If root has only a single child at this point, return the child.\n\tif len(terms) == 1 {\n\t\treturn terms[0]\n\t}\n\n\t// Otherwise, return root.\n\tc.terms = terms\n\treturn c\n}\n\nfunc (c *calcProduct) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\t// For each of root’s children that are Product nodes, replace them with their children.\n\tterms := make([]calcTerm, 0, len(c.terms))\n\tfor _, term := range c.terms {\n\t\tterm = term.partiallySimplify()\n\t\tif product, ok := term.(*calcProduct); ok {\n\t\t\tterms = append(terms, product.terms...)\n\t\t} else {\n\t\t\tterms = append(terms, term)\n\t\t}\n\t}\n\n\t// If root has multiple children that are numbers (not percentages or dimensions), remove\n\t// them and replace them with a single number containing the product of the removed nodes.\n\tfor i, term := range terms {\n\t\tif numeric, ok := term.(*calcNumeric); ok && numeric.unit == \"\" {\n\t\t\tend := i + 1\n\t\t\tfor j := end; j < len(terms); j++ {\n\t\t\t\tterm2 := terms[j]\n\t\t\t\tif numeric2, ok := term2.(*calcNumeric); ok && numeric2.unit == \"\" {\n\t\t\t\t\tnumeric.number *= numeric2.number\n\t\t\t\t} else {\n\t\t\t\t\tterms[end] = term2\n\t\t\t\t\tend++\n\t\t\t\t}\n\t\t\t}\n\t\t\tterms = terms[:end]\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// If root contains only numeric values and/or Invert nodes containing numeric values,\n\t// and multiplying the types of all the children (noting that the type of an Invert\n\t// node is the inverse of its child’s type) results in a type that matches any of the\n\t// types that a math function can resolve to, return the result of multiplying all the\n\t// values of the children (noting that the value of an Invert node is the reciprocal\n\t// of its child’s value), expressed in the result’s canonical unit.\n\tif len(terms) == 2 {\n\t\t// Right now, only handle the case of two numbers, one of which has no unit\n\t\tif first, ok := terms[0].(*calcNumeric); ok {\n\t\t\tif second, ok := terms[1].(*calcNumeric); ok {\n\t\t\t\tif first.unit == \"\" {\n\t\t\t\t\tsecond.number *= first.number\n\t\t\t\t\treturn second\n\t\t\t\t}\n\t\t\t\tif second.unit == \"\" {\n\t\t\t\t\tfirst.number *= second.number\n\t\t\t\t\treturn first\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// ALGORITHM DEVIATION: Divide instead of multiply if the reciprocal is shorter\n\tfor i := 1; i < len(terms); i++ {\n\t\tif numeric, ok := terms[i].(*calcNumeric); ok {\n\t\t\treciprocal := 1 / numeric.number\n\t\t\tif multiply, ok := floatToStringForCalc(numeric.number); ok {\n\t\t\t\tif divide, ok := floatToStringForCalc(reciprocal); ok && len(divide) < len(multiply) {\n\t\t\t\t\tnumeric.number = reciprocal\n\t\t\t\t\tterms[i] = &calcInvert{term: numeric}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// If root has only a single child at this point, return the child.\n\tif len(terms) == 1 {\n\t\treturn terms[0]\n\t}\n\n\t// Otherwise, return root.\n\tc.terms = terms\n\treturn c\n}\n\nfunc (c *calcNegate) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\tc.term = c.term.partiallySimplify()\n\n\t// If root’s child is a numeric value, return an equivalent numeric value, but with the value negated (0 - value).\n\tif numeric, ok := c.term.(*calcNumeric); ok {\n\t\tnumeric.number = -numeric.number\n\t\treturn numeric\n\t}\n\n\t// If root’s child is a Negate node, return the child’s child.\n\tif negate, ok := c.term.(*calcNegate); ok {\n\t\treturn negate.term\n\t}\n\n\treturn c\n}\n\nfunc (c *calcInvert) partiallySimplify() calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-simplification\n\n\tc.term = c.term.partiallySimplify()\n\n\t// If root’s child is a number (not a percentage or dimension) return the reciprocal of the child’s value.\n\tif numeric, ok := c.term.(*calcNumeric); ok && numeric.unit == \"\" {\n\t\tnumeric.number = 1 / numeric.number\n\t\treturn numeric\n\t}\n\n\t// If root’s child is an Invert node, return the child’s child.\n\tif invert, ok := c.term.(*calcInvert); ok {\n\t\treturn invert.term\n\t}\n\n\treturn c\n}\n\nfunc (c *calcNumeric) partiallySimplify() calcTerm {\n\treturn c\n}\n\nfunc (c *calcValue) partiallySimplify() calcTerm {\n\treturn c\n}\n\nfunc tryToParseCalcTerm(tokens []css_ast.Token) calcTerm {\n\t// Specification: https://www.w3.org/TR/css-values-4/#calc-internal\n\tterms := make([]calcTerm, len(tokens))\n\n\tfor i, token := range tokens {\n\t\tvar term calcTerm\n\t\tif token.Kind == css_lexer.TFunction && token.Text == \"var\" {\n\t\t\t// Using \"var()\" should bail because it can expand to any number of tokens\n\t\t\treturn nil\n\t\t} else if token.Kind == css_lexer.TOpenParen || (token.Kind == css_lexer.TFunction && token.Text == \"calc\") {\n\t\t\tterm = tryToParseCalcTerm(*token.Children)\n\t\t\tif term == nil {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TNumber {\n\t\t\tif number, err := strconv.ParseFloat(token.Text, 64); err == nil {\n\t\t\t\tterm = &calcNumeric{number: number}\n\t\t\t} else {\n\t\t\t\tterm = &calcValue{token: token}\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TPercentage {\n\t\t\tif number, err := strconv.ParseFloat(token.PercentageValue(), 64); err == nil {\n\t\t\t\tterm = &calcNumeric{number: number, unit: \"%\"}\n\t\t\t} else {\n\t\t\t\tterm = &calcValue{token: token}\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TDimension {\n\t\t\tif number, err := strconv.ParseFloat(token.DimensionValue(), 64); err == nil {\n\t\t\t\tterm = &calcNumeric{number: number, unit: token.DimensionUnit()}\n\t\t\t} else {\n\t\t\t\tterm = &calcValue{token: token}\n\t\t\t}\n\t\t} else if token.Kind == css_lexer.TIdent && strings.EqualFold(token.Text, \"Infinity\") {\n\t\t\tterm = &calcNumeric{number: math.Inf(1)}\n\t\t} else if token.Kind == css_lexer.TIdent && strings.EqualFold(token.Text, \"-Infinity\") {\n\t\t\tterm = &calcNumeric{number: math.Inf(-1)}\n\t\t} else if token.Kind == css_lexer.TIdent && strings.EqualFold(token.Text, \"NaN\") {\n\t\t\tterm = &calcNumeric{number: math.NaN()}\n\t\t} else {\n\t\t\tterm = &calcValue{\n\t\t\t\ttoken: token,\n\n\t\t\t\t// From the specification: \"In addition, whitespace is required on both sides of the\n\t\t\t\t// + and - operators. (The * and / operators can be used without white space around them.)\"\n\t\t\t\tisInvalidPlusOrMinus: i > 0 && i+1 < len(tokens) &&\n\t\t\t\t\t(token.Kind == css_lexer.TDelimPlus || token.Kind == css_lexer.TDelimMinus) &&\n\t\t\t\t\t(((token.Whitespace&css_ast.WhitespaceBefore) == 0 && (tokens[i-1].Whitespace&css_ast.WhitespaceAfter) == 0) ||\n\t\t\t\t\t\t(token.Whitespace&css_ast.WhitespaceAfter) == 0 && (tokens[i+1].Whitespace&css_ast.WhitespaceBefore) == 0),\n\t\t\t}\n\t\t}\n\t\tterms[i] = term\n\t}\n\n\t// Collect children into Product and Invert nodes\n\tfirst := 1\n\tfor first+1 < len(terms) {\n\t\t// If this is a \"*\" or \"/\" operator\n\t\tif value, ok := terms[first].(*calcValue); ok && (value.token.Kind == css_lexer.TDelimAsterisk || value.token.Kind == css_lexer.TDelimSlash) {\n\t\t\t// Scan over the run\n\t\t\tlast := first\n\t\t\tfor last+3 < len(terms) {\n\t\t\t\tif value, ok := terms[last+2].(*calcValue); ok && (value.token.Kind == css_lexer.TDelimAsterisk || value.token.Kind == css_lexer.TDelimSlash) {\n\t\t\t\t\tlast += 2\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Generate a node for the run\n\t\t\tproduct := calcProduct{terms: make([]calcTerm, (last-first)/2+2)}\n\t\t\tfor i := range product.terms {\n\t\t\t\tterm := terms[first+i*2-1]\n\t\t\t\tif i > 0 && terms[first+i*2-2].(*calcValue).token.Kind == css_lexer.TDelimSlash {\n\t\t\t\t\tterm = &calcInvert{term: term}\n\t\t\t\t}\n\t\t\t\tproduct.terms[i] = term\n\t\t\t}\n\n\t\t\t// Replace the run with a single node\n\t\t\tterms[first-1] = &product\n\t\t\tterms = append(terms[:first], terms[last+2:]...)\n\t\t\tcontinue\n\t\t}\n\n\t\tfirst++\n\t}\n\n\t// Collect children into Sum and Negate nodes\n\tfirst = 1\n\tfor first+1 < len(terms) {\n\t\t// If this is a \"+\" or \"-\" operator\n\t\tif value, ok := terms[first].(*calcValue); ok && !value.isInvalidPlusOrMinus &&\n\t\t\t(value.token.Kind == css_lexer.TDelimPlus || value.token.Kind == css_lexer.TDelimMinus) {\n\t\t\t// Scan over the run\n\t\t\tlast := first\n\t\t\tfor last+3 < len(terms) {\n\t\t\t\tif value, ok := terms[last+2].(*calcValue); ok && !value.isInvalidPlusOrMinus &&\n\t\t\t\t\t(value.token.Kind == css_lexer.TDelimPlus || value.token.Kind == css_lexer.TDelimMinus) {\n\t\t\t\t\tlast += 2\n\t\t\t\t} else {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Generate a node for the run\n\t\t\tsum := calcSum{terms: make([]calcTerm, (last-first)/2+2)}\n\t\t\tfor i := range sum.terms {\n\t\t\t\tterm := terms[first+i*2-1]\n\t\t\t\tif i > 0 && terms[first+i*2-2].(*calcValue).token.Kind == css_lexer.TDelimMinus {\n\t\t\t\t\tterm = &calcNegate{term: term}\n\t\t\t\t}\n\t\t\t\tsum.terms[i] = term\n\t\t\t}\n\n\t\t\t// Replace the run with a single node\n\t\t\tterms[first-1] = &sum\n\t\t\tterms = append(terms[:first], terms[last+2:]...)\n\t\t\tcontinue\n\t\t}\n\n\t\tfirst++\n\t}\n\n\t// This only succeeds if everything reduces to a single term\n\tif len(terms) == 1 {\n\t\treturn terms[0]\n\t}\n\treturn nil\n}\n"
  },
  {
    "path": "lib/esbuild/css_printer/astro_features.go",
    "content": "package css_printer\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n)\n\nfunc (p *printer) printScopedSelector() bool {\n\tvar str string\n\tif p.options.ScopeStrategy == ScopeStrategyWhere {\n\t\tstr = fmt.Sprintf(\":where(.astro-%s)\", p.options.Scope)\n\t} else if p.options.ScopeStrategy == ScopeStrategyAttribute {\n\t\tstr = fmt.Sprintf(\"[data-astro-cid-%s]\", p.options.Scope)\n\t} else {\n\t\tstr = fmt.Sprintf(\".astro-%s\", p.options.Scope)\n\t}\n\tp.print(str)\n\treturn true\n}\n\nfunc (p *printer) printCompoundSelector(sel css_ast.CompoundSelector, isFirst bool, isLast bool, shouldScope bool) {\n\tscoped := false\n\tif !isFirst && sel.Combinator == \"\" {\n\t\t// A space is required in between compound selectors if there is no\n\t\t// combinator in the middle. It's fine to convert \"a + b\" into \"a+b\"\n\t\t// but not to convert \"a b\" into \"ab\".\n\t\tp.print(\" \")\n\t}\n\n\tif sel.NestingSelector == css_ast.NestingSelectorPrefix {\n\t\tp.print(\"&\")\n\t\tscoped = true\n\t}\n\n\tif sel.Combinator != \"\" {\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.print(sel.Combinator)\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t}\n\n\tif sel.TypeSelector != nil {\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif len(sel.SubclassSelectors) > 0 {\n\t\t\t// There is no chance of whitespace before a subclass selector or pseudo\n\t\t\t// class selector\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\t\tif sel.TypeSelector.Name.Text == \"*\" {\n\t\t\tif shouldScope {\n\t\t\t\tscoped = p.printScopedSelector()\n\t\t\t} else {\n\t\t\t\tp.printNamespacedName(*sel.TypeSelector, whitespace)\n\t\t\t}\n\t\t} else {\n\t\t\tp.printNamespacedName(*sel.TypeSelector, whitespace)\n\t\t}\n\t\tswitch sel.TypeSelector.Name.Text {\n\t\tcase \"body\", \"html\":\n\t\t\tscoped = true\n\t\tdefault:\n\t\t\tif !scoped && shouldScope {\n\t\t\t\tscoped = p.printScopedSelector()\n\t\t\t}\n\t\t}\n\t}\n\n\tvar onlyPseudoSubclassSelectors *bool\n\n\tfor i, sub := range sel.SubclassSelectors {\n\t\twhitespace := mayNeedWhitespaceAfter\n\n\t\t// There is no chance of whitespace between subclass selectors\n\t\tif i+1 < len(sel.SubclassSelectors) {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\n\t\tswitch s := sub.(type) {\n\t\tcase *css_ast.SSHash:\n\t\t\tp.print(\"#\")\n\n\t\t\t// This deliberately does not use identHash. From the specification:\n\t\t\t// \"In <id-selector>, the <hash-token>'s value must be an identifier.\"\n\t\t\tp.printIdent(s.Name, identNormal, whitespace)\n\t\t\tif !scoped && shouldScope {\n\t\t\t\tscoped = p.printScopedSelector()\n\t\t\t}\n\n\t\tcase *css_ast.SSClass:\n\t\t\tp.print(\".\")\n\t\t\tp.printIdent(s.Name, identNormal, whitespace)\n\t\t\tif !scoped && shouldScope {\n\t\t\t\tscoped = p.printScopedSelector()\n\t\t\t}\n\n\t\tcase *css_ast.SSAttribute:\n\t\t\tif !scoped && shouldScope {\n\t\t\t\tscoped = p.printScopedSelector()\n\t\t\t}\n\t\t\tp.print(\"[\")\n\t\t\tp.printNamespacedName(s.NamespacedName, canDiscardWhitespaceAfter)\n\t\t\tif s.MatcherOp != \"\" {\n\t\t\t\tp.print(s.MatcherOp)\n\t\t\t\tprintAsIdent := false\n\n\t\t\t\t// Print the value as an identifier if it's possible\n\t\t\t\tif css_lexer.WouldStartIdentifierWithoutEscapes(s.MatcherValue) {\n\t\t\t\t\tprintAsIdent = true\n\t\t\t\t\tfor _, c := range s.MatcherValue {\n\t\t\t\t\t\tif !css_lexer.IsNameContinue(c) {\n\t\t\t\t\t\t\tprintAsIdent = false\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif printAsIdent {\n\t\t\t\t\tp.printIdent(s.MatcherValue, identNormal, canDiscardWhitespaceAfter)\n\t\t\t\t} else {\n\t\t\t\t\tp.printQuoted(s.MatcherValue)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif s.MatcherModifier != 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t\tp.print(string(rune(s.MatcherModifier)))\n\t\t\t}\n\t\t\tp.print(\"]\")\n\n\t\tcase *css_ast.SSPseudoClass:\n\t\t\tif sel.TypeSelector == nil && onlyPseudoSubclassSelectors == nil {\n\t\t\t\tonlyPseudoSubclassSelectors = new(bool)\n\t\t\t\t*onlyPseudoSubclassSelectors = true\n\t\t\t\tfor _, ss := range sel.SubclassSelectors {\n\t\t\t\t\t_, ok := ss.(*css_ast.SSPseudoClass)\n\t\t\t\t\tif !ok {\n\t\t\t\t\t\t*onlyPseudoSubclassSelectors = false\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If there is no type selector and all subclass selectors are pseudo\n\t\t\t// selectors, we need to add the scope before the first pseudo selector.\n\t\t\tif !scoped && shouldScope && sel.TypeSelector == nil && *onlyPseudoSubclassSelectors && i == 0 && s.Name != \"global\" && s.Name != \"root\" {\n\t\t\t\tscoped = p.printScopedSelector()\n\t\t\t}\n\t\t\tp.printPseudoClassSelector(*s, whitespace)\n\t\t\tif s.Name == \"global\" || s.Name == \"root\" {\n\t\t\t\tscoped = true\n\t\t\t}\n\t\t}\n\t}\n\n\tif !scoped && shouldScope {\n\t\tp.printScopedSelector()\n\t}\n\n\t// It doesn't matter where the \"&\" goes since all non-prefix cases are\n\t// treated the same. This just always puts it as a suffix for simplicity.\n\tif sel.NestingSelector == css_ast.NestingSelectorPresentButNotPrefix {\n\t\tp.print(\"&\")\n\t}\n}\n\nfunc (p *printer) printPseudoClassSelector(pseudo css_ast.SSPseudoClass, whitespace trailingWhitespace) {\n\tif pseudo.Name == \"global\" {\n\t\tif len(pseudo.Args) > 0 {\n\t\t\tp.printTokens(pseudo.Args, printTokensOpts{})\n\t\t} else {\n\t\t\tp.printIdent(pseudo.Name, identNormal, whitespace)\n\t\t}\n\t} else {\n\t\tif pseudo.IsElement {\n\t\t\tp.print(\"::\")\n\t\t} else {\n\t\t\tp.print(\":\")\n\t\t}\n\t\tif len(pseudo.Args) > 0 {\n\t\t\tp.printIdent(pseudo.Name, identNormal, canDiscardWhitespaceAfter)\n\t\t\tp.print(\"(\")\n\t\t\tp.printTokens(pseudo.Args, printTokensOpts{})\n\t\t\tp.print(\")\")\n\t\t} else {\n\t\t\tp.printIdent(pseudo.Name, identNormal, whitespace)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "lib/esbuild/css_printer/css_printer.go",
    "content": "package css_printer\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"unicode/utf8\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/config\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_ast\"\n\t\"github.com/withastro/compiler/lib/esbuild/css_lexer\"\n\t\"github.com/withastro/compiler/lib/esbuild/helpers\"\n\t\"github.com/withastro/compiler/lib/esbuild/sourcemap\"\n)\n\nconst quoteForURL byte = 0\n\ntype printer struct {\n\toptions                Options\n\timportRecords          []ast.ImportRecord\n\tcss                    []byte\n\textractedLegalComments map[string]bool\n\tbuilder                sourcemap.ChunkBuilder\n\tselectorRuleDepth      int\n}\n\ntype ScopeStrategy uint8\n\nconst (\n\tScopeStrategyWhere ScopeStrategy = iota\n\tScopeStrategyClass\n\tScopeStrategyAttribute ScopeStrategy = iota\n)\n\ntype Options struct {\n\t// This will be present if the input file had a source map. In that case we\n\t// want to map all the way back to the original input file(s).\n\tInputSourceMap *sourcemap.SourceMap\n\n\t// If we're writing out a source map, this table of line start indices lets\n\t// us do binary search on to figure out what line a given AST node came from\n\tLineOffsetTables []sourcemap.LineOffsetTable\n\n\tMinifyWhitespace  bool\n\tASCIIOnly         bool\n\tAddSourceMappings bool\n\tLegalComments     config.LegalComments\n\tScope             string\n\tScopeStrategy     ScopeStrategy\n}\n\ntype PrintResult struct {\n\tCSS                    []byte\n\tExtractedLegalComments map[string]bool\n\tSourceMapChunk         sourcemap.Chunk\n}\n\nfunc Print(tree css_ast.AST, options Options) PrintResult {\n\tp := printer{\n\t\toptions:       options,\n\t\timportRecords: tree.ImportRecords,\n\t\tbuilder:       sourcemap.MakeChunkBuilder(options.InputSourceMap, options.LineOffsetTables),\n\t}\n\tfor _, rule := range tree.Rules {\n\t\tp.printRule(rule, 0, false)\n\t}\n\treturn PrintResult{\n\t\tCSS:                    p.css,\n\t\tExtractedLegalComments: p.extractedLegalComments,\n\t\tSourceMapChunk:         p.builder.GenerateChunk(p.css),\n\t}\n}\n\nfunc (p *printer) printRule(rule css_ast.Rule, indent int32, omitTrailingSemicolon bool) {\n\tif r, ok := rule.Data.(*css_ast.RComment); ok {\n\t\tswitch p.options.LegalComments {\n\t\tcase config.LegalCommentsNone:\n\t\t\treturn\n\n\t\tcase config.LegalCommentsEndOfFile,\n\t\t\tconfig.LegalCommentsLinkedWithComment,\n\t\t\tconfig.LegalCommentsExternalWithoutComment:\n\t\t\tif p.extractedLegalComments == nil {\n\t\t\t\tp.extractedLegalComments = make(map[string]bool)\n\t\t\t}\n\t\t\tp.extractedLegalComments[r.Text] = true\n\t\t\treturn\n\t\t}\n\t}\n\n\tif p.options.AddSourceMappings {\n\t\tp.builder.AddSourceMapping(rule.Loc, p.css)\n\t}\n\n\tif !p.options.MinifyWhitespace {\n\t\tp.printIndent(indent)\n\t}\n\n\tswitch r := rule.Data.(type) {\n\tcase *css_ast.RAtCharset:\n\t\t// It's not valid to remove the space in between these two tokens\n\t\tp.print(\"@charset \")\n\n\t\t// It's not valid to print the string with single quotes\n\t\tp.printQuotedWithQuote(r.Encoding, '\"')\n\t\tp.print(\";\")\n\n\tcase *css_ast.RAtImport:\n\t\tif p.options.MinifyWhitespace {\n\t\t\tp.print(\"@import\")\n\t\t} else {\n\t\t\tp.print(\"@import \")\n\t\t}\n\t\tp.printQuoted(p.importRecords[r.ImportRecordIndex].Path.Text)\n\t\tp.printTokens(r.ImportConditions, printTokensOpts{})\n\t\tp.print(\";\")\n\n\tcase *css_ast.RAtKeyframes:\n\t\tp.print(\"@\")\n\t\tp.printIdent(r.AtToken, identNormal, mayNeedWhitespaceAfter)\n\t\tp.print(\" \")\n\t\tif r.Name == \"\" {\n\t\t\tp.print(\"\\\"\\\"\")\n\t\t} else {\n\t\t\tp.printIdent(r.Name, identNormal, canDiscardWhitespaceAfter)\n\t\t}\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tif p.options.MinifyWhitespace {\n\t\t\tp.print(\"{\")\n\t\t} else {\n\t\t\tp.print(\"{\\n\")\n\t\t}\n\t\tindent++\n\t\tfor _, block := range r.Blocks {\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.printIndent(indent)\n\t\t\t}\n\t\t\tfor i, sel := range block.Selectors {\n\t\t\t\tif i > 0 {\n\t\t\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\t\t\tp.print(\",\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.print(\", \")\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tp.print(sel)\n\t\t\t}\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.printRuleBlock(block.Rules, indent)\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\"\\n\")\n\t\t\t}\n\t\t}\n\t\tindent--\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.printIndent(indent)\n\t\t}\n\t\tp.print(\"}\")\n\n\tcase *css_ast.RKnownAt:\n\t\tp.print(\"@\")\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif len(r.Prelude) == 0 {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\t\tp.printIdent(r.AtToken, identNormal, whitespace)\n\t\tif (!p.options.MinifyWhitespace && r.Rules != nil) || len(r.Prelude) > 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printTokens(r.Prelude, printTokensOpts{})\n\t\tif r.Rules == nil {\n\t\t\tp.print(\";\")\n\t\t} else {\n\t\t\tif !p.options.MinifyWhitespace && len(r.Prelude) > 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.printRuleBlock(r.Rules, indent)\n\t\t}\n\n\tcase *css_ast.RUnknownAt:\n\t\tp.print(\"@\")\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif len(r.Prelude) == 0 {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\t\tp.printIdent(r.AtToken, identNormal, whitespace)\n\t\tif (!p.options.MinifyWhitespace && r.Block != nil) || len(r.Prelude) > 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printTokens(r.Prelude, printTokensOpts{})\n\t\tif !p.options.MinifyWhitespace && r.Block != nil && len(r.Prelude) > 0 {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tif r.Block == nil {\n\t\t\tp.print(\";\")\n\t\t} else {\n\t\t\tp.printTokens(r.Block, printTokensOpts{})\n\t\t}\n\n\tcase *css_ast.RSelector:\n\t\tif r.HasAtNest {\n\t\t\tp.print(\"@nest\")\n\t\t}\n\t\tp.printComplexSelectors(r.Selectors, indent, r.HasAtNest)\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.selectorRuleDepth++\n\t\tp.printRuleBlock(r.Rules, indent)\n\t\tp.selectorRuleDepth--\n\n\tcase *css_ast.RQualified:\n\t\thasWhitespaceAfter := p.printTokens(r.Prelude, printTokensOpts{})\n\t\tif !hasWhitespaceAfter && !p.options.MinifyWhitespace {\n\t\t\tp.print(\" \")\n\t\t}\n\t\tp.printRuleBlock(r.Rules, indent)\n\n\tcase *css_ast.RDeclaration:\n\t\tp.printIdent(r.KeyText, identNormal, canDiscardWhitespaceAfter)\n\t\tp.print(\":\")\n\t\thasWhitespaceAfter := p.printTokens(r.Value, printTokensOpts{\n\t\t\tindent:        indent,\n\t\t\tisDeclaration: true,\n\t\t})\n\t\tif r.Important {\n\t\t\tif !hasWhitespaceAfter && !p.options.MinifyWhitespace && len(r.Value) > 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.print(\"!important\")\n\t\t}\n\t\tif !omitTrailingSemicolon {\n\t\t\tp.print(\";\")\n\t\t}\n\n\tcase *css_ast.RBadDeclaration:\n\t\tp.printTokens(r.Tokens, printTokensOpts{})\n\t\tif !omitTrailingSemicolon {\n\t\t\tp.print(\";\")\n\t\t}\n\n\tcase *css_ast.RComment:\n\t\tp.printIndentedComment(indent, r.Text)\n\n\tcase *css_ast.RAtLayer:\n\t\tp.print(\"@layer\")\n\t\tfor i, parts := range r.Names {\n\t\t\tif i == 0 {\n\t\t\t\tp.print(\" \")\n\t\t\t} else if !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\", \")\n\t\t\t} else {\n\t\t\t\tp.print(\",\")\n\t\t\t}\n\t\t\tp.print(strings.Join(parts, \".\"))\n\t\t}\n\t\tif r.Rules == nil {\n\t\t\tp.print(\";\")\n\t\t} else {\n\t\t\tif !p.options.MinifyWhitespace {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t\tp.printRuleBlock(r.Rules, indent)\n\t\t}\n\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n\n\tif !p.options.MinifyWhitespace {\n\t\tp.print(\"\\n\")\n\t}\n}\n\nfunc (p *printer) printIndentedComment(indent int32, text string) {\n\t// Avoid generating a comment containing the character sequence \"</style\"\n\ttext = helpers.EscapeClosingTag(text, \"/style\")\n\n\t// Re-indent multi-line comments\n\tfor {\n\t\tnewline := strings.IndexByte(text, '\\n')\n\t\tif newline == -1 {\n\t\t\tbreak\n\t\t}\n\t\tp.print(text[:newline+1])\n\t\tif !p.options.MinifyWhitespace {\n\t\t\tp.printIndent(indent)\n\t\t}\n\t\ttext = text[newline+1:]\n\t}\n\tp.print(text)\n}\n\nfunc (p *printer) printRuleBlock(rules []css_ast.Rule, indent int32) {\n\tif p.options.MinifyWhitespace {\n\t\tp.print(\"{\")\n\t} else {\n\t\tp.print(\"{\\n\")\n\t}\n\n\tfor i, decl := range rules {\n\t\tomitTrailingSemicolon := p.options.MinifyWhitespace && i+1 == len(rules)\n\t\tp.printRule(decl, indent+1, omitTrailingSemicolon)\n\t}\n\n\tif !p.options.MinifyWhitespace {\n\t\tp.printIndent(indent)\n\t}\n\tp.print(\"}\")\n}\n\nfunc (p *printer) printComplexSelectors(selectors []css_ast.ComplexSelector, indent int32, hasAtNest bool) {\n\tfor i, complex := range selectors {\n\t\tif i > 0 {\n\t\t\tif p.options.MinifyWhitespace {\n\t\t\t\tp.print(\",\")\n\t\t\t} else {\n\t\t\t\tp.print(\",\\n\")\n\t\t\t\tp.printIndent(indent)\n\t\t\t}\n\t\t}\n\n\t\tfor j, compound := range complex.Selectors {\n\t\t\tshouldScope := true\n\t\t\tif p.selectorRuleDepth > 0 {\n\t\t\t\thasNestingSelector := false\n\t\t\t\tfor _, part := range complex.Selectors {\n\t\t\t\t\tif part.NestingSelector != css_ast.NestingSelectorNone {\n\t\t\t\t\t\thasNestingSelector = true\n\t\t\t\t\t\tbreak\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif !hasNestingSelector {\n\t\t\t\t\tshouldScope = false\n\t\t\t\t}\n\t\t\t}\n\t\t\tp.printCompoundSelector(compound, (!hasAtNest || i != 0) && j == 0, j+1 == len(complex.Selectors), shouldScope)\n\t\t}\n\t}\n}\n\nfunc (p *printer) printNamespacedName(nsName css_ast.NamespacedName, whitespace trailingWhitespace) {\n\tif nsName.NamespacePrefix != nil {\n\t\tswitch nsName.NamespacePrefix.Kind {\n\t\tcase css_lexer.TIdent:\n\t\t\tp.printIdent(nsName.NamespacePrefix.Text, identNormal, canDiscardWhitespaceAfter)\n\t\tcase css_lexer.TDelimAsterisk:\n\t\t\tp.print(\"*\")\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\n\t\tp.print(\"|\")\n\t}\n\n\tswitch nsName.Name.Kind {\n\tcase css_lexer.TIdent:\n\t\tp.printIdent(nsName.Name.Text, identNormal, whitespace)\n\tcase css_lexer.TDelimAsterisk:\n\t\tp.print(\"*\")\n\tcase css_lexer.TDelimAmpersand:\n\t\tp.print(\"&\")\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (p *printer) print(text string) {\n\tp.css = append(p.css, text...)\n}\n\nfunc bestQuoteCharForString(text string, forURL bool) byte {\n\tforURLCost := 0\n\tsingleCost := 2\n\tdoubleCost := 2\n\n\tfor _, c := range text {\n\t\tswitch c {\n\t\tcase '\\'':\n\t\t\tforURLCost++\n\t\t\tsingleCost++\n\n\t\tcase '\"':\n\t\t\tforURLCost++\n\t\t\tdoubleCost++\n\n\t\tcase '(', ')', ' ', '\\t':\n\t\t\tforURLCost++\n\n\t\tcase '\\\\', '\\n', '\\r', '\\f':\n\t\t\tforURLCost++\n\t\t\tsingleCost++\n\t\t\tdoubleCost++\n\t\t}\n\t}\n\n\t// Quotes can sometimes be omitted for URL tokens\n\tif forURL && forURLCost < singleCost && forURLCost < doubleCost {\n\t\treturn quoteForURL\n\t}\n\n\t// Prefer double quotes to single quotes if there is no cost difference\n\tif singleCost < doubleCost {\n\t\treturn '\\''\n\t}\n\n\treturn '\"'\n}\n\nfunc (p *printer) printQuoted(text string) {\n\tp.printQuotedWithQuote(text, bestQuoteCharForString(text, false))\n}\n\ntype escapeKind uint8\n\nconst (\n\tescapeNone escapeKind = iota\n\tescapeBackslash\n\tescapeHex\n)\n\nfunc (p *printer) printWithEscape(c rune, escape escapeKind, remainingText string, mayNeedWhitespaceAfter bool) {\n\tvar temp [utf8.UTFMax]byte\n\n\tif escape == escapeBackslash && ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {\n\t\t// Hexadecimal characters cannot use a plain backslash escape\n\t\tescape = escapeHex\n\t}\n\n\tswitch escape {\n\tcase escapeNone:\n\t\twidth := utf8.EncodeRune(temp[:], c)\n\t\tp.css = append(p.css, temp[:width]...)\n\n\tcase escapeBackslash:\n\t\tp.css = append(p.css, '\\\\')\n\t\twidth := utf8.EncodeRune(temp[:], c)\n\t\tp.css = append(p.css, temp[:width]...)\n\n\tcase escapeHex:\n\t\ttext := fmt.Sprintf(\"\\\\%x\", c)\n\t\tp.css = append(p.css, text...)\n\n\t\t// Make sure the next character is not interpreted as part of the escape sequence\n\t\tif len(text) < 1+6 {\n\t\t\tif next := utf8.RuneLen(c); next < len(remainingText) {\n\t\t\t\tc = rune(remainingText[next])\n\t\t\t\tif c == ' ' || c == '\\t' || (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') {\n\t\t\t\t\tp.css = append(p.css, ' ')\n\t\t\t\t}\n\t\t\t} else if mayNeedWhitespaceAfter {\n\t\t\t\t// If the last character is a hexadecimal escape, print a space afterwards\n\t\t\t\t// for the escape sequence to consume. That way we're sure it won't\n\t\t\t\t// accidentally consume a semantically significant space afterward.\n\t\t\t\tp.css = append(p.css, ' ')\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (p *printer) printQuotedWithQuote(text string, quote byte) {\n\tif quote != quoteForURL {\n\t\tp.css = append(p.css, quote)\n\t}\n\n\tfor i, c := range text {\n\t\tescape := escapeNone\n\n\t\tswitch c {\n\t\tcase '\\x00', '\\r', '\\n', '\\f':\n\t\t\t// Use a hexadecimal escape for characters that would be invalid escapes\n\t\t\tescape = escapeHex\n\n\t\tcase '\\\\', rune(quote):\n\t\t\tescape = escapeBackslash\n\n\t\tcase '(', ')', ' ', '\\t', '\"', '\\'':\n\t\t\t// These characters must be escaped in URL tokens\n\t\t\tif quote == quoteForURL {\n\t\t\t\tescape = escapeBackslash\n\t\t\t}\n\n\t\tcase '/':\n\t\t\t// Avoid generating the sequence \"</style\" in CSS code\n\t\t\tif i >= 1 && text[i-1] == '<' && i+6 <= len(text) && strings.EqualFold(text[i+1:i+6], \"style\") {\n\t\t\t\tescape = escapeBackslash\n\t\t\t}\n\n\t\tdefault:\n\t\t\tif (p.options.ASCIIOnly && c >= 0x80) || c == '\\uFEFF' {\n\t\t\t\tescape = escapeHex\n\t\t\t}\n\t\t}\n\n\t\tp.printWithEscape(c, escape, text[i:], false)\n\t}\n\n\tif quote != quoteForURL {\n\t\tp.css = append(p.css, quote)\n\t}\n}\n\ntype identMode uint8\n\nconst (\n\tidentNormal identMode = iota\n\tidentHash\n\tidentDimensionUnit\n)\n\ntype trailingWhitespace uint8\n\nconst (\n\tmayNeedWhitespaceAfter trailingWhitespace = iota\n\tcanDiscardWhitespaceAfter\n)\n\nfunc (p *printer) printIdent(text string, mode identMode, whitespace trailingWhitespace) {\n\tfor i, c := range text {\n\t\tescape := escapeNone\n\n\t\tif p.options.ASCIIOnly && c >= 0x80 {\n\t\t\tescape = escapeHex\n\t\t} else if c == '\\r' || c == '\\n' || c == '\\f' || c == '\\uFEFF' {\n\t\t\t// Use a hexadecimal escape for characters that would be invalid escapes\n\t\t\tescape = escapeHex\n\t\t} else {\n\t\t\t// Escape non-identifier characters\n\t\t\tif !css_lexer.IsNameContinue(c) {\n\t\t\t\tescape = escapeBackslash\n\t\t\t}\n\n\t\t\t// Special escape behavior for the first character\n\t\t\tif i == 0 {\n\t\t\t\tswitch mode {\n\t\t\t\tcase identNormal:\n\t\t\t\t\tif !css_lexer.WouldStartIdentifierWithoutEscapes(text) {\n\t\t\t\t\t\tescape = escapeBackslash\n\t\t\t\t\t}\n\n\t\t\t\tcase identDimensionUnit:\n\t\t\t\t\tif !css_lexer.WouldStartIdentifierWithoutEscapes(text) {\n\t\t\t\t\t\tescape = escapeBackslash\n\t\t\t\t\t} else if c >= '0' && c <= '9' {\n\t\t\t\t\t\t// Unit: \"2x\"\n\t\t\t\t\t\tescape = escapeHex\n\t\t\t\t\t} else if c == 'e' || c == 'E' {\n\t\t\t\t\t\tif len(text) >= 2 && text[1] >= '0' && text[1] <= '9' {\n\t\t\t\t\t\t\t// Unit: \"e2x\"\n\t\t\t\t\t\t\tescape = escapeBackslash\n\t\t\t\t\t\t} else if len(text) >= 3 && text[1] == '-' && text[2] >= '0' && text[2] <= '9' {\n\t\t\t\t\t\t\t// Unit: \"e-2x\"\n\t\t\t\t\t\t\tescape = escapeBackslash\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If the last character is a hexadecimal escape, print a space afterwards\n\t\t// for the escape sequence to consume. That way we're sure it won't\n\t\t// accidentally consume a semantically significant space afterward.\n\t\tmayNeedWhitespaceAfter := whitespace == mayNeedWhitespaceAfter && escape != escapeNone && i+utf8.RuneLen(c) == len(text)\n\t\tp.printWithEscape(c, escape, text[i:], mayNeedWhitespaceAfter)\n\t}\n}\n\nfunc (p *printer) printIndent(indent int32) {\n\tfor i, n := 0, int(indent); i < n; i++ {\n\t\tp.css = append(p.css, \"  \"...)\n\t}\n}\n\ntype printTokensOpts struct {\n\tindent        int32\n\tisDeclaration bool\n}\n\nfunc (p *printer) printTokens(tokens []css_ast.Token, opts printTokensOpts) bool {\n\thasWhitespaceAfter := len(tokens) > 0 && (tokens[0].Whitespace&css_ast.WhitespaceBefore) != 0\n\n\t// Pretty-print long comma-separated declarations of 3 or more items\n\tisMultiLineValue := false\n\tif !p.options.MinifyWhitespace && opts.isDeclaration {\n\t\tcommaCount := 0\n\t\tfor _, t := range tokens {\n\t\t\tif t.Kind == css_lexer.TComma {\n\t\t\t\tcommaCount++\n\t\t\t}\n\t\t}\n\t\tisMultiLineValue = commaCount >= 2\n\t}\n\n\tfor i, t := range tokens {\n\t\tif t.Kind == css_lexer.TWhitespace {\n\t\t\thasWhitespaceAfter = true\n\t\t\tcontinue\n\t\t}\n\t\tif hasWhitespaceAfter {\n\t\t\tif isMultiLineValue && (i == 0 || tokens[i-1].Kind == css_lexer.TComma) {\n\t\t\t\tp.print(\"\\n\")\n\t\t\t\tp.printIndent(opts.indent + 1)\n\t\t\t} else {\n\t\t\t\tp.print(\" \")\n\t\t\t}\n\t\t}\n\t\thasWhitespaceAfter = (t.Whitespace&css_ast.WhitespaceAfter) != 0 ||\n\t\t\t(i+1 < len(tokens) && (tokens[i+1].Whitespace&css_ast.WhitespaceBefore) != 0)\n\n\t\twhitespace := mayNeedWhitespaceAfter\n\t\tif !hasWhitespaceAfter {\n\t\t\twhitespace = canDiscardWhitespaceAfter\n\t\t}\n\n\t\tswitch t.Kind {\n\t\tcase css_lexer.TIdent:\n\t\t\tp.printIdent(t.Text, identNormal, whitespace)\n\n\t\tcase css_lexer.TFunction:\n\t\t\tp.printIdent(t.Text, identNormal, whitespace)\n\t\t\tp.print(\"(\")\n\n\t\tcase css_lexer.TDimension:\n\t\t\tp.print(t.DimensionValue())\n\t\t\tp.printIdent(t.DimensionUnit(), identDimensionUnit, whitespace)\n\n\t\tcase css_lexer.TAtKeyword:\n\t\t\tp.print(\"@\")\n\t\t\tp.printIdent(t.Text, identNormal, whitespace)\n\n\t\tcase css_lexer.THash:\n\t\t\tp.print(\"#\")\n\t\t\tp.printIdent(t.Text, identHash, whitespace)\n\n\t\tcase css_lexer.TString:\n\t\t\tp.printQuoted(t.Text)\n\n\t\tcase css_lexer.TURL:\n\t\t\ttext := p.importRecords[t.ImportRecordIndex].Path.Text\n\t\t\tp.print(\"url(\")\n\t\t\tp.printQuotedWithQuote(text, bestQuoteCharForString(text, true))\n\t\t\tp.print(\")\")\n\n\t\tdefault:\n\t\t\tp.print(t.Text)\n\t\t}\n\n\t\tif t.Children != nil {\n\t\t\tp.printTokens(*t.Children, printTokensOpts{})\n\n\t\t\tswitch t.Kind {\n\t\t\tcase css_lexer.TFunction:\n\t\t\t\tp.print(\")\")\n\n\t\t\tcase css_lexer.TOpenParen:\n\t\t\t\tp.print(\")\")\n\n\t\t\tcase css_lexer.TOpenBrace:\n\t\t\t\tp.print(\"}\")\n\n\t\t\tcase css_lexer.TOpenBracket:\n\t\t\t\tp.print(\"]\")\n\t\t\t}\n\t\t}\n\t}\n\tif hasWhitespaceAfter {\n\t\tp.print(\" \")\n\t}\n\treturn hasWhitespaceAfter\n}\n"
  },
  {
    "path": "lib/esbuild/css_printer/css_printer_test.go",
    "content": "package css_printer\n\nimport (\n\t\"testing\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/css_parser\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n\t\"github.com/withastro/compiler/lib/esbuild/test\"\n)\n\nfunc assertEqual(t *testing.T, a interface{}, b interface{}) {\n\tt.Helper()\n\tif a != b {\n\t\tt.Fatalf(\"%s != %s\", a, b)\n\t}\n}\n\nfunc expectPrintedCommon(t *testing.T, name string, contents string, expected string, options Options) {\n\tt.Helper()\n\tt.Run(name, func(t *testing.T) {\n\t\tt.Helper()\n\t\tlog := logger.NewDeferLog(logger.DeferLogNoVerboseOrDebug)\n\t\ttree := css_parser.Parse(log, test.SourceForTest(contents), css_parser.Options{\n\t\t\tMinifyWhitespace: options.MinifyWhitespace,\n\t\t})\n\t\tmsgs := log.Done()\n\t\ttext := \"\"\n\t\tfor _, msg := range msgs {\n\t\t\tif msg.Kind == logger.Error {\n\t\t\t\ttext += msg.String(logger.OutputOptions{}, logger.TerminalInfo{})\n\t\t\t}\n\t\t}\n\t\tassertEqual(t, text, \"\")\n\t\tresult := Print(tree, options)\n\t\tassertEqual(t, string(result.CSS), expected)\n\t})\n}\n\nfunc expectPrinted(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents, contents, expected, Options{})\n}\n\nfunc expectPrintedMinify(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [minified]\", contents, expected, Options{\n\t\tMinifyWhitespace: true,\n\t})\n}\n\nfunc expectPrintedASCII(t *testing.T, contents string, expected string) {\n\tt.Helper()\n\texpectPrintedCommon(t, contents+\" [ascii]\", contents, expected, Options{\n\t\tASCIIOnly: true,\n\t})\n}\n\nfunc expectPrintedString(t *testing.T, stringValue string, expected string) {\n\tt.Helper()\n\tt.Run(stringValue, func(t *testing.T) {\n\t\tt.Helper()\n\t\tp := printer{}\n\t\tp.printQuoted(stringValue)\n\t\tassertEqual(t, string(p.css), expected)\n\t})\n}\n\nfunc TestStringQuote(t *testing.T) {\n\texpectPrintedString(t, \"\", \"\\\"\\\"\")\n\texpectPrintedString(t, \"foo\", \"\\\"foo\\\"\")\n\texpectPrintedString(t, \"f\\\"o\", \"'f\\\"o'\")\n\texpectPrintedString(t, \"f'\\\"'o\", \"\\\"f'\\\\\\\"'o\\\"\")\n\texpectPrintedString(t, \"f\\\"'\\\"o\", \"'f\\\"\\\\'\\\"o'\")\n\texpectPrintedString(t, \"f\\\\o\", \"\\\"f\\\\\\\\o\\\"\")\n\texpectPrintedString(t, \"f\\ro\", \"\\\"f\\\\do\\\"\")\n\texpectPrintedString(t, \"f\\no\", \"\\\"f\\\\ao\\\"\")\n\texpectPrintedString(t, \"f\\fo\", \"\\\"f\\\\co\\\"\")\n\texpectPrintedString(t, \"f\\r\\no\", \"\\\"f\\\\d\\\\ao\\\"\")\n\texpectPrintedString(t, \"f\\r0\", \"\\\"f\\\\d 0\\\"\")\n\texpectPrintedString(t, \"f\\n0\", \"\\\"f\\\\a 0\\\"\")\n\texpectPrintedString(t, \"f\\n \", \"\\\"f\\\\a  \\\"\")\n\texpectPrintedString(t, \"f\\n\\t\", \"\\\"f\\\\a \\t\\\"\")\n\texpectPrintedString(t, \"f\\nf\", \"\\\"f\\\\a f\\\"\")\n\texpectPrintedString(t, \"f\\nF\", \"\\\"f\\\\a F\\\"\")\n\texpectPrintedString(t, \"f\\ng\", \"\\\"f\\\\ag\\\"\")\n\texpectPrintedString(t, \"f\\nG\", \"\\\"f\\\\aG\\\"\")\n\texpectPrintedString(t, \"f\\x01o\", \"\\\"f\\x01o\\\"\")\n\texpectPrintedString(t, \"f\\to\", \"\\\"f\\to\\\"\")\n\n\texpectPrintedString(t, \"</script>\", \"\\\"</script>\\\"\")\n\texpectPrintedString(t, \"</style>\", \"\\\"<\\\\/style>\\\"\")\n\texpectPrintedString(t, \"</style\", \"\\\"<\\\\/style\\\"\")\n\texpectPrintedString(t, \"</STYLE\", \"\\\"<\\\\/STYLE\\\"\")\n\texpectPrintedString(t, \"</StYlE\", \"\\\"<\\\\/StYlE\\\"\")\n\texpectPrintedString(t, \">/style\", \"\\\">/style\\\"\")\n\texpectPrintedString(t, \">/STYLE\", \"\\\">/STYLE\\\"\")\n\texpectPrintedString(t, \">/StYlE\", \"\\\">/StYlE\\\"\")\n}\n\nfunc TestURLQuote(t *testing.T) {\n\texpectPrinted(t, \"* { background: url('foo') }\", \"* {\\n  background: url(foo);\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('f o') }\", \"* {\\n  background: url(f\\\\ o);\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('f  o') }\", \"* {\\n  background: url(\\\"f  o\\\");\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('foo)') }\", \"* {\\n  background: url(foo\\\\));\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('(foo') }\", \"* {\\n  background: url(\\\\(foo);\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('(foo)') }\", \"* {\\n  background: url(\\\"(foo)\\\");\\n}\\n\")\n\texpectPrinted(t, \"* { background: url('\\\"foo\\\"') }\", \"* {\\n  background: url('\\\"foo\\\"');\\n}\\n\")\n}\n\nfunc TestImportant(t *testing.T) {\n\texpectPrinted(t, \"a { b: c!important }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c!important; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c! important }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c! important; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c ! important }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c ! important; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c !IMPORTANT; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c !ImPoRtAnT; }\", \"a {\\n  b: c !important;\\n}\\n\")\n\texpectPrintedMinify(t, \"a { b: c !important }\", \"a{b:c!important}\")\n}\n\nfunc TestSelector(t *testing.T) {\n\texpectPrintedMinify(t, \"a + b c > d ~ e{}\", \"a+b c>d~e{}\")\n\n\texpectPrinted(t, \":unknown( x (a+b), 'c' ) {}\", \":unknown(x (a+b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x (a-b), 'c' ) {}\", \":unknown(x (a-b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x (a,b), 'c' ) {}\", \":unknown(x (a, b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x ( a + b ), 'c' ) {}\", \":unknown(x (a + b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x ( a - b ), 'c' ) {}\", \":unknown(x (a - b), \\\"c\\\") {\\n}\\n\")\n\texpectPrinted(t, \":unknown( x ( a , b ), 'c' ) {}\", \":unknown(x (a, b), \\\"c\\\") {\\n}\\n\")\n\n\texpectPrintedMinify(t, \":unknown( x (a+b), 'c' ) {}\", \":unknown(x (a+b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x (a-b), 'c' ) {}\", \":unknown(x (a-b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x (a,b), 'c' ) {}\", \":unknown(x (a,b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x ( a + b ), 'c' ) {}\", \":unknown(x (a + b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x ( a - b ), 'c' ) {}\", \":unknown(x (a - b),\\\"c\\\"){}\")\n\texpectPrintedMinify(t, \":unknown( x ( a , b ), 'c' ) {}\", \":unknown(x (a,b),\\\"c\\\"){}\")\n}\n\nfunc TestNestedSelector(t *testing.T) {\n\texpectPrintedMinify(t, \"a { &b {} }\", \"a{&b{}}\")\n\texpectPrintedMinify(t, \"a { & b {} }\", \"a{& b{}}\")\n\texpectPrintedMinify(t, \"a { & :b {} }\", \"a{& :b{}}\")\n\texpectPrintedMinify(t, \"& a & b & c {}\", \"& a & b & c{}\")\n}\n\nfunc TestBadQualifiedRules(t *testing.T) {\n\texpectPrinted(t, \";\", \"; {\\n}\\n\")\n\texpectPrinted(t, \"$bad: rule;\", \"$bad: rule; {\\n}\\n\")\n\texpectPrinted(t, \"a {}; b {};\", \"a {\\n}\\n; b {\\n}\\n; {\\n}\\n\")\n\texpectPrinted(t, \"a { div.major { color: blue } color: red }\", \"a {\\n  div.major { color: blue } color: red;\\n}\\n\")\n\texpectPrinted(t, \"a { div:hover { color: blue } color: red }\", \"a {\\n  div: hover { color: blue } color: red;\\n}\\n\")\n\texpectPrinted(t, \"a { div:hover { color: blue }; color: red }\", \"a {\\n  div: hover { color: blue };\\n  color: red;\\n}\\n\")\n\n\texpectPrinted(t, \"$bad{ color: red }\", \"$bad {\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"$bad { color: red }\", \"$bad {\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"$bad foo{ color: red }\", \"$bad foo {\\n  color: red;\\n}\\n\")\n\texpectPrinted(t, \"$bad foo { color: red }\", \"$bad foo {\\n  color: red;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"$bad{ color: red }\", \"$bad{color:red}\")\n\texpectPrintedMinify(t, \"$bad { color: red }\", \"$bad{color:red}\")\n\texpectPrintedMinify(t, \"$bad foo{ color: red }\", \"$bad foo{color:red}\")\n\texpectPrintedMinify(t, \"$bad foo { color: red }\", \"$bad foo{color:red}\")\n}\n\nfunc TestDeclaration(t *testing.T) {\n\texpectPrinted(t, \"* { unknown: x (a+b) }\", \"* {\\n  unknown: x (a+b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x (a-b) }\", \"* {\\n  unknown: x (a-b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x (a,b) }\", \"* {\\n  unknown: x (a, b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x ( a + b ) }\", \"* {\\n  unknown: x (a + b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x ( a - b ) }\", \"* {\\n  unknown: x (a - b);\\n}\\n\")\n\texpectPrinted(t, \"* { unknown: x ( a , b ) }\", \"* {\\n  unknown: x (a, b);\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { unknown: x (a+b) }\", \"*{unknown:x (a+b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x (a-b) }\", \"*{unknown:x (a-b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x (a,b) }\", \"*{unknown:x (a,b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x ( a + b ) }\", \"*{unknown:x (a + b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x ( a - b ) }\", \"*{unknown:x (a - b)}\")\n\texpectPrintedMinify(t, \"* { unknown: x ( a , b ) }\", \"*{unknown:x (a,b)}\")\n\n\t// Pretty-print long lists in declarations\n\texpectPrinted(t, \"a { b: c, d }\", \"a {\\n  b: c, d;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c, (d, e) }\", \"a {\\n  b: c, (d, e);\\n}\\n\")\n\texpectPrinted(t, \"a { b: c, d, e }\", \"a {\\n  b:\\n    c,\\n    d,\\n    e;\\n}\\n\")\n\texpectPrinted(t, \"a { b: c, (d, e), f }\", \"a {\\n  b:\\n    c,\\n    (d, e),\\n    f;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"a { b: c, d }\", \"a{b:c,d}\")\n\texpectPrintedMinify(t, \"a { b: c, (d, e) }\", \"a{b:c,(d,e)}\")\n\texpectPrintedMinify(t, \"a { b: c, d, e }\", \"a{b:c,d,e}\")\n\texpectPrintedMinify(t, \"a { b: c, (d, e), f }\", \"a{b:c,(d,e),f}\")\n}\n\nfunc TestVerbatimWhitespace(t *testing.T) {\n\texpectPrinted(t, \"*{--x:}\", \"* {\\n  --x:;\\n}\\n\")\n\texpectPrinted(t, \"*{--x: }\", \"* {\\n  --x: ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:; }\", \"* {\\n  --x:;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: ; }\", \"* {\\n  --x: ;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"*{--x:}\", \"*{--x:}\")\n\texpectPrintedMinify(t, \"*{--x: }\", \"*{--x: }\")\n\texpectPrintedMinify(t, \"* { --x:; }\", \"*{--x:}\")\n\texpectPrintedMinify(t, \"* { --x: ; }\", \"*{--x: }\")\n\n\texpectPrinted(t, \"*{--x:!important}\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"*{--x: !important}\", \"* {\\n  --x: !important;\\n}\\n\")\n\texpectPrinted(t, \"*{ --x:!important }\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"*{ --x: !important }\", \"* {\\n  --x: !important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:!important; }\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: !important; }\", \"* {\\n  --x: !important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:! important ; }\", \"* {\\n  --x:!important;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: ! important ; }\", \"* {\\n  --x: !important;\\n}\\n\")\n\n\texpectPrintedMinify(t, \"*{--x:!important}\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"*{--x: !important}\", \"*{--x: !important}\")\n\texpectPrintedMinify(t, \"*{ --x:!important }\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"*{ --x: !important }\", \"*{--x: !important}\")\n\texpectPrintedMinify(t, \"* { --x:!important; }\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"* { --x: !important; }\", \"*{--x: !important}\")\n\texpectPrintedMinify(t, \"* { --x:! important ; }\", \"*{--x:!important}\")\n\texpectPrintedMinify(t, \"* { --x: ! important ; }\", \"*{--x: !important}\")\n\n\texpectPrinted(t, \"* { --x:y; }\", \"* {\\n  --x:y;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: y; }\", \"* {\\n  --x: y;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:y ; }\", \"* {\\n  --x:y ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x:y, ; }\", \"* {\\n  --x:y, ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: var(y,); }\", \"* {\\n  --x: var(y,);\\n}\\n\")\n\texpectPrinted(t, \"* { --x: var(y, ); }\", \"* {\\n  --x: var(y, );\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:y; }\", \"*{--x:y}\")\n\texpectPrintedMinify(t, \"* { --x: y; }\", \"*{--x: y}\")\n\texpectPrintedMinify(t, \"* { --x:y ; }\", \"*{--x:y }\")\n\texpectPrintedMinify(t, \"* { --x:y, ; }\", \"*{--x:y, }\")\n\texpectPrintedMinify(t, \"* { --x: var(y,); }\", \"*{--x: var(y,)}\")\n\texpectPrintedMinify(t, \"* { --x: var(y, ); }\", \"*{--x: var(y, )}\")\n\n\texpectPrinted(t, \"* { --x:(y); }\", \"* {\\n  --x:(y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:(y) ; }\", \"* {\\n  --x:(y) ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: (y); }\", \"* {\\n  --x: (y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:(y ); }\", \"* {\\n  --x:(y );\\n}\\n\")\n\texpectPrinted(t, \"* { --x:( y); }\", \"* {\\n  --x:( y);\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:(y); }\", \"*{--x:(y)}\")\n\texpectPrintedMinify(t, \"* { --x:(y) ; }\", \"*{--x:(y) }\")\n\texpectPrintedMinify(t, \"* { --x: (y); }\", \"*{--x: (y)}\")\n\texpectPrintedMinify(t, \"* { --x:(y ); }\", \"*{--x:(y )}\")\n\texpectPrintedMinify(t, \"* { --x:( y); }\", \"*{--x:( y)}\")\n\n\texpectPrinted(t, \"* { --x:f(y); }\", \"* {\\n  --x:f(y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:f(y) ; }\", \"* {\\n  --x:f(y) ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: f(y); }\", \"* {\\n  --x: f(y);\\n}\\n\")\n\texpectPrinted(t, \"* { --x:f(y ); }\", \"* {\\n  --x:f(y );\\n}\\n\")\n\texpectPrinted(t, \"* { --x:f( y); }\", \"* {\\n  --x:f( y);\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:f(y); }\", \"*{--x:f(y)}\")\n\texpectPrintedMinify(t, \"* { --x:f(y) ; }\", \"*{--x:f(y) }\")\n\texpectPrintedMinify(t, \"* { --x: f(y); }\", \"*{--x: f(y)}\")\n\texpectPrintedMinify(t, \"* { --x:f(y ); }\", \"*{--x:f(y )}\")\n\texpectPrintedMinify(t, \"* { --x:f( y); }\", \"*{--x:f( y)}\")\n\n\texpectPrinted(t, \"* { --x:[y]; }\", \"* {\\n  --x:[y];\\n}\\n\")\n\texpectPrinted(t, \"* { --x:[y] ; }\", \"* {\\n  --x:[y] ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: [y]; }\", \"* {\\n  --x: [y];\\n}\\n\")\n\texpectPrinted(t, \"* { --x:[y ]; }\", \"* {\\n  --x:[y ];\\n}\\n\")\n\texpectPrinted(t, \"* { --x:[ y]; }\", \"* {\\n  --x:[ y];\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:[y]; }\", \"*{--x:[y]}\")\n\texpectPrintedMinify(t, \"* { --x:[y] ; }\", \"*{--x:[y] }\")\n\texpectPrintedMinify(t, \"* { --x: [y]; }\", \"*{--x: [y]}\")\n\texpectPrintedMinify(t, \"* { --x:[y ]; }\", \"*{--x:[y ]}\")\n\texpectPrintedMinify(t, \"* { --x:[ y]; }\", \"*{--x:[ y]}\")\n\n\texpectPrinted(t, \"* { --x:{y}; }\", \"* {\\n  --x:{y};\\n}\\n\")\n\texpectPrinted(t, \"* { --x:{y} ; }\", \"* {\\n  --x:{y} ;\\n}\\n\")\n\texpectPrinted(t, \"* { --x: {y}; }\", \"* {\\n  --x: {y};\\n}\\n\")\n\texpectPrinted(t, \"* { --x:{y }; }\", \"* {\\n  --x:{y };\\n}\\n\")\n\texpectPrinted(t, \"* { --x:{ y}; }\", \"* {\\n  --x:{ y};\\n}\\n\")\n\n\texpectPrintedMinify(t, \"* { --x:{y}; }\", \"*{--x:{y}}\")\n\texpectPrintedMinify(t, \"* { --x:{y} ; }\", \"*{--x:{y} }\")\n\texpectPrintedMinify(t, \"* { --x: {y}; }\", \"*{--x: {y}}\")\n\texpectPrintedMinify(t, \"* { --x:{y }; }\", \"*{--x:{y }}\")\n\texpectPrintedMinify(t, \"* { --x:{ y}; }\", \"*{--x:{ y}}\")\n\n\texpectPrintedMinify(t, \"@supports ( --x : y , z ) { a { color: red; } }\", \"@supports ( --x : y , z ){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( --x : ) { a { color: red; } }\", \"@supports ( --x : ){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports (--x: ) { a { color: red; } }\", \"@supports (--x: ){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( --x y , z ) { a { color: red; } }\", \"@supports (--x y,z){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( --x ) { a { color: red; } }\", \"@supports (--x){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( ) { a { color: red; } }\", \"@supports (){a{color:red}}\")\n\texpectPrintedMinify(t, \"@supports ( . --x : y , z ) { a { color: red; } }\", \"@supports (. --x : y,z){a{color:red}}\")\n}\n\nfunc TestAtRule(t *testing.T) {\n\texpectPrintedMinify(t, \"@unknown;\", \"@unknown;\")\n\texpectPrintedMinify(t, \"@unknown x;\", \"@unknown x;\")\n\texpectPrintedMinify(t, \"@unknown{}\", \"@unknown{}\")\n\texpectPrintedMinify(t, \"@unknown{\\na: b;\\nc: d;\\n}\", \"@unknown{a: b; c: d;}\")\n\n\texpectPrinted(t, \"@unknown x{}\", \"@unknown x {}\\n\")\n\texpectPrinted(t, \"@unknown x {}\", \"@unknown x {}\\n\")\n\texpectPrintedMinify(t, \"@unknown x{}\", \"@unknown x{}\")\n\texpectPrintedMinify(t, \"@unknown x {}\", \"@unknown x{}\")\n\n\texpectPrinted(t, \"@unknown x ( a + b ) ;\", \"@unknown x (a + b);\\n\")\n\texpectPrinted(t, \"@unknown x ( a - b ) ;\", \"@unknown x (a - b);\\n\")\n\texpectPrinted(t, \"@unknown x ( a , b ) ;\", \"@unknown x (a, b);\\n\")\n\texpectPrintedMinify(t, \"@unknown x ( a + b ) ;\", \"@unknown x (a + b);\")\n\texpectPrintedMinify(t, \"@unknown x ( a - b ) ;\", \"@unknown x (a - b);\")\n\texpectPrintedMinify(t, \"@unknown x ( a , b ) ;\", \"@unknown x (a,b);\")\n}\n\nfunc TestAtCharset(t *testing.T) {\n\texpectPrinted(t, \"@charset \\\"UTF-8\\\";\", \"@charset \\\"UTF-8\\\";\\n\")\n\texpectPrintedMinify(t, \"@charset \\\"UTF-8\\\";\", \"@charset \\\"UTF-8\\\";\")\n}\n\nfunc TestAtImport(t *testing.T) {\n\texpectPrinted(t, \"@import\\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import \\\"foo.css\\\";\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(foo.css);\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\");\", \"@import \\\"foo.css\\\";\\n\")\n\texpectPrinted(t, \"@import url(\\\"foo.css\\\") print;\", \"@import \\\"foo.css\\\" print;\\n\")\n\n\texpectPrintedMinify(t, \"@import\\\"foo.css\\\";\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import \\\"foo.css\\\";\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import url(foo.css);\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\");\", \"@import\\\"foo.css\\\";\")\n\texpectPrintedMinify(t, \"@import url(\\\"foo.css\\\") print;\", \"@import\\\"foo.css\\\"print;\")\n}\n\nfunc TestAtKeyframes(t *testing.T) {\n\texpectPrintedMinify(t, \"@keyframes name { 0%, 50% { color: red } 25%, 75% { color: blue } }\",\n\t\t\"@keyframes name{0%,50%{color:red}25%,75%{color:blue}}\")\n\texpectPrintedMinify(t, \"@keyframes name { from { color: red } to { color: blue } }\",\n\t\t\"@keyframes name{from{color:red}to{color:blue}}\")\n}\n\nfunc TestAtMedia(t *testing.T) {\n\texpectPrinted(t, \"@media screen { div { color: red } }\", \"@media screen {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@media screen{div{color:red}}\", \"@media screen {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMinify(t, \"@media screen { div { color: red } }\", \"@media screen{div{color:red}}\")\n\texpectPrintedMinify(t, \"@media screen{div{color:red}}\", \"@media screen{div{color:red}}\")\n}\n\nfunc TestAtFontFace(t *testing.T) {\n\texpectPrinted(t, \"@font-face { font-family: 'Open Sans'; src: url('OpenSans.woff') format('woff') }\",\n\t\t\"@font-face {\\n  font-family: \\\"Open Sans\\\";\\n  src: url(OpenSans.woff) format(\\\"woff\\\");\\n}\\n\")\n\texpectPrintedMinify(t, \"@font-face { font-family: 'Open Sans'; src: url('OpenSans.woff') format('woff') }\",\n\t\t\"@font-face{font-family:\\\"Open Sans\\\";src:url(OpenSans.woff) format(\\\"woff\\\")}\")\n}\n\nfunc TestAtPage(t *testing.T) {\n\texpectPrinted(t, \"@page { margin: 1cm }\", \"@page {\\n  margin: 1cm;\\n}\\n\")\n\texpectPrinted(t, \"@page :first { margin: 1cm }\", \"@page :first {\\n  margin: 1cm;\\n}\\n\")\n\texpectPrintedMinify(t, \"@page { margin: 1cm }\", \"@page{margin:1cm}\")\n\texpectPrintedMinify(t, \"@page :first { margin: 1cm }\", \"@page :first{margin:1cm}\")\n}\n\nfunc TestAtStartingStyle(t *testing.T) {\n\texpectPrinted(t, \"@starting-style { div { color: red } }\", \"@starting-style {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrinted(t, \"@starting-style{div{color:red}}\", \"@starting-style {\\n  div {\\n    color: red;\\n  }\\n}\\n\")\n\texpectPrintedMinify(t, \"@starting-style { div { color: red } }\", \"@starting-style{div{color:red}}\")\n\texpectPrintedMinify(t, \"@starting-style{div{color:red}}\", \"@starting-style{div{color:red}}\")\n}\n\nfunc TestMsGridColumnsWhitespace(t *testing.T) {\n\t// Must not insert a space between the \"]\" and the \"(\"\n\texpectPrinted(t, \"div { -ms-grid-columns: (1fr)[3] }\", \"div {\\n  -ms-grid-columns: (1fr)[3];\\n}\\n\")\n\texpectPrinted(t, \"div { -ms-grid-columns: 1fr (20px 1fr)[3] }\", \"div {\\n  -ms-grid-columns: 1fr (20px 1fr)[3];\\n}\\n\")\n\texpectPrintedMinify(t, \"div { -ms-grid-columns: (1fr)[3] }\", \"div{-ms-grid-columns:(1fr)[3]}\")\n\texpectPrintedMinify(t, \"div { -ms-grid-columns: 1fr (20px 1fr)[3] }\", \"div{-ms-grid-columns:1fr (20px 1fr)[3]}\")\n}\n\nfunc TestASCII(t *testing.T) {\n\texpectPrintedASCII(t, \"* { background: url(🐈) }\", \"* {\\n  background: url(\\\\1f408);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url(🐈6) }\", \"* {\\n  background: url(\\\\1f408 6);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('🐈') }\", \"* {\\n  background: url(\\\\1f408);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('🐈6') }\", \"* {\\n  background: url(\\\\1f408 6);\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('(🐈)') }\", \"* {\\n  background: url(\\\"(\\\\1f408)\\\");\\n}\\n\")\n\texpectPrintedASCII(t, \"* { background: url('(🐈6)') }\", \"* {\\n  background: url(\\\"(\\\\1f408 6)\\\");\\n}\\n\")\n\n\texpectPrintedASCII(t, \"div { 🐈: 🐈('🐈') }\", \"div {\\n  \\\\1f408: \\\\1f408(\\\"\\\\1f408\\\");\\n}\\n\")\n\texpectPrintedASCII(t, \"div { 🐈 : 🐈 ('🐈 ') }\", \"div {\\n  \\\\1f408: \\\\1f408  (\\\"\\\\1f408  \\\");\\n}\\n\")\n\texpectPrintedASCII(t, \"div { 🐈6: 🐈6('🐈6') }\", \"div {\\n  \\\\1f408 6: \\\\1f408 6(\\\"\\\\1f408 6\\\");\\n}\\n\")\n\n\texpectPrintedASCII(t, \"@🐈;\", \"@\\\\1f408;\\n\")\n\texpectPrintedASCII(t, \"@🐈 {}\", \"@\\\\1f408 {}\\n\")\n\texpectPrintedASCII(t, \"@🐈 x {}\", \"@\\\\1f408  x {}\\n\")\n\n\texpectPrintedASCII(t, \"#🐈#x {}\", \"#\\\\1f408#x {\\n}\\n\")\n\texpectPrintedASCII(t, \"#🐈 #x {}\", \"#\\\\1f408  #x {\\n}\\n\")\n\texpectPrintedASCII(t, \"#🐈::x {}\", \"#\\\\1f408::x {\\n}\\n\")\n\texpectPrintedASCII(t, \"#🐈 ::x {}\", \"#\\\\1f408  ::x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \".🐈.x {}\", \".\\\\1f408.x {\\n}\\n\")\n\texpectPrintedASCII(t, \".🐈 .x {}\", \".\\\\1f408  .x {\\n}\\n\")\n\texpectPrintedASCII(t, \".🐈::x {}\", \".\\\\1f408::x {\\n}\\n\")\n\texpectPrintedASCII(t, \".🐈 ::x {}\", \".\\\\1f408  ::x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \"🐈|🐈.x {}\", \"\\\\1f408|\\\\1f408.x {\\n}\\n\")\n\texpectPrintedASCII(t, \"🐈|🐈 .x {}\", \"\\\\1f408|\\\\1f408  .x {\\n}\\n\")\n\texpectPrintedASCII(t, \"🐈|🐈::x {}\", \"\\\\1f408|\\\\1f408::x {\\n}\\n\")\n\texpectPrintedASCII(t, \"🐈|🐈 ::x {}\", \"\\\\1f408|\\\\1f408  ::x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \"::🐈:x {}\", \"::\\\\1f408:x {\\n}\\n\")\n\texpectPrintedASCII(t, \"::🐈 :x {}\", \"::\\\\1f408  :x {\\n}\\n\")\n\n\texpectPrintedASCII(t, \"[🐈] {}\", \"[\\\\1f408] {\\n}\\n\")\n\texpectPrintedASCII(t, \"[🐈=🐈] {}\", \"[\\\\1f408=\\\\1f408] {\\n}\\n\")\n\texpectPrintedASCII(t, \"[🐈|🐈=🐈] {}\", \"[\\\\1f408|\\\\1f408=\\\\1f408] {\\n}\\n\")\n\n\t// A space must be consumed after an escaped code point even with six digits\n\texpectPrintedASCII(t, \".\\\\10FFF abc:after { content: '\\\\10FFF abc' }\", \".\\\\10fff abc:after {\\n  content: \\\"\\\\10fff abc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\U00010FFFabc:after { content: '\\U00010FFFabc' }\", \".\\\\10fff abc:after {\\n  content: \\\"\\\\10fff abc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\\\10FFFFabc:after { content: '\\\\10FFFFabc' }\", \".\\\\10ffffabc:after {\\n  content: \\\"\\\\10ffffabc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\\\10FFFF abc:after { content: '\\\\10FFFF abc' }\", \".\\\\10ffffabc:after {\\n  content: \\\"\\\\10ffffabc\\\";\\n}\\n\")\n\texpectPrintedASCII(t, \".\\U0010FFFFabc:after { content: '\\U0010FFFFabc' }\", \".\\\\10ffffabc:after {\\n  content: \\\"\\\\10ffffabc\\\";\\n}\\n\")\n\n\t// This character should always be escaped\n\texpectPrinted(t, \".\\\\FEFF:after { content: '\\uFEFF' }\", \".\\\\feff:after {\\n  content: \\\"\\\\feff\\\";\\n}\\n\")\n}\n"
  },
  {
    "path": "lib/esbuild/esbuild.go",
    "content": "package esbuild\n"
  },
  {
    "path": "lib/esbuild/helpers/bitset.go",
    "content": "package helpers\n\nimport \"bytes\"\n\ntype BitSet struct {\n\tentries []byte\n}\n\nfunc NewBitSet(bitCount uint) BitSet {\n\treturn BitSet{make([]byte, (bitCount+7)/8)}\n}\n\nfunc (bs BitSet) HasBit(bit uint) bool {\n\treturn (bs.entries[bit/8] & (1 << (bit & 7))) != 0\n}\n\nfunc (bs BitSet) SetBit(bit uint) {\n\tbs.entries[bit/8] |= 1 << (bit & 7)\n}\n\nfunc (bs BitSet) Equals(other BitSet) bool {\n\treturn bytes.Equal(bs.entries, other.entries)\n}\n\nfunc (bs BitSet) String() string {\n\treturn string(bs.entries)\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/comment.go",
    "content": "package helpers\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nfunc RemoveMultiLineCommentIndent(prefix string, text string) string {\n\t// Figure out the initial indent\n\tindent := 0\nseekBackwardToNewline:\n\tfor len(prefix) > 0 {\n\t\tc, size := utf8.DecodeLastRuneInString(prefix)\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\tbreak seekBackwardToNewline\n\t\t}\n\t\tprefix = prefix[:len(prefix)-size]\n\t\tindent++\n\t}\n\n\t// Split the comment into lines\n\tvar lines []string\n\tstart := 0\n\tfor i, c := range text {\n\t\tswitch c {\n\t\tcase '\\r', '\\n':\n\t\t\t// Don't double-append for Windows style \"\\r\\n\" newlines\n\t\t\tif start <= i {\n\t\t\t\tlines = append(lines, text[start:i])\n\t\t\t}\n\n\t\t\tstart = i + 1\n\n\t\t\t// Ignore the second part of Windows style \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && start < len(text) && text[start] == '\\n' {\n\t\t\t\tstart++\n\t\t\t}\n\n\t\tcase '\\u2028', '\\u2029':\n\t\t\tlines = append(lines, text[start:i])\n\t\t\tstart = i + 3\n\t\t}\n\t}\n\tlines = append(lines, text[start:])\n\n\t// Find the minimum indent over all lines after the first line\n\tfor _, line := range lines[1:] {\n\t\tlineIndent := 0\n\t\tfor _, c := range line {\n\t\t\tif c != ' ' && c != '\\t' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tlineIndent++\n\t\t}\n\t\tif indent > lineIndent {\n\t\t\tindent = lineIndent\n\t\t}\n\t}\n\n\t// Trim the indent off of all lines after the first line\n\tfor i, line := range lines {\n\t\tif i > 0 {\n\t\t\tlines[i] = line[indent:]\n\t\t}\n\t}\n\treturn strings.Join(lines, \"\\n\")\n}\n\nfunc EscapeClosingTag(text string, slashTag string) string {\n\ti := strings.Index(text, \"</\")\n\tif i < 0 {\n\t\treturn text\n\t}\n\tvar b strings.Builder\n\tfor {\n\t\tb.WriteString(text[:i+1])\n\t\ttext = text[i+1:]\n\t\tif len(text) >= len(slashTag) && strings.EqualFold(text[:len(slashTag)], slashTag) {\n\t\t\tb.WriteByte('\\\\')\n\t\t}\n\t\ti = strings.Index(text, \"</\")\n\t\tif i < 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\tb.WriteString(text)\n\treturn b.String()\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/hash.go",
    "content": "package helpers\n\n// From: http://boost.sourceforge.net/doc/html/boost/hash_combine.html\nfunc HashCombine(seed uint32, hash uint32) uint32 {\n\treturn seed ^ (hash + 0x9e3779b9 + (seed << 6) + (seed >> 2))\n}\n\nfunc HashCombineString(seed uint32, text string) uint32 {\n\tseed = HashCombine(seed, uint32(len(text)))\n\tfor _, c := range text {\n\t\tseed = HashCombine(seed, uint32(c))\n\t}\n\treturn seed\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/joiner.go",
    "content": "package helpers\n\nimport (\n\t\"bytes\"\n\t\"strings\"\n)\n\n// This provides an efficient way to join lots of big string and byte slices\n// together. It avoids the cost of repeatedly reallocating as the buffer grows\n// by measuring exactly how big the buffer should be and then allocating once.\n// This is a measurable speedup.\ntype Joiner struct {\n\tstrings  []joinerString\n\tbytes    []joinerBytes\n\tlength   uint32\n\tlastByte byte\n}\n\ntype joinerString struct {\n\tdata   string\n\toffset uint32\n}\n\ntype joinerBytes struct {\n\tdata   []byte\n\toffset uint32\n}\n\nfunc (j *Joiner) AddString(data string) {\n\tif len(data) > 0 {\n\t\tj.lastByte = data[len(data)-1]\n\t}\n\tj.strings = append(j.strings, joinerString{data, j.length})\n\tj.length += uint32(len(data))\n}\n\nfunc (j *Joiner) AddBytes(data []byte) {\n\tif len(data) > 0 {\n\t\tj.lastByte = data[len(data)-1]\n\t}\n\tj.bytes = append(j.bytes, joinerBytes{data, j.length})\n\tj.length += uint32(len(data))\n}\n\nfunc (j *Joiner) LastByte() byte {\n\treturn j.lastByte\n}\n\nfunc (j *Joiner) Length() uint32 {\n\treturn j.length\n}\n\nfunc (j *Joiner) EnsureNewlineAtEnd() {\n\tif j.length > 0 && j.lastByte != '\\n' {\n\t\tj.AddString(\"\\n\")\n\t}\n}\n\nfunc (j *Joiner) Done() []byte {\n\tif len(j.strings) == 0 && len(j.bytes) == 1 && j.bytes[0].offset == 0 {\n\t\t// No need to allocate if there was only a single byte array written\n\t\treturn j.bytes[0].data\n\t}\n\tbuffer := make([]byte, j.length)\n\tfor _, item := range j.strings {\n\t\tcopy(buffer[item.offset:], item.data)\n\t}\n\tfor _, item := range j.bytes {\n\t\tcopy(buffer[item.offset:], item.data)\n\t}\n\treturn buffer\n}\n\nfunc (j *Joiner) Contains(s string, b []byte) bool {\n\tfor _, item := range j.strings {\n\t\tif strings.Contains(item.data, s) {\n\t\t\treturn true\n\t\t}\n\t}\n\tfor _, item := range j.bytes {\n\t\tif bytes.Contains(item.data, b) {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/mime.go",
    "content": "package helpers\n\nimport \"strings\"\n\nvar builtinTypesLower = map[string]string{\n\t\".css\":  \"text/css; charset=utf-8\",\n\t\".gif\":  \"image/gif\",\n\t\".htm\":  \"text/html; charset=utf-8\",\n\t\".html\": \"text/html; charset=utf-8\",\n\t\".jpeg\": \"image/jpeg\",\n\t\".jpg\":  \"image/jpeg\",\n\t\".js\":   \"text/javascript; charset=utf-8\",\n\t\".json\": \"application/json\",\n\t\".mjs\":  \"text/javascript; charset=utf-8\",\n\t\".pdf\":  \"application/pdf\",\n\t\".png\":  \"image/png\",\n\t\".svg\":  \"image/svg+xml\",\n\t\".wasm\": \"application/wasm\",\n\t\".webp\": \"image/webp\",\n\t\".xml\":  \"text/xml; charset=utf-8\",\n}\n\n// This is used instead of Go's built-in \"mime.TypeByExtension\" function because\n// that function is broken on Windows: https://github.com/golang/go/issues/32350.\nfunc MimeTypeByExtension(ext string) string {\n\tcontentType := builtinTypesLower[ext]\n\tif contentType == \"\" {\n\t\tcontentType = builtinTypesLower[strings.ToLower(ext)]\n\t}\n\treturn contentType\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/path.go",
    "content": "package helpers\n\nimport \"strings\"\n\nfunc IsInsideNodeModules(path string) bool {\n\tfor {\n\t\t// This is written in a platform-independent manner because it's run on\n\t\t// user-specified paths which can be arbitrary non-file-system things. So\n\t\t// for example Windows paths may end up being used on Unix or URLs may end\n\t\t// up being used on Windows. Be consistently agnostic to which kind of\n\t\t// slash is used on all platforms.\n\t\tslash := strings.LastIndexAny(path, \"/\\\\\")\n\t\tif slash == -1 {\n\t\t\treturn false\n\t\t}\n\t\tdir, base := path[:slash], path[slash+1:]\n\t\tif base == \"node_modules\" {\n\t\t\treturn true\n\t\t}\n\t\tpath = dir\n\t}\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/serializer.go",
    "content": "package helpers\n\nimport \"sync\"\n\n// Each call to \"Enter(i)\" doesn't start until \"Leave(i-1)\" is called\ntype Serializer struct {\n\tflags []sync.WaitGroup\n}\n\nfunc MakeSerializer(count int) Serializer {\n\tflags := make([]sync.WaitGroup, count)\n\tfor i := 0; i < count; i++ {\n\t\tflags[i].Add(1)\n\t}\n\treturn Serializer{flags: flags}\n}\n\nfunc (s *Serializer) Enter(i int) {\n\tif i > 0 {\n\t\ts.flags[i-1].Wait()\n\t}\n}\n\nfunc (s *Serializer) Leave(i int) {\n\ts.flags[i].Done()\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/stack.go",
    "content": "package helpers\n\nimport (\n\t\"runtime/debug\"\n\t\"strings\"\n)\n\nfunc PrettyPrintedStack() string {\n\tlines := strings.Split(strings.TrimSpace(string(debug.Stack())), \"\\n\")\n\n\t// Strip the first \"goroutine\" line\n\tif len(lines) > 0 {\n\t\tif first := lines[0]; strings.HasPrefix(first, \"goroutine \") && strings.HasSuffix(first, \":\") {\n\t\t\tlines = lines[1:]\n\t\t}\n\t}\n\n\tsb := strings.Builder{}\n\n\tfor _, line := range lines {\n\t\t// Indented lines are source locations\n\t\tif strings.HasPrefix(line, \"\\t\") {\n\t\t\tline = line[1:]\n\t\t\tline = strings.TrimPrefix(line, \"github.com/evanw/esbuild/\")\n\t\t\tif offset := strings.LastIndex(line, \" +0x\"); offset != -1 {\n\t\t\t\tline = line[:offset]\n\t\t\t}\n\t\t\tsb.WriteString(\" (\")\n\t\t\tsb.WriteString(line)\n\t\t\tsb.WriteString(\")\")\n\t\t\tcontinue\n\t\t}\n\n\t\t// Other lines are function calls\n\t\tif sb.Len() > 0 {\n\t\t\tsb.WriteByte('\\n')\n\t\t}\n\t\tif strings.HasSuffix(line, \")\") {\n\t\t\tif paren := strings.LastIndexByte(line, '('); paren != -1 {\n\t\t\t\tline = line[:paren]\n\t\t\t}\n\t\t}\n\t\tif slash := strings.LastIndexByte(line, '/'); slash != -1 {\n\t\t\tline = line[slash+1:]\n\t\t}\n\t\tsb.WriteString(line)\n\t}\n\n\treturn sb.String()\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/timer.go",
    "content": "package helpers\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\ntype Timer struct {\n\tdata  []timerData\n\tmutex sync.Mutex\n}\n\ntype timerData struct {\n\ttime  time.Time\n\tname  string\n\tisEnd bool\n}\n\nfunc (t *Timer) Begin(name string) {\n\tif t != nil {\n\t\tt.data = append(t.data, timerData{\n\t\t\tname: name,\n\t\t\ttime: time.Now(),\n\t\t})\n\t}\n}\n\nfunc (t *Timer) End(name string) {\n\tif t != nil {\n\t\tt.data = append(t.data, timerData{\n\t\t\tname:  name,\n\t\t\ttime:  time.Now(),\n\t\t\tisEnd: true,\n\t\t})\n\t}\n}\n\nfunc (t *Timer) Fork() *Timer {\n\tif t != nil {\n\t\treturn &Timer{}\n\t}\n\treturn nil\n}\n\nfunc (t *Timer) Join(other *Timer) {\n\tif t != nil && other != nil {\n\t\tt.mutex.Lock()\n\t\tdefer t.mutex.Unlock()\n\t\tt.data = append(t.data, other.data...)\n\t}\n}\n\nfunc (t *Timer) Log(log logger.Log) {\n\tif t == nil {\n\t\treturn\n\t}\n\n\ttype pair struct {\n\t\ttimerData\n\t\tindex uint32\n\t}\n\n\tvar notes []logger.MsgData\n\tvar stack []pair\n\tindent := 0\n\n\tfor _, item := range t.data {\n\t\tif !item.isEnd {\n\t\t\ttop := pair{timerData: item, index: uint32(len(notes))}\n\t\t\tnotes = append(notes, logger.MsgData{DisableMaximumWidth: true})\n\t\t\tstack = append(stack, top)\n\t\t\tindent++\n\t\t} else {\n\t\t\tindent--\n\t\t\tlast := len(stack) - 1\n\t\t\ttop := stack[last]\n\t\t\tstack = stack[:last]\n\t\t\tif item.name != top.name {\n\t\t\t\tpanic(\"Internal error\")\n\t\t\t}\n\t\t\tnotes[top.index].Text = fmt.Sprintf(\"%s%s: %dms\",\n\t\t\t\tstrings.Repeat(\"  \", indent),\n\t\t\t\ttop.name,\n\t\t\t\titem.time.Sub(top.time).Milliseconds())\n\t\t}\n\t}\n\n\tlog.AddWithNotes(logger.Info, nil, logger.Range{},\n\t\t\"Timing information (times may not nest hierarchically due to parallelism)\", notes)\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/typos.go",
    "content": "package helpers\n\nimport \"unicode/utf8\"\n\ntype TypoDetector struct {\n\toneCharTypos map[string]string\n}\n\nfunc MakeTypoDetector(valid []string) TypoDetector {\n\tdetector := TypoDetector{oneCharTypos: make(map[string]string)}\n\n\t// Add all combinations of each valid word with one character missing\n\tfor _, correct := range valid {\n\t\tif len(correct) > 3 {\n\t\t\tfor i, ch := range correct {\n\t\t\t\tdetector.oneCharTypos[correct[:i]+correct[i+utf8.RuneLen(ch):]] = correct\n\t\t\t}\n\t\t}\n\t}\n\n\treturn detector\n}\n\nfunc (detector TypoDetector) MaybeCorrectTypo(typo string) (string, bool) {\n\t// Check for a single deleted character\n\tif corrected, ok := detector.oneCharTypos[typo]; ok {\n\t\treturn corrected, true\n\t}\n\n\t// Check for a single misplaced character\n\tfor i, ch := range typo {\n\t\tif corrected, ok := detector.oneCharTypos[typo[:i]+typo[i+utf8.RuneLen(ch):]]; ok {\n\t\t\treturn corrected, true\n\t\t}\n\t}\n\n\treturn \"\", false\n}\n"
  },
  {
    "path": "lib/esbuild/helpers/utf.go",
    "content": "package helpers\n\nimport (\n\t\"strings\"\n\t\"unicode/utf8\"\n)\n\nfunc ContainsNonBMPCodePoint(text string) bool {\n\tfor _, c := range text {\n\t\tif c > 0xFFFF {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}\n\n// This does \"ContainsNonBMPCodePoint(UTF16ToString(text))\" without any allocations\nfunc ContainsNonBMPCodePointUTF16(text []uint16) bool {\n\tif n := len(text); n > 0 {\n\t\tfor i, c := range text[:n-1] {\n\t\t\t// Check for a high surrogate\n\t\t\tif c >= 0xD800 && c <= 0xDBFF {\n\t\t\t\t// Check for a low surrogate\n\t\t\t\tif c2 := text[i+1]; c2 >= 0xDC00 && c2 <= 0xDFFF {\n\t\t\t\t\treturn true\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false\n}\n\nfunc StringToUTF16(text string) []uint16 {\n\tdecoded := make([]uint16, 0, len(text))\n\tfor _, c := range text {\n\t\tif c <= 0xFFFF {\n\t\t\tdecoded = append(decoded, uint16(c))\n\t\t} else {\n\t\t\tc -= 0x10000\n\t\t\tdecoded = append(decoded, uint16(0xD800+((c>>10)&0x3FF)), uint16(0xDC00+(c&0x3FF)))\n\t\t}\n\t}\n\treturn decoded\n}\n\nfunc UTF16ToString(text []uint16) string {\n\tvar temp [utf8.UTFMax]byte\n\tb := strings.Builder{}\n\tn := len(text)\n\tfor i := 0; i < n; i++ {\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF && i+1 < n {\n\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\tr1 = (r1-0xD800)<<10 | (r2 - 0xDC00) + 0x10000\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t\twidth := encodeWTF8Rune(temp[:], r1)\n\t\tb.Write(temp[:width])\n\t}\n\treturn b.String()\n}\n\nfunc UTF16ToStringWithValidation(text []uint16) (string, uint16, bool) {\n\tvar temp [utf8.UTFMax]byte\n\tb := strings.Builder{}\n\tn := len(text)\n\tfor i := 0; i < n; i++ {\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF {\n\t\t\tif i+1 < n {\n\t\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\t\tr1 = (r1-0xD800)<<10 | (r2 - 0xDC00) + 0x10000\n\t\t\t\t\ti++\n\t\t\t\t} else {\n\t\t\t\t\treturn \"\", uint16(r1), false\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn \"\", uint16(r1), false\n\t\t\t}\n\t\t} else if r1 >= 0xDC00 && r1 <= 0xDFFF {\n\t\t\treturn \"\", uint16(r1), false\n\t\t}\n\t\twidth := encodeWTF8Rune(temp[:], r1)\n\t\tb.Write(temp[:width])\n\t}\n\treturn b.String(), 0, true\n}\n\n// Does \"UTF16ToString(text) == str\" without a temporary allocation\nfunc UTF16EqualsString(text []uint16, str string) bool {\n\tif len(text) > len(str) {\n\t\t// Strings can't be equal if UTF-16 encoding is longer than UTF-8 encoding\n\t\treturn false\n\t}\n\tvar temp [utf8.UTFMax]byte\n\tn := len(text)\n\tj := 0\n\tfor i := 0; i < n; i++ {\n\t\tr1 := rune(text[i])\n\t\tif r1 >= 0xD800 && r1 <= 0xDBFF && i+1 < n {\n\t\t\tif r2 := rune(text[i+1]); r2 >= 0xDC00 && r2 <= 0xDFFF {\n\t\t\t\tr1 = (r1-0xD800)<<10 | (r2 - 0xDC00) + 0x10000\n\t\t\t\ti++\n\t\t\t}\n\t\t}\n\t\twidth := encodeWTF8Rune(temp[:], r1)\n\t\tif j+width > len(str) {\n\t\t\treturn false\n\t\t}\n\t\tfor k := 0; k < width; k++ {\n\t\t\tif temp[k] != str[j] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tj++\n\t\t}\n\t}\n\treturn j == len(str)\n}\n\nfunc UTF16EqualsUTF16(a []uint16, b []uint16) bool {\n\tif len(a) == len(b) {\n\t\tfor i, c := range a {\n\t\t\tif c != b[i] {\n\t\t\t\treturn false\n\t\t\t}\n\t\t}\n\t\treturn true\n\t}\n\treturn false\n}\n\n// This is a clone of \"utf8.EncodeRune\" that has been modified to encode using\n// WTF-8 instead. See https://simonsapin.github.io/wtf-8/ for more info.\nfunc encodeWTF8Rune(p []byte, r rune) int {\n\t// Negative values are erroneous. Making it unsigned addresses the problem.\n\tswitch i := uint32(r); {\n\tcase i <= 0x7F:\n\t\tp[0] = byte(r)\n\t\treturn 1\n\tcase i <= 0x7FF:\n\t\t_ = p[1] // eliminate bounds checks\n\t\tp[0] = 0xC0 | byte(r>>6)\n\t\tp[1] = 0x80 | byte(r)&0x3F\n\t\treturn 2\n\tcase i > utf8.MaxRune:\n\t\tr = utf8.RuneError\n\t\tfallthrough\n\tcase i <= 0xFFFF:\n\t\t_ = p[2] // eliminate bounds checks\n\t\tp[0] = 0xE0 | byte(r>>12)\n\t\tp[1] = 0x80 | byte(r>>6)&0x3F\n\t\tp[2] = 0x80 | byte(r)&0x3F\n\t\treturn 3\n\tdefault:\n\t\t_ = p[3] // eliminate bounds checks\n\t\tp[0] = 0xF0 | byte(r>>18)\n\t\tp[1] = 0x80 | byte(r>>12)&0x3F\n\t\tp[2] = 0x80 | byte(r>>6)&0x3F\n\t\tp[3] = 0x80 | byte(r)&0x3F\n\t\treturn 4\n\t}\n}\n\n// This is a clone of \"utf8.DecodeRuneInString\" that has been modified to\n// decode using WTF-8 instead. See https://simonsapin.github.io/wtf-8/ for\n// more info.\nfunc DecodeWTF8Rune(s string) (rune, int) {\n\tn := len(s)\n\tif n < 1 {\n\t\treturn utf8.RuneError, 0\n\t}\n\n\ts0 := s[0]\n\tif s0 < 0x80 {\n\t\treturn rune(s0), 1\n\t}\n\n\tvar sz int\n\tif (s0 & 0xE0) == 0xC0 {\n\t\tsz = 2\n\t} else if (s0 & 0xF0) == 0xE0 {\n\t\tsz = 3\n\t} else if (s0 & 0xF8) == 0xF0 {\n\t\tsz = 4\n\t} else {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tif n < sz {\n\t\treturn utf8.RuneError, 0\n\t}\n\n\ts1 := s[1]\n\tif (s1 & 0xC0) != 0x80 {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tif sz == 2 {\n\t\tcp := rune(s0&0x1F)<<6 | rune(s1&0x3F)\n\t\tif cp < 0x80 {\n\t\t\treturn utf8.RuneError, 1\n\t\t}\n\t\treturn cp, 2\n\t}\n\ts2 := s[2]\n\n\tif (s2 & 0xC0) != 0x80 {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tif sz == 3 {\n\t\tcp := rune(s0&0x0F)<<12 | rune(s1&0x3F)<<6 | rune(s2&0x3F)\n\t\tif cp < 0x0800 {\n\t\t\treturn utf8.RuneError, 1\n\t\t}\n\t\treturn cp, 3\n\t}\n\ts3 := s[3]\n\n\tif (s3 & 0xC0) != 0x80 {\n\t\treturn utf8.RuneError, 1\n\t}\n\n\tcp := rune(s0&0x07)<<18 | rune(s1&0x3F)<<12 | rune(s2&0x3F)<<6 | rune(s3&0x3F)\n\tif cp < 0x010000 || cp > 0x10FFFF {\n\t\treturn utf8.RuneError, 1\n\t}\n\treturn cp, 4\n}\n"
  },
  {
    "path": "lib/esbuild/logger/logger.go",
    "content": "package logger\n\n// Logging is currently designed to look and feel like clang's error format.\n// Errors are streamed asynchronously as they happen, each error contains the\n// contents of the line with the error, and the error count is limited by\n// default.\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"runtime\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\t\"unicode/utf8\"\n)\n\nconst defaultTerminalWidth = 80\n\ntype Log struct {\n\tAddMsg    func(Msg)\n\tHasErrors func() bool\n\n\t// This is called after the build has finished but before writing to stdout.\n\t// It exists to ensure that deferred warning messages end up in the terminal\n\t// before the data written to stdout.\n\tAlmostDone func()\n\n\tDone func() []Msg\n\n\tLevel LogLevel\n}\n\ntype LogLevel int8\n\nconst (\n\tLevelNone LogLevel = iota\n\tLevelVerbose\n\tLevelDebug\n\tLevelInfo\n\tLevelWarning\n\tLevelError\n\tLevelSilent\n)\n\ntype MsgKind uint8\n\nconst (\n\tError MsgKind = iota\n\tWarning\n\tInfo\n\tNote\n\tDebug\n\tVerbose\n)\n\nfunc (kind MsgKind) String() string {\n\tswitch kind {\n\tcase Error:\n\t\treturn \"ERROR\"\n\tcase Warning:\n\t\treturn \"WARNING\"\n\tcase Info:\n\t\treturn \"INFO\"\n\tcase Note:\n\t\treturn \"NOTE\"\n\tcase Debug:\n\t\treturn \"DEBUG\"\n\tcase Verbose:\n\t\treturn \"VERBOSE\"\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nfunc (kind MsgKind) Icon() string {\n\t// Special-case Windows command prompt, which only supports a few characters\n\tif isProbablyWindowsCommandPrompt() {\n\t\tswitch kind {\n\t\tcase Error:\n\t\t\treturn \"X\"\n\t\tcase Warning:\n\t\t\treturn \"▲\"\n\t\tcase Info:\n\t\t\treturn \"►\"\n\t\tcase Note:\n\t\t\treturn \"→\"\n\t\tcase Debug:\n\t\t\treturn \"●\"\n\t\tcase Verbose:\n\t\t\treturn \"♦\"\n\t\tdefault:\n\t\t\tpanic(\"Internal error\")\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase Error:\n\t\treturn \"✘\"\n\tcase Warning:\n\t\treturn \"▲\"\n\tcase Info:\n\t\treturn \"▶\"\n\tcase Note:\n\t\treturn \"→\"\n\tcase Debug:\n\t\treturn \"●\"\n\tcase Verbose:\n\t\treturn \"⬥\"\n\tdefault:\n\t\tpanic(\"Internal error\")\n\t}\n}\n\nvar windowsCommandPrompt struct {\n\tmutex         sync.Mutex\n\tonce          bool\n\tisProbablyCMD bool\n}\n\nfunc isProbablyWindowsCommandPrompt() bool {\n\twindowsCommandPrompt.mutex.Lock()\n\tdefer windowsCommandPrompt.mutex.Unlock()\n\n\tif !windowsCommandPrompt.once {\n\t\twindowsCommandPrompt.once = true\n\n\t\t// Assume we are running in Windows Command Prompt if we're on Windows. If\n\t\t// so, we can't use emoji because it won't be supported. Except we can\n\t\t// still use emoji if the WT_SESSION environment variable is present\n\t\t// because that means we're running in the new Windows Terminal instead.\n\t\tif runtime.GOOS == \"windows\" {\n\t\t\twindowsCommandPrompt.isProbablyCMD = true\n\t\t\tfor _, env := range os.Environ() {\n\t\t\t\tif strings.HasPrefix(env, \"WT_SESSION=\") {\n\t\t\t\t\twindowsCommandPrompt.isProbablyCMD = false\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn windowsCommandPrompt.isProbablyCMD\n}\n\ntype Msg struct {\n\tNotes      []MsgData\n\tPluginName string\n\tData       MsgData\n\tKind       MsgKind\n}\n\ntype MsgData struct {\n\t// Optional user-specified data that is passed through unmodified\n\tUserDetail interface{}\n\n\tLocation *MsgLocation\n\tText     string\n\n\tDisableMaximumWidth bool\n}\n\ntype MsgLocation struct {\n\tFile       string\n\tNamespace  string\n\tLineText   string\n\tSuggestion string\n\tLine       int // 1-based\n\tColumn     int // 0-based, in bytes\n\tLength     int // in bytes\n}\n\ntype Loc struct {\n\t// This is the 0-based index of this location from the start of the file, in bytes\n\tStart int32\n}\n\ntype Range struct {\n\tLoc Loc\n\tLen int32\n}\n\nfunc (r Range) End() int32 {\n\treturn r.Loc.Start + r.Len\n}\n\ntype Span struct {\n\tText  string\n\tRange Range\n}\n\n// This type is just so we can use Go's native sort function\ntype SortableMsgs []Msg\n\nfunc (a SortableMsgs) Len() int          { return len(a) }\nfunc (a SortableMsgs) Swap(i int, j int) { a[i], a[j] = a[j], a[i] }\n\nfunc (a SortableMsgs) Less(i int, j int) bool {\n\tai := a[i]\n\taj := a[j]\n\taiLoc := ai.Data.Location\n\tajLoc := aj.Data.Location\n\tif aiLoc == nil || ajLoc == nil {\n\t\treturn aiLoc == nil && ajLoc != nil\n\t}\n\tif aiLoc.File != ajLoc.File {\n\t\treturn aiLoc.File < ajLoc.File\n\t}\n\tif aiLoc.Line != ajLoc.Line {\n\t\treturn aiLoc.Line < ajLoc.Line\n\t}\n\tif aiLoc.Column != ajLoc.Column {\n\t\treturn aiLoc.Column < ajLoc.Column\n\t}\n\tif ai.Kind != aj.Kind {\n\t\treturn ai.Kind < aj.Kind\n\t}\n\treturn ai.Data.Text < aj.Data.Text\n}\n\n// This is used to represent both file system paths (Namespace == \"file\") and\n// abstract module paths (Namespace != \"file\"). Abstract module paths represent\n// \"virtual modules\" when used for an input file and \"package paths\" when used\n// to represent an external module.\ntype Path struct {\n\tText      string\n\tNamespace string\n\n\t// This feature was added to support ancient CSS libraries that append things\n\t// like \"?#iefix\" and \"#icons\" to some of their import paths as a hack for IE6.\n\t// The intent is for these suffix parts to be ignored but passed through to\n\t// the output. This is supported by other bundlers, so we also support this.\n\tIgnoredSuffix string\n\n\tFlags PathFlags\n}\n\ntype PathFlags uint8\n\nconst (\n\t// This corresponds to a value of \"false' in the \"browser\" package.json field\n\tPathDisabled PathFlags = 1 << iota\n)\n\nfunc (p Path) IsDisabled() bool {\n\treturn (p.Flags & PathDisabled) != 0\n}\n\nfunc (a Path) ComesBeforeInSortedOrder(b Path) bool {\n\treturn a.Namespace > b.Namespace ||\n\t\t(a.Namespace == b.Namespace && (a.Text < b.Text ||\n\t\t\t(a.Text == b.Text && (a.Flags < b.Flags ||\n\t\t\t\t(a.Flags == b.Flags && a.IgnoredSuffix < b.IgnoredSuffix)))))\n}\n\nvar noColorResult bool\nvar noColorOnce sync.Once\n\nfunc hasNoColorEnvironmentVariable() bool {\n\tnoColorOnce.Do(func() {\n\t\tfor _, key := range os.Environ() {\n\t\t\t// Read \"NO_COLOR\" from the environment. This is a convention that some\n\t\t\t// software follows. See https://no-color.org/ for more information.\n\t\t\tif strings.HasPrefix(key, \"NO_COLOR=\") {\n\t\t\t\tnoColorResult = true\n\t\t\t}\n\t\t}\n\t})\n\treturn noColorResult\n}\n\n// This has a custom implementation instead of using \"filepath.Dir/Base/Ext\"\n// because it should work the same on Unix and Windows. These names end up in\n// the generated output and the generated output should not depend on the OS.\nfunc PlatformIndependentPathDirBaseExt(path string) (dir string, base string, ext string) {\n\tfor {\n\t\ti := strings.LastIndexAny(path, \"/\\\\\")\n\n\t\t// Stop if there are no more slashes\n\t\tif i < 0 {\n\t\t\tbase = path\n\t\t\tbreak\n\t\t}\n\n\t\t// Stop if we found a non-trailing slash\n\t\tif i+1 != len(path) {\n\t\t\tdir, base = path[:i], path[i+1:]\n\t\t\tbreak\n\t\t}\n\n\t\t// Ignore trailing slashes\n\t\tpath = path[:i]\n\t}\n\n\t// Strip off the extension\n\tif dot := strings.LastIndexByte(base, '.'); dot >= 0 {\n\t\tbase, ext = base[:dot], base[dot:]\n\t}\n\n\treturn\n}\n\ntype Source struct {\n\t// This is used for error messages and the metadata JSON file.\n\t//\n\t// This is a mostly platform-independent path. It's relative to the current\n\t// working directory and always uses standard path separators. Use this for\n\t// referencing a file in all output data. These paths still use the original\n\t// case of the path so they may still work differently on file systems that\n\t// are case-insensitive vs. case-sensitive.\n\tPrettyPath string\n\n\t// An identifier that is mixed in to automatically-generated symbol names to\n\t// improve readability. For example, if the identifier is \"util\" then the\n\t// symbol for an \"export default\" statement will be called \"util_default\".\n\tIdentifierName string\n\n\tContents string\n\n\t// This is used as a unique key to identify this source file. It should never\n\t// be shown to the user (e.g. never print this to the terminal).\n\t//\n\t// If it's marked as an absolute path, it's a platform-dependent path that\n\t// includes environment-specific things such as Windows backslash path\n\t// separators and potentially the user's home directory. Only use this for\n\t// passing to syscalls for reading and writing to the file system. Do not\n\t// include this in any output data.\n\t//\n\t// If it's marked as not an absolute path, it's an opaque string that is used\n\t// to refer to an automatically-generated module.\n\tKeyPath Path\n\n\tIndex uint32\n}\n\nfunc (s *Source) TextForRange(r Range) string {\n\treturn s.Contents[r.Loc.Start : r.Loc.Start+r.Len]\n}\n\nfunc (s *Source) LocBeforeWhitespace(loc Loc) Loc {\n\tfor loc.Start > 0 {\n\t\tc, width := utf8.DecodeLastRuneInString(s.Contents[:loc.Start])\n\t\tif c != ' ' && c != '\\t' && c != '\\r' && c != '\\n' {\n\t\t\tbreak\n\t\t}\n\t\tloc.Start -= int32(width)\n\t}\n\treturn loc\n}\n\nfunc (s *Source) RangeOfOperatorBefore(loc Loc, op string) Range {\n\ttext := s.Contents[:loc.Start]\n\tindex := strings.LastIndex(text, op)\n\tif index >= 0 {\n\t\treturn Range{Loc: Loc{Start: int32(index)}, Len: int32(len(op))}\n\t}\n\treturn Range{Loc: loc}\n}\n\nfunc (s *Source) RangeOfOperatorAfter(loc Loc, op string) Range {\n\ttext := s.Contents[loc.Start:]\n\tindex := strings.Index(text, op)\n\tif index >= 0 {\n\t\treturn Range{Loc: Loc{Start: loc.Start + int32(index)}, Len: int32(len(op))}\n\t}\n\treturn Range{Loc: loc}\n}\n\nfunc (s *Source) RangeOfString(loc Loc) Range {\n\ttext := s.Contents[loc.Start:]\n\tif len(text) == 0 {\n\t\treturn Range{Loc: loc, Len: 0}\n\t}\n\n\tquote := text[0]\n\tif quote == '\"' || quote == '\\'' {\n\t\t// Search for the matching quote character\n\t\tfor i := 1; i < len(text); i++ {\n\t\t\tc := text[i]\n\t\t\tif c == quote {\n\t\t\t\treturn Range{Loc: loc, Len: int32(i + 1)}\n\t\t\t} else if c == '\\\\' {\n\t\t\t\ti += 1\n\t\t\t}\n\t\t}\n\t}\n\n\treturn Range{Loc: loc, Len: 0}\n}\n\nfunc (s *Source) RangeOfNumber(loc Loc) (r Range) {\n\ttext := s.Contents[loc.Start:]\n\tr = Range{Loc: loc, Len: 0}\n\n\tif len(text) > 0 {\n\t\tif c := text[0]; c >= '0' && c <= '9' {\n\t\t\tr.Len = 1\n\t\t\tfor int(r.Len) < len(text) {\n\t\t\t\tc := text[r.Len]\n\t\t\t\tif (c < '0' || c > '9') && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '.' && c != '_' {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tr.Len++\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc (s *Source) RangeOfLegacyOctalEscape(loc Loc) (r Range) {\n\ttext := s.Contents[loc.Start:]\n\tr = Range{Loc: loc, Len: 0}\n\n\tif len(text) >= 2 && text[0] == '\\\\' {\n\t\tr.Len = 2\n\t\tfor r.Len < 4 && int(r.Len) < len(text) {\n\t\t\tc := text[r.Len]\n\t\t\tif c < '0' || c > '9' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tr.Len++\n\t\t}\n\t}\n\treturn\n}\n\nfunc plural(prefix string, count int, shown int, someAreMissing bool) string {\n\tvar text string\n\tif count == 1 {\n\t\ttext = fmt.Sprintf(\"%d %s\", count, prefix)\n\t} else {\n\t\ttext = fmt.Sprintf(\"%d %ss\", count, prefix)\n\t}\n\tif shown < count {\n\t\ttext = fmt.Sprintf(\"%d of %s\", shown, text)\n\t} else if someAreMissing && count > 1 {\n\t\ttext = \"all \" + text\n\t}\n\treturn text\n}\n\nfunc errorAndWarningSummary(errors int, warnings int, shownErrors int, shownWarnings int) string {\n\tsomeAreMissing := shownWarnings < warnings || shownErrors < errors\n\tswitch {\n\tcase errors == 0:\n\t\treturn plural(\"warning\", warnings, shownWarnings, someAreMissing)\n\tcase warnings == 0:\n\t\treturn plural(\"error\", errors, shownErrors, someAreMissing)\n\tdefault:\n\t\treturn fmt.Sprintf(\"%s and %s\",\n\t\t\tplural(\"warning\", warnings, shownWarnings, someAreMissing),\n\t\t\tplural(\"error\", errors, shownErrors, someAreMissing))\n\t}\n}\n\ntype APIKind uint8\n\nconst (\n\tGoAPI APIKind = iota\n\tCLIAPI\n\tJSAPI\n)\n\n// This can be used to customize error messages for the current API kind\nvar API APIKind\n\ntype TerminalInfo struct {\n\tIsTTY           bool\n\tUseColorEscapes bool\n\tWidth           int\n\tHeight          int\n}\n\nfunc NewStderrLog(options OutputOptions) Log {\n\tvar mutex sync.Mutex\n\tvar msgs SortableMsgs\n\tterminalInfo := GetTerminalInfo(os.Stderr)\n\terrors := 0\n\twarnings := 0\n\tshownErrors := 0\n\tshownWarnings := 0\n\thasErrors := false\n\tremainingMessagesBeforeLimit := options.MessageLimit\n\tif remainingMessagesBeforeLimit == 0 {\n\t\tremainingMessagesBeforeLimit = 0x7FFFFFFF\n\t}\n\tvar deferredWarnings []Msg\n\tdidFinalizeLog := false\n\n\tfinalizeLog := func() {\n\t\tif didFinalizeLog {\n\t\t\treturn\n\t\t}\n\t\tdidFinalizeLog = true\n\n\t\t// Print the deferred warning now if there was no error after all\n\t\tfor remainingMessagesBeforeLimit > 0 && len(deferredWarnings) > 0 {\n\t\t\tshownWarnings++\n\t\t\twriteStringWithColor(os.Stderr, deferredWarnings[0].String(options, terminalInfo))\n\t\t\tdeferredWarnings = deferredWarnings[1:]\n\t\t\tremainingMessagesBeforeLimit--\n\t\t}\n\n\t\t// Print out a summary\n\t\tif options.MessageLimit > 0 && errors+warnings > options.MessageLimit {\n\t\t\twriteStringWithColor(os.Stderr, fmt.Sprintf(\"%s shown (disable the message limit with --log-limit=0)\\n\",\n\t\t\t\terrorAndWarningSummary(errors, warnings, shownErrors, shownWarnings)))\n\t\t} else if options.LogLevel <= LevelInfo && (warnings != 0 || errors != 0) {\n\t\t\twriteStringWithColor(os.Stderr, fmt.Sprintf(\"%s\\n\",\n\t\t\t\terrorAndWarningSummary(errors, warnings, shownErrors, shownWarnings)))\n\t\t}\n\t}\n\n\tswitch options.Color {\n\tcase ColorNever:\n\t\tterminalInfo.UseColorEscapes = false\n\tcase ColorAlways:\n\t\tterminalInfo.UseColorEscapes = SupportsColorEscapes\n\t}\n\n\treturn Log{\n\t\tLevel: options.LogLevel,\n\n\t\tAddMsg: func(msg Msg) {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tmsgs = append(msgs, msg)\n\n\t\t\tswitch msg.Kind {\n\t\t\tcase Verbose:\n\t\t\t\tif options.LogLevel <= LevelVerbose {\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t}\n\n\t\t\tcase Debug:\n\t\t\t\tif options.LogLevel <= LevelDebug {\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t}\n\n\t\t\tcase Info:\n\t\t\t\tif options.LogLevel <= LevelInfo {\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t}\n\n\t\t\tcase Error:\n\t\t\t\thasErrors = true\n\t\t\t\tif options.LogLevel <= LevelError {\n\t\t\t\t\terrors++\n\t\t\t\t}\n\n\t\t\tcase Warning:\n\t\t\t\tif options.LogLevel <= LevelWarning {\n\t\t\t\t\twarnings++\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Be silent if we're past the limit so we don't flood the terminal\n\t\t\tif remainingMessagesBeforeLimit == 0 {\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tswitch msg.Kind {\n\t\t\tcase Error:\n\t\t\t\tif options.LogLevel <= LevelError {\n\t\t\t\t\tshownErrors++\n\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t\tremainingMessagesBeforeLimit--\n\t\t\t\t}\n\n\t\t\tcase Warning:\n\t\t\t\tif options.LogLevel <= LevelWarning {\n\t\t\t\t\tif remainingMessagesBeforeLimit > (options.MessageLimit+1)/2 {\n\t\t\t\t\t\tshownWarnings++\n\t\t\t\t\t\twriteStringWithColor(os.Stderr, msg.String(options, terminalInfo))\n\t\t\t\t\t\tremainingMessagesBeforeLimit--\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// If we have less than half of the slots left, wait for potential\n\t\t\t\t\t\t// future errors instead of using up all of the slots with warnings.\n\t\t\t\t\t\t// We want the log for a failed build to always have at least one\n\t\t\t\t\t\t// error in it.\n\t\t\t\t\t\tdeferredWarnings = append(deferredWarnings, msg)\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tHasErrors: func() bool {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\treturn hasErrors\n\t\t},\n\n\t\tAlmostDone: func() {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\n\t\t\tfinalizeLog()\n\t\t},\n\n\t\tDone: func() []Msg {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\n\t\t\tfinalizeLog()\n\t\t\tsort.Stable(msgs)\n\t\t\treturn msgs\n\t\t},\n\t}\n}\n\nfunc PrintErrorToStderr(osArgs []string, text string) {\n\tPrintMessageToStderr(osArgs, Msg{Kind: Error, Data: MsgData{Text: text}})\n}\n\nfunc OutputOptionsForArgs(osArgs []string) OutputOptions {\n\toptions := OutputOptions{IncludeSource: true}\n\n\t// Implement a mini argument parser so these options always work even if we\n\t// haven't yet gotten to the general-purpose argument parsing code\n\tfor _, arg := range osArgs {\n\t\tswitch arg {\n\t\tcase \"--color=false\":\n\t\t\toptions.Color = ColorNever\n\t\tcase \"--color=true\", \"--color\":\n\t\t\toptions.Color = ColorAlways\n\t\tcase \"--log-level=info\":\n\t\t\toptions.LogLevel = LevelInfo\n\t\tcase \"--log-level=warning\":\n\t\t\toptions.LogLevel = LevelWarning\n\t\tcase \"--log-level=error\":\n\t\t\toptions.LogLevel = LevelError\n\t\tcase \"--log-level=silent\":\n\t\t\toptions.LogLevel = LevelSilent\n\t\t}\n\t}\n\n\treturn options\n}\n\nfunc PrintMessageToStderr(osArgs []string, msg Msg) {\n\tlog := NewStderrLog(OutputOptionsForArgs(osArgs))\n\tlog.AddMsg(msg)\n\tlog.Done()\n}\n\ntype Colors struct {\n\tReset     string\n\tBold      string\n\tDim       string\n\tUnderline string\n\n\tRed   string\n\tGreen string\n\tBlue  string\n\n\tCyan    string\n\tMagenta string\n\tYellow  string\n\n\tRedBgRed     string\n\tRedBgWhite   string\n\tGreenBgGreen string\n\tGreenBgWhite string\n\tBlueBgBlue   string\n\tBlueBgWhite  string\n\n\tCyanBgCyan       string\n\tCyanBgBlack      string\n\tMagentaBgMagenta string\n\tMagentaBgBlack   string\n\tYellowBgYellow   string\n\tYellowBgBlack    string\n}\n\nvar TerminalColors = Colors{\n\tReset:     \"\\033[0m\",\n\tBold:      \"\\033[1m\",\n\tDim:       \"\\033[37m\",\n\tUnderline: \"\\033[4m\",\n\n\tRed:   \"\\033[31m\",\n\tGreen: \"\\033[32m\",\n\tBlue:  \"\\033[34m\",\n\n\tCyan:    \"\\033[36m\",\n\tMagenta: \"\\033[35m\",\n\tYellow:  \"\\033[33m\",\n\n\tRedBgRed:     \"\\033[41;31m\",\n\tRedBgWhite:   \"\\033[41;97m\",\n\tGreenBgGreen: \"\\033[42;32m\",\n\tGreenBgWhite: \"\\033[42;97m\",\n\tBlueBgBlue:   \"\\033[44;34m\",\n\tBlueBgWhite:  \"\\033[44;97m\",\n\n\tCyanBgCyan:       \"\\033[46;36m\",\n\tCyanBgBlack:      \"\\033[46;30m\",\n\tMagentaBgMagenta: \"\\033[45;35m\",\n\tMagentaBgBlack:   \"\\033[45;30m\",\n\tYellowBgYellow:   \"\\033[43;33m\",\n\tYellowBgBlack:    \"\\033[43;30m\",\n}\n\nfunc PrintText(file *os.File, level LogLevel, osArgs []string, callback func(Colors) string) {\n\toptions := OutputOptionsForArgs(osArgs)\n\n\t// Skip logging these if these logs are disabled\n\tif options.LogLevel > level {\n\t\treturn\n\t}\n\n\tPrintTextWithColor(file, options.Color, callback)\n}\n\nfunc PrintTextWithColor(file *os.File, useColor UseColor, callback func(Colors) string) {\n\tvar useColorEscapes bool\n\tswitch useColor {\n\tcase ColorNever:\n\t\tuseColorEscapes = false\n\tcase ColorAlways:\n\t\tuseColorEscapes = SupportsColorEscapes\n\tcase ColorIfTerminal:\n\t\tuseColorEscapes = GetTerminalInfo(file).UseColorEscapes\n\t}\n\n\tvar colors Colors\n\tif useColorEscapes {\n\t\tcolors = TerminalColors\n\t}\n\twriteStringWithColor(file, callback(colors))\n}\n\ntype SummaryTableEntry struct {\n\tDir         string\n\tBase        string\n\tSize        string\n\tBytes       int\n\tIsSourceMap bool\n}\n\n// This type is just so we can use Go's native sort function\ntype SummaryTable []SummaryTableEntry\n\nfunc (t SummaryTable) Len() int          { return len(t) }\nfunc (t SummaryTable) Swap(i int, j int) { t[i], t[j] = t[j], t[i] }\n\nfunc (t SummaryTable) Less(i int, j int) bool {\n\tti := t[i]\n\ttj := t[j]\n\n\t// Sort source maps last\n\tif !ti.IsSourceMap && tj.IsSourceMap {\n\t\treturn true\n\t}\n\tif ti.IsSourceMap && !tj.IsSourceMap {\n\t\treturn false\n\t}\n\n\t// Sort by size first\n\tif ti.Bytes > tj.Bytes {\n\t\treturn true\n\t}\n\tif ti.Bytes < tj.Bytes {\n\t\treturn false\n\t}\n\n\t// Sort alphabetically by directory first\n\tif ti.Dir < tj.Dir {\n\t\treturn true\n\t}\n\tif ti.Dir > tj.Dir {\n\t\treturn false\n\t}\n\n\t// Then sort alphabetically by file name\n\treturn ti.Base < tj.Base\n}\n\n// Show a warning icon next to output files that are 1mb or larger\nconst sizeWarningThreshold = 1024 * 1024\n\nfunc PrintSummary(useColor UseColor, table SummaryTable, start *time.Time) {\n\tPrintTextWithColor(os.Stderr, useColor, func(colors Colors) string {\n\t\tisProbablyWindowsCommandPrompt := isProbablyWindowsCommandPrompt()\n\t\tsb := strings.Builder{}\n\n\t\tif len(table) > 0 {\n\t\t\tinfo := GetTerminalInfo(os.Stderr)\n\n\t\t\t// Truncate the table in case it's really long\n\t\t\tmaxLength := info.Height / 2\n\t\t\tif info.Height == 0 {\n\t\t\t\tmaxLength = 20\n\t\t\t} else if maxLength < 5 {\n\t\t\t\tmaxLength = 5\n\t\t\t}\n\t\t\tlength := len(table)\n\t\t\tsort.Sort(table)\n\t\t\tif length > maxLength {\n\t\t\t\ttable = table[:maxLength]\n\t\t\t}\n\n\t\t\t// Compute the maximum width of the size column\n\t\t\tspacingBetweenColumns := 2\n\t\t\thasSizeWarning := false\n\t\t\tmaxPath := 0\n\t\t\tmaxSize := 0\n\t\t\tfor _, entry := range table {\n\t\t\t\tpath := len(entry.Dir) + len(entry.Base)\n\t\t\t\tsize := len(entry.Size) + spacingBetweenColumns\n\t\t\t\tif path > maxPath {\n\t\t\t\t\tmaxPath = path\n\t\t\t\t}\n\t\t\t\tif size > maxSize {\n\t\t\t\t\tmaxSize = size\n\t\t\t\t}\n\t\t\t\tif !entry.IsSourceMap && entry.Bytes >= sizeWarningThreshold {\n\t\t\t\t\thasSizeWarning = true\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tmargin := \"  \"\n\t\t\tlayoutWidth := info.Width\n\t\t\tif layoutWidth < 1 {\n\t\t\t\tlayoutWidth = defaultTerminalWidth\n\t\t\t}\n\t\t\tlayoutWidth -= 2 * len(margin)\n\t\t\tif hasSizeWarning {\n\t\t\t\t// Add space for the warning icon\n\t\t\t\tlayoutWidth -= 2\n\t\t\t}\n\t\t\tif layoutWidth > maxPath+maxSize {\n\t\t\t\tlayoutWidth = maxPath + maxSize\n\t\t\t}\n\t\t\tsb.WriteByte('\\n')\n\n\t\t\tfor _, entry := range table {\n\t\t\t\tdir, base := entry.Dir, entry.Base\n\t\t\t\tpathWidth := layoutWidth - maxSize\n\n\t\t\t\t// Truncate the path with \"...\" to fit on one line\n\t\t\t\tif len(dir)+len(base) > pathWidth {\n\t\t\t\t\t// Trim the directory from the front, leaving the trailing slash\n\t\t\t\t\tif len(dir) > 0 {\n\t\t\t\t\t\tn := pathWidth - len(base) - 3\n\t\t\t\t\t\tif n < 1 {\n\t\t\t\t\t\t\tn = 1\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdir = \"...\" + dir[len(dir)-n:]\n\t\t\t\t\t}\n\n\t\t\t\t\t// Trim the file name from the back\n\t\t\t\t\tif len(dir)+len(base) > pathWidth {\n\t\t\t\t\t\tn := pathWidth - len(dir) - 3\n\t\t\t\t\t\tif n < 0 {\n\t\t\t\t\t\t\tn = 0\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbase = base[:n] + \"...\"\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tspacer := layoutWidth - len(entry.Size) - len(dir) - len(base)\n\t\t\t\tif spacer < 0 {\n\t\t\t\t\tspacer = 0\n\t\t\t\t}\n\n\t\t\t\t// Put a warning next to the size if it's above a certain threshold\n\t\t\t\tsizeColor := colors.Cyan\n\t\t\t\tsizeWarning := \"\"\n\t\t\t\tif !entry.IsSourceMap && entry.Bytes >= sizeWarningThreshold {\n\t\t\t\t\tsizeColor = colors.Yellow\n\n\t\t\t\t\t// Emoji don't work in Windows Command Prompt\n\t\t\t\t\tif !isProbablyWindowsCommandPrompt {\n\t\t\t\t\t\tsizeWarning = \" ⚠️\"\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsb.WriteString(fmt.Sprintf(\"%s%s%s%s%s%s%s%s%s%s%s%s\\n\",\n\t\t\t\t\tmargin,\n\t\t\t\t\tcolors.Dim,\n\t\t\t\t\tdir,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tcolors.Bold,\n\t\t\t\t\tbase,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t\tstrings.Repeat(\" \", spacer),\n\t\t\t\t\tsizeColor,\n\t\t\t\t\tentry.Size,\n\t\t\t\t\tsizeWarning,\n\t\t\t\t\tcolors.Reset,\n\t\t\t\t))\n\t\t\t}\n\n\t\t\t// Say how many remaining files are not shown\n\t\t\tif length > maxLength {\n\t\t\t\tplural := \"s\"\n\t\t\t\tif length == maxLength+1 {\n\t\t\t\t\tplural = \"\"\n\t\t\t\t}\n\t\t\t\tsb.WriteString(fmt.Sprintf(\"%s%s...and %d more output file%s...%s\\n\", margin, colors.Dim, length-maxLength, plural, colors.Reset))\n\t\t\t}\n\t\t}\n\t\tsb.WriteByte('\\n')\n\n\t\tlightningSymbol := \"⚡ \"\n\n\t\t// Emoji don't work in Windows Command Prompt\n\t\tif isProbablyWindowsCommandPrompt {\n\t\t\tlightningSymbol = \"\"\n\t\t}\n\n\t\t// Printing the time taken is optional\n\t\tif start != nil {\n\t\t\tsb.WriteString(fmt.Sprintf(\"%s%sDone in %dms%s\\n\",\n\t\t\t\tlightningSymbol,\n\t\t\t\tcolors.Green,\n\t\t\t\ttime.Since(*start).Milliseconds(),\n\t\t\t\tcolors.Reset,\n\t\t\t))\n\t\t}\n\n\t\treturn sb.String()\n\t})\n}\n\ntype DeferLogKind uint8\n\nconst (\n\tDeferLogAll DeferLogKind = iota\n\tDeferLogNoVerboseOrDebug\n)\n\nfunc NewDeferLog(kind DeferLogKind) Log {\n\tvar msgs SortableMsgs\n\tvar mutex sync.Mutex\n\tvar hasErrors bool\n\n\treturn Log{\n\t\tLevel: LevelInfo,\n\n\t\tAddMsg: func(msg Msg) {\n\t\t\tif kind == DeferLogNoVerboseOrDebug && (msg.Kind == Verbose || msg.Kind == Debug) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tif msg.Kind == Error {\n\t\t\t\thasErrors = true\n\t\t\t}\n\t\t\tmsgs = append(msgs, msg)\n\t\t},\n\n\t\tHasErrors: func() bool {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\treturn hasErrors\n\t\t},\n\n\t\tAlmostDone: func() {\n\t\t},\n\n\t\tDone: func() []Msg {\n\t\t\tmutex.Lock()\n\t\t\tdefer mutex.Unlock()\n\t\t\tsort.Stable(msgs)\n\t\t\treturn msgs\n\t\t},\n\t}\n}\n\ntype UseColor uint8\n\nconst (\n\tColorIfTerminal UseColor = iota\n\tColorNever\n\tColorAlways\n)\n\ntype OutputOptions struct {\n\tMessageLimit  int\n\tIncludeSource bool\n\tColor         UseColor\n\tLogLevel      LogLevel\n}\n\nfunc (msg Msg) String(options OutputOptions, terminalInfo TerminalInfo) string {\n\t// Format the message\n\ttext := msgString(options.IncludeSource, terminalInfo, msg.Kind, msg.Data, msg.PluginName)\n\n\t// Format the notes\n\tvar oldData MsgData\n\tfor i, note := range msg.Notes {\n\t\tif options.IncludeSource && (i == 0 || strings.IndexByte(oldData.Text, '\\n') >= 0 || oldData.Location != nil) {\n\t\t\ttext += \"\\n\"\n\t\t}\n\t\ttext += msgString(options.IncludeSource, terminalInfo, Note, note, \"\")\n\t\toldData = note\n\t}\n\n\t// Add extra spacing between messages if source code is present\n\tif options.IncludeSource {\n\t\ttext += \"\\n\"\n\t}\n\treturn text\n}\n\n// The number of margin characters in addition to the line number\nconst extraMarginChars = 9\n\nfunc marginWithLineText(maxMargin int, line int) string {\n\tnumber := fmt.Sprintf(\"%d\", line)\n\treturn fmt.Sprintf(\"      %s%s │ \", strings.Repeat(\" \", maxMargin-len(number)), number)\n}\n\nfunc emptyMarginText(maxMargin int, isLast bool) string {\n\tspace := strings.Repeat(\" \", maxMargin)\n\tif isLast {\n\t\treturn fmt.Sprintf(\"      %s ╵ \", space)\n\t}\n\treturn fmt.Sprintf(\"      %s │ \", space)\n}\n\nfunc msgString(includeSource bool, terminalInfo TerminalInfo, kind MsgKind, data MsgData, pluginName string) string {\n\tif !includeSource {\n\t\tif loc := data.Location; loc != nil {\n\t\t\treturn fmt.Sprintf(\"%s: %s: %s\\n\", loc.File, kind.String(), data.Text)\n\t\t}\n\t\treturn fmt.Sprintf(\"%s: %s\\n\", kind.String(), data.Text)\n\t}\n\n\tvar colors Colors\n\tif terminalInfo.UseColorEscapes {\n\t\tcolors = TerminalColors\n\t}\n\n\tvar iconColor string\n\tvar kindColorBrackets string\n\tvar kindColorText string\n\n\tlocation := \"\"\n\n\tif data.Location != nil {\n\t\tmaxMargin := len(fmt.Sprintf(\"%d\", data.Location.Line))\n\t\td := detailStruct(data, terminalInfo, maxMargin)\n\n\t\tif d.Suggestion != \"\" {\n\t\t\tlocation = fmt.Sprintf(\"\\n    %s:%d:%d:\\n%s%s%s%s%s%s\\n%s%s%s%s%s\\n%s%s%s%s%s\\n%s\",\n\t\t\t\td.Path, d.Line, d.Column,\n\t\t\t\tcolors.Dim, d.SourceBefore, colors.Green, d.SourceMarked, colors.Dim, d.SourceAfter,\n\t\t\t\temptyMarginText(maxMargin, false), d.Indent, colors.Green, d.Marker, colors.Dim,\n\t\t\t\temptyMarginText(maxMargin, true), d.Indent, colors.Green, d.Suggestion, colors.Reset,\n\t\t\t\td.ContentAfter,\n\t\t\t)\n\t\t} else {\n\t\t\tlocation = fmt.Sprintf(\"\\n    %s:%d:%d:\\n%s%s%s%s%s%s\\n%s%s%s%s%s\\n%s\",\n\t\t\t\td.Path, d.Line, d.Column,\n\t\t\t\tcolors.Dim, d.SourceBefore, colors.Green, d.SourceMarked, colors.Dim, d.SourceAfter,\n\t\t\t\temptyMarginText(maxMargin, true), d.Indent, colors.Green, d.Marker, colors.Reset,\n\t\t\t\td.ContentAfter,\n\t\t\t)\n\t\t}\n\t}\n\n\tswitch kind {\n\tcase Verbose:\n\t\ticonColor = colors.Cyan\n\t\tkindColorBrackets = colors.CyanBgCyan\n\t\tkindColorText = colors.CyanBgBlack\n\n\tcase Debug:\n\t\ticonColor = colors.Green\n\t\tkindColorBrackets = colors.GreenBgGreen\n\t\tkindColorText = colors.GreenBgWhite\n\n\tcase Info:\n\t\ticonColor = colors.Blue\n\t\tkindColorBrackets = colors.BlueBgBlue\n\t\tkindColorText = colors.BlueBgWhite\n\n\tcase Error:\n\t\ticonColor = colors.Red\n\t\tkindColorBrackets = colors.RedBgRed\n\t\tkindColorText = colors.RedBgWhite\n\n\tcase Warning:\n\t\ticonColor = colors.Yellow\n\t\tkindColorBrackets = colors.YellowBgYellow\n\t\tkindColorText = colors.YellowBgBlack\n\n\tcase Note:\n\t\tsb := strings.Builder{}\n\n\t\tfor _, line := range strings.Split(data.Text, \"\\n\") {\n\t\t\t// Special-case word wrapping\n\t\t\tif wrapWidth := terminalInfo.Width; wrapWidth > 2 {\n\t\t\t\tif !data.DisableMaximumWidth && wrapWidth > 100 {\n\t\t\t\t\twrapWidth = 100 // Enforce a maximum paragraph width for readability\n\t\t\t\t}\n\t\t\t\tfor _, run := range wrapWordsInString(line, wrapWidth-2) {\n\t\t\t\t\tsb.WriteString(\"  \")\n\t\t\t\t\tsb.WriteString(linkifyText(run, colors.Underline, colors.Reset))\n\t\t\t\t\tsb.WriteByte('\\n')\n\t\t\t\t}\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// Otherwise, just write an indented line\n\t\t\tsb.WriteString(\"  \")\n\t\t\tsb.WriteString(linkifyText(line, colors.Underline, colors.Reset))\n\t\t\tsb.WriteByte('\\n')\n\t\t}\n\n\t\tsb.WriteString(location)\n\t\treturn sb.String()\n\t}\n\n\tif pluginName != \"\" {\n\t\tpluginName = fmt.Sprintf(\"%s%s[plugin %s]%s \", colors.Bold, colors.Magenta, pluginName, colors.Reset)\n\t}\n\n\treturn fmt.Sprintf(\"%s%s %s[%s%s%s]%s %s%s%s%s\\n%s\",\n\t\ticonColor, kind.Icon(),\n\t\tkindColorBrackets, kindColorText, kind.String(), kindColorBrackets, colors.Reset,\n\t\tpluginName,\n\t\tcolors.Bold, data.Text, colors.Reset,\n\t\tlocation,\n\t)\n}\n\nfunc linkifyText(text string, underline string, reset string) string {\n\tif underline == \"\" {\n\t\treturn text\n\t}\n\n\thttps := strings.Index(text, \"https://\")\n\tif https == -1 {\n\t\treturn text\n\t}\n\n\tsb := strings.Builder{}\n\tfor {\n\t\thttps := strings.Index(text, \"https://\")\n\t\tif https == -1 {\n\t\t\tbreak\n\t\t}\n\n\t\tend := strings.IndexByte(text[https:], ' ')\n\t\tif end == -1 {\n\t\t\tend = len(text)\n\t\t} else {\n\t\t\tend += https\n\t\t}\n\n\t\t// Remove trailing punctuation\n\t\tif end > https {\n\t\t\tswitch text[end-1] {\n\t\t\tcase '.', ',', '?', '!', ')', ']', '}':\n\t\t\t\tend--\n\t\t\t}\n\t\t}\n\n\t\tsb.WriteString(text[:https])\n\t\tsb.WriteString(underline)\n\t\tsb.WriteString(text[https:end])\n\t\tsb.WriteString(reset)\n\t\ttext = text[end:]\n\t}\n\n\tsb.WriteString(text)\n\treturn sb.String()\n}\n\nfunc wrapWordsInString(text string, width int) []string {\n\truns := []string{}\n\nouter:\n\tfor text != \"\" {\n\t\ti := 0\n\t\tx := 0\n\t\twordEndI := 0\n\n\t\t// Skip over any leading spaces\n\t\tfor i < len(text) && text[i] == ' ' {\n\t\t\ti++\n\t\t\tx++\n\t\t}\n\n\t\t// Find out how many words will fit in this run\n\t\tfor i < len(text) {\n\t\t\toldWordEndI := wordEndI\n\t\t\twordStartI := i\n\n\t\t\t// Find the end of the word\n\t\t\tfor i < len(text) {\n\t\t\t\tc, width := utf8.DecodeRuneInString(text[i:])\n\t\t\t\tif c == ' ' {\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\ti += width\n\t\t\t\tx += 1 // Naively assume that each unicode code point is a single column\n\t\t\t}\n\t\t\twordEndI = i\n\n\t\t\t// Split into a new run if this isn't the first word in the run and the end is past the width\n\t\t\tif wordStartI > 0 && x > width {\n\t\t\t\truns = append(runs, text[:oldWordEndI])\n\t\t\t\ttext = text[wordStartI:]\n\t\t\t\tcontinue outer\n\t\t\t}\n\n\t\t\t// Skip over any spaces after the word\n\t\t\tfor i < len(text) && text[i] == ' ' {\n\t\t\t\ti++\n\t\t\t\tx++\n\t\t\t}\n\t\t}\n\n\t\t// If we get here, this is the last run (i.e. everything fits)\n\t\tbreak\n\t}\n\n\t// Remove any trailing spaces on the last run\n\tfor len(text) > 0 && text[len(text)-1] == ' ' {\n\t\ttext = text[:len(text)-1]\n\t}\n\truns = append(runs, text)\n\treturn runs\n}\n\ntype MsgDetail struct {\n\tSourceBefore string\n\tSourceMarked string\n\tSourceAfter  string\n\n\tIndent     string\n\tMarker     string\n\tSuggestion string\n\n\tContentAfter string\n\n\tPath   string\n\tLine   int\n\tColumn int\n}\n\n// It's not common for large files to have many warnings. But when it happens,\n// we want to make sure that it's not too slow. Source code locations are\n// represented as byte offsets for compactness but transforming these to\n// line/column locations for warning messages requires scanning through the\n// file. A naive approach for this would cause O(n^2) scanning time for n\n// warnings distributed throughout the file.\n//\n// Warnings are typically generated sequentially as the file is scanned. So\n// one way of optimizing this is to just start scanning from where we left\n// off last time instead of always starting from the beginning of the file.\n// That's what this object does.\n//\n// Another option could be to eagerly populate an array of line/column offsets\n// and then use binary search for each query. This might slow down the common\n// case of a file with only at most a few warnings though, so think before\n// optimizing too much. Performance in the zero or one warning case is by far\n// the most important.\ntype LineColumnTracker struct {\n\tcontents     string\n\tprettyPath   string\n\toffset       int32\n\tline         int32\n\tlineStart    int32\n\tlineEnd      int32\n\thasLineStart bool\n\thasLineEnd   bool\n\thasSource    bool\n}\n\nfunc MakeLineColumnTracker(source *Source) LineColumnTracker {\n\tif source == nil {\n\t\treturn LineColumnTracker{\n\t\t\thasSource: false,\n\t\t}\n\t}\n\n\treturn LineColumnTracker{\n\t\tcontents:     source.Contents,\n\t\tprettyPath:   source.PrettyPath,\n\t\thasLineStart: true,\n\t\thasSource:    true,\n\t}\n}\n\nfunc (tracker *LineColumnTracker) MsgData(r Range, text string) MsgData {\n\treturn MsgData{\n\t\tText:     text,\n\t\tLocation: tracker.MsgLocationOrNil(r),\n\t}\n}\n\nfunc (t *LineColumnTracker) scanTo(offset int32) {\n\tcontents := t.contents\n\ti := t.offset\n\n\t// Scan forward\n\tif i < offset {\n\t\tfor {\n\t\t\tr, size := utf8.DecodeRuneInString(contents[i:])\n\t\t\ti += int32(size)\n\n\t\t\tswitch r {\n\t\t\tcase '\\n':\n\t\t\t\tt.hasLineStart = true\n\t\t\t\tt.hasLineEnd = false\n\t\t\t\tt.lineStart = i\n\t\t\t\tif i == int32(size) || contents[i-int32(size)-1] != '\\r' {\n\t\t\t\t\tt.line++\n\t\t\t\t}\n\n\t\t\tcase '\\r', '\\u2028', '\\u2029':\n\t\t\t\tt.hasLineStart = true\n\t\t\t\tt.hasLineEnd = false\n\t\t\t\tt.lineStart = i\n\t\t\t\tt.line++\n\t\t\t}\n\n\t\t\tif i >= offset {\n\t\t\t\tt.offset = i\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// Scan backward\n\tif i > offset {\n\t\tfor {\n\t\t\tr, size := utf8.DecodeLastRuneInString(contents[:i])\n\t\t\ti -= int32(size)\n\n\t\t\tswitch r {\n\t\t\tcase '\\n':\n\t\t\t\tt.hasLineStart = false\n\t\t\t\tt.hasLineEnd = true\n\t\t\t\tt.lineEnd = i\n\t\t\t\tif i == 0 || contents[i-1] != '\\r' {\n\t\t\t\t\tt.line--\n\t\t\t\t}\n\n\t\t\tcase '\\r', '\\u2028', '\\u2029':\n\t\t\t\tt.hasLineStart = false\n\t\t\t\tt.hasLineEnd = true\n\t\t\t\tt.lineEnd = i\n\t\t\t\tt.line--\n\t\t\t}\n\n\t\t\tif i <= offset {\n\t\t\t\tt.offset = i\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc (t *LineColumnTracker) computeLineAndColumn(offset int) (lineCount int, columnCount int, lineStart int, lineEnd int) {\n\tt.scanTo(int32(offset))\n\n\t// Scan for the start of the line\n\tif !t.hasLineStart {\n\t\tcontents := t.contents\n\t\ti := t.offset\n\t\tfor i > 0 {\n\t\t\tr, size := utf8.DecodeLastRuneInString(contents[:i])\n\t\t\tif r == '\\n' || r == '\\r' || r == '\\u2028' || r == '\\u2029' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ti -= int32(size)\n\t\t}\n\t\tt.hasLineStart = true\n\t\tt.lineStart = i\n\t}\n\n\t// Scan for the end of the line\n\tif !t.hasLineEnd {\n\t\tcontents := t.contents\n\t\ti := t.offset\n\t\tn := int32(len(contents))\n\t\tfor i < n {\n\t\t\tr, size := utf8.DecodeRuneInString(contents[i:])\n\t\t\tif r == '\\n' || r == '\\r' || r == '\\u2028' || r == '\\u2029' {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\ti += int32(size)\n\t\t}\n\t\tt.hasLineEnd = true\n\t\tt.lineEnd = i\n\t}\n\n\treturn int(t.line), offset - int(t.lineStart), int(t.lineStart), int(t.lineEnd)\n}\n\nfunc (tracker *LineColumnTracker) MsgLocationOrNil(r Range) *MsgLocation {\n\tif tracker == nil || !tracker.hasSource {\n\t\treturn nil\n\t}\n\n\t// Convert the index into a line and column number\n\tlineCount, columnCount, lineStart, lineEnd := tracker.computeLineAndColumn(int(r.Loc.Start))\n\n\treturn &MsgLocation{\n\t\tFile:     tracker.prettyPath,\n\t\tLine:     lineCount + 1, // 0-based to 1-based\n\t\tColumn:   columnCount,\n\t\tLength:   int(r.Len),\n\t\tLineText: tracker.contents[lineStart:lineEnd],\n\t}\n}\n\nfunc detailStruct(data MsgData, terminalInfo TerminalInfo, maxMargin int) MsgDetail {\n\t// Only highlight the first line of the line text\n\tloc := *data.Location\n\tendOfFirstLine := len(loc.LineText)\n\tfor i, c := range loc.LineText {\n\t\tif c == '\\r' || c == '\\n' || c == '\\u2028' || c == '\\u2029' {\n\t\t\tendOfFirstLine = i\n\t\t\tbreak\n\t\t}\n\t}\n\tfirstLine := loc.LineText[:endOfFirstLine]\n\tafterFirstLine := loc.LineText[endOfFirstLine:]\n\tif afterFirstLine != \"\" && !strings.HasSuffix(afterFirstLine, \"\\n\") {\n\t\tafterFirstLine += \"\\n\"\n\t}\n\n\t// Clamp values in range\n\tif loc.Line < 0 {\n\t\tloc.Line = 0\n\t}\n\tif loc.Column < 0 {\n\t\tloc.Column = 0\n\t}\n\tif loc.Length < 0 {\n\t\tloc.Length = 0\n\t}\n\tif loc.Column > endOfFirstLine {\n\t\tloc.Column = endOfFirstLine\n\t}\n\tif loc.Length > endOfFirstLine-loc.Column {\n\t\tloc.Length = endOfFirstLine - loc.Column\n\t}\n\n\tspacesPerTab := 2\n\tlineText := renderTabStops(firstLine, spacesPerTab)\n\ttextUpToLoc := renderTabStops(firstLine[:loc.Column], spacesPerTab)\n\tmarkerStart := len(textUpToLoc)\n\tmarkerEnd := markerStart\n\tindent := strings.Repeat(\" \", estimateWidthInTerminal(textUpToLoc))\n\tmarker := \"^\"\n\n\t// Extend markers to cover the full range of the error\n\tif loc.Length > 0 {\n\t\tmarkerEnd = len(renderTabStops(firstLine[:loc.Column+loc.Length], spacesPerTab))\n\t}\n\n\t// Clip the marker to the bounds of the line\n\tif markerStart > len(lineText) {\n\t\tmarkerStart = len(lineText)\n\t}\n\tif markerEnd > len(lineText) {\n\t\tmarkerEnd = len(lineText)\n\t}\n\tif markerEnd < markerStart {\n\t\tmarkerEnd = markerStart\n\t}\n\n\t// Trim the line to fit the terminal width\n\twidth := terminalInfo.Width\n\tif width < 1 {\n\t\twidth = defaultTerminalWidth\n\t}\n\twidth -= maxMargin + extraMarginChars\n\tif width < 1 {\n\t\twidth = 1\n\t}\n\tif loc.Column == endOfFirstLine {\n\t\t// If the marker is at the very end of the line, the marker will be a \"^\"\n\t\t// character that extends one column past the end of the line. In this case\n\t\t// we should reserve a column at the end so the marker doesn't wrap.\n\t\twidth -= 1\n\t}\n\tif len(lineText) > width {\n\t\t// Try to center the error\n\t\tsliceStart := (markerStart + markerEnd - width) / 2\n\t\tif sliceStart > markerStart-width/5 {\n\t\t\tsliceStart = markerStart - width/5\n\t\t}\n\t\tif sliceStart < 0 {\n\t\t\tsliceStart = 0\n\t\t}\n\t\tif sliceStart > len(lineText)-width {\n\t\t\tsliceStart = len(lineText) - width\n\t\t}\n\t\tsliceEnd := sliceStart + width\n\n\t\t// Slice the line\n\t\tslicedLine := lineText[sliceStart:sliceEnd]\n\t\tmarkerStart -= sliceStart\n\t\tmarkerEnd -= sliceStart\n\t\tif markerStart < 0 {\n\t\t\tmarkerStart = 0\n\t\t}\n\t\tif markerEnd > len(slicedLine) {\n\t\t\tmarkerEnd = len(slicedLine)\n\t\t}\n\n\t\t// Truncate the ends with \"...\"\n\t\tif len(slicedLine) > 3 && sliceStart > 0 {\n\t\t\tslicedLine = \"...\" + slicedLine[3:]\n\t\t\tif markerStart < 3 {\n\t\t\t\tmarkerStart = 3\n\t\t\t}\n\t\t}\n\t\tif len(slicedLine) > 3 && sliceEnd < len(lineText) {\n\t\t\tslicedLine = slicedLine[:len(slicedLine)-3] + \"...\"\n\t\t\tif markerEnd > len(slicedLine)-3 {\n\t\t\t\tmarkerEnd = len(slicedLine) - 3\n\t\t\t}\n\t\t\tif markerEnd < markerStart {\n\t\t\t\tmarkerEnd = markerStart\n\t\t\t}\n\t\t}\n\n\t\t// Now we can compute the indent\n\t\tlineText = slicedLine\n\t\tindent = strings.Repeat(\" \", estimateWidthInTerminal(lineText[:markerStart]))\n\t}\n\n\t// If marker is still multi-character after clipping, make the marker wider\n\tif markerEnd-markerStart > 1 {\n\t\tmarker = strings.Repeat(\"~\", estimateWidthInTerminal(lineText[markerStart:markerEnd]))\n\t}\n\n\t// Put a margin before the marker indent\n\tmargin := marginWithLineText(maxMargin, loc.Line)\n\n\treturn MsgDetail{\n\t\tPath:   loc.File,\n\t\tLine:   loc.Line,\n\t\tColumn: loc.Column,\n\n\t\tSourceBefore: margin + lineText[:markerStart],\n\t\tSourceMarked: lineText[markerStart:markerEnd],\n\t\tSourceAfter:  lineText[markerEnd:],\n\n\t\tIndent:     indent,\n\t\tMarker:     marker,\n\t\tSuggestion: loc.Suggestion,\n\n\t\tContentAfter: afterFirstLine,\n\t}\n}\n\n// Estimate the number of columns this string will take when printed\nfunc estimateWidthInTerminal(text string) int {\n\t// For now just assume each code point is one column. This is wrong but is\n\t// less wrong than assuming each code unit is one column.\n\twidth := 0\n\tfor text != \"\" {\n\t\tc, size := utf8.DecodeRuneInString(text)\n\t\ttext = text[size:]\n\n\t\t// Ignore the Zero Width No-Break Space character (UTF-8 BOM)\n\t\tif c != 0xFEFF {\n\t\t\twidth++\n\t\t}\n\t}\n\treturn width\n}\n\nfunc renderTabStops(withTabs string, spacesPerTab int) string {\n\tif !strings.ContainsRune(withTabs, '\\t') {\n\t\treturn withTabs\n\t}\n\n\twithoutTabs := strings.Builder{}\n\tcount := 0\n\n\tfor _, c := range withTabs {\n\t\tif c == '\\t' {\n\t\t\tspaces := spacesPerTab - count%spacesPerTab\n\t\t\tfor i := 0; i < spaces; i++ {\n\t\t\t\twithoutTabs.WriteRune(' ')\n\t\t\t\tcount++\n\t\t\t}\n\t\t} else {\n\t\t\twithoutTabs.WriteRune(c)\n\t\t\tcount++\n\t\t}\n\t}\n\n\treturn withoutTabs.String()\n}\n\nfunc (log Log) Add(kind MsgKind, tracker *LineColumnTracker, r Range, text string) {\n\tlog.AddMsg(Msg{\n\t\tKind: kind,\n\t\tData: tracker.MsgData(r, text),\n\t})\n}\n\nfunc (log Log) AddWithNotes(kind MsgKind, tracker *LineColumnTracker, r Range, text string, notes []MsgData) {\n\tlog.AddMsg(Msg{\n\t\tKind:  kind,\n\t\tData:  tracker.MsgData(r, text),\n\t\tNotes: notes,\n\t})\n}\n"
  },
  {
    "path": "lib/esbuild/logger/logger_darwin.go",
    "content": "//go:build darwin\n// +build darwin\n\npackage logger\n\nimport (\n\t\"os\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst SupportsColorEscapes = true\n\nfunc GetTerminalInfo(file *os.File) (info TerminalInfo) {\n\tfd := file.Fd()\n\n\t// Is this file descriptor a terminal?\n\tif _, err := unix.IoctlGetTermios(int(fd), unix.TIOCGETA); err == nil {\n\t\tinfo.IsTTY = true\n\t\tinfo.UseColorEscapes = !hasNoColorEnvironmentVariable()\n\n\t\t// Get the width of the window\n\t\tif w, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ); err == nil {\n\t\t\tinfo.Width = int(w.Col)\n\t\t\tinfo.Height = int(w.Row)\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "lib/esbuild/logger/logger_linux.go",
    "content": "//go:build linux\n// +build linux\n\npackage logger\n\nimport (\n\t\"os\"\n\n\t\"golang.org/x/sys/unix\"\n)\n\nconst SupportsColorEscapes = true\n\nfunc GetTerminalInfo(file *os.File) (info TerminalInfo) {\n\tfd := file.Fd()\n\n\t// Is this file descriptor a terminal?\n\tif _, err := unix.IoctlGetTermios(int(fd), unix.TCGETS); err == nil {\n\t\tinfo.IsTTY = true\n\t\tinfo.UseColorEscapes = !hasNoColorEnvironmentVariable()\n\n\t\t// Get the width of the window\n\t\tif w, err := unix.IoctlGetWinsize(int(fd), unix.TIOCGWINSZ); err == nil {\n\t\t\tinfo.Width = int(w.Col)\n\t\t\tinfo.Height = int(w.Row)\n\t\t}\n\t}\n\n\treturn\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "lib/esbuild/logger/logger_other.go",
    "content": "//go:build !darwin && !linux && !windows\n// +build !darwin,!linux,!windows\n\npackage logger\n\nimport \"os\"\n\nconst SupportsColorEscapes = false\n\nfunc GetTerminalInfo(*os.File) TerminalInfo {\n\treturn TerminalInfo{}\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "lib/esbuild/logger/logger_windows.go",
    "content": "//go:build windows\n// +build windows\n\npackage logger\n\nimport (\n\t\"os\"\n\t\"strings\"\n\t\"syscall\"\n\t\"unsafe\"\n)\n\nconst SupportsColorEscapes = true\n\nvar kernel32 = syscall.NewLazyDLL(\"kernel32.dll\")\nvar getConsoleMode = kernel32.NewProc(\"GetConsoleMode\")\nvar setConsoleTextAttribute = kernel32.NewProc(\"SetConsoleTextAttribute\")\nvar getConsoleScreenBufferInfo = kernel32.NewProc(\"GetConsoleScreenBufferInfo\")\n\ntype consoleScreenBufferInfo struct {\n\tdwSizeX              int16\n\tdwSizeY              int16\n\tdwCursorPositionX    int16\n\tdwCursorPositionY    int16\n\twAttributes          uint16\n\tsrWindowLeft         int16\n\tsrWindowTop          int16\n\tsrWindowRight        int16\n\tsrWindowBottom       int16\n\tdwMaximumWindowSizeX int16\n\tdwMaximumWindowSizeY int16\n}\n\nfunc GetTerminalInfo(file *os.File) TerminalInfo {\n\tfd := file.Fd()\n\n\t// Is this file descriptor a terminal?\n\tvar unused uint32\n\tisTTY, _, _ := syscall.Syscall(getConsoleMode.Addr(), 2, fd, uintptr(unsafe.Pointer(&unused)), 0)\n\n\t// Get the width of the window\n\tvar info consoleScreenBufferInfo\n\tsyscall.Syscall(getConsoleScreenBufferInfo.Addr(), 2, fd, uintptr(unsafe.Pointer(&info)), 0)\n\n\treturn TerminalInfo{\n\t\tIsTTY:           isTTY != 0,\n\t\tWidth:           int(info.dwSizeX) - 1,\n\t\tHeight:          int(info.dwSizeY) - 1,\n\t\tUseColorEscapes: !hasNoColorEnvironmentVariable(),\n\t}\n}\n\nconst (\n\tFOREGROUND_BLUE uint8 = 1 << iota\n\tFOREGROUND_GREEN\n\tFOREGROUND_RED\n\tFOREGROUND_INTENSITY\n\tBACKGROUND_BLUE\n\tBACKGROUND_GREEN\n\tBACKGROUND_RED\n\tBACKGROUND_INTENSITY\n)\n\nvar windowsEscapeSequenceMap = map[string]uint8{\n\tTerminalColors.Reset: FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,\n\tTerminalColors.Dim:   FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,\n\tTerminalColors.Bold:  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,\n\n\t// Apparently underlines only work with the CJK locale on Windows :(\n\tTerminalColors.Underline: FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,\n\n\tTerminalColors.Red:   FOREGROUND_RED,\n\tTerminalColors.Green: FOREGROUND_GREEN,\n\tTerminalColors.Blue:  FOREGROUND_BLUE,\n\n\tTerminalColors.Cyan:    FOREGROUND_GREEN | FOREGROUND_BLUE,\n\tTerminalColors.Magenta: FOREGROUND_RED | FOREGROUND_BLUE,\n\tTerminalColors.Yellow:  FOREGROUND_RED | FOREGROUND_GREEN,\n\n\tTerminalColors.RedBgRed:     FOREGROUND_RED | BACKGROUND_RED,\n\tTerminalColors.RedBgWhite:   FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_RED,\n\tTerminalColors.GreenBgGreen: FOREGROUND_GREEN | BACKGROUND_GREEN,\n\tTerminalColors.GreenBgWhite: FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_GREEN,\n\tTerminalColors.BlueBgBlue:   FOREGROUND_BLUE | BACKGROUND_BLUE,\n\tTerminalColors.BlueBgWhite:  FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_BLUE,\n\n\tTerminalColors.CyanBgCyan:       FOREGROUND_GREEN | FOREGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_BLUE,\n\tTerminalColors.CyanBgBlack:      BACKGROUND_GREEN | BACKGROUND_BLUE,\n\tTerminalColors.MagentaBgMagenta: FOREGROUND_RED | FOREGROUND_BLUE | BACKGROUND_RED | BACKGROUND_BLUE,\n\tTerminalColors.MagentaBgBlack:   BACKGROUND_RED | BACKGROUND_BLUE,\n\tTerminalColors.YellowBgYellow:   FOREGROUND_RED | FOREGROUND_GREEN | BACKGROUND_RED | BACKGROUND_GREEN,\n\tTerminalColors.YellowBgBlack:    BACKGROUND_RED | BACKGROUND_GREEN,\n}\n\nfunc writeStringWithColor(file *os.File, text string) {\n\tfd := file.Fd()\n\ti := 0\n\n\tfor i < len(text) {\n\t\t// Find the escape\n\t\tif text[i] != 033 {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\t// Find the 'm'\n\t\twindow := text[i:]\n\t\tif len(window) > 8 {\n\t\t\twindow = window[:8]\n\t\t}\n\t\tm := strings.IndexByte(window, 'm')\n\t\tif m == -1 {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\t\tm += i + 1\n\n\t\t// Find the escape sequence\n\t\tattributes, ok := windowsEscapeSequenceMap[text[i:m]]\n\t\tif !ok {\n\t\t\ti++\n\t\t\tcontinue\n\t\t}\n\n\t\t// Write out the text before the escape sequence\n\t\tfile.WriteString(text[:i])\n\n\t\t// Apply the escape sequence\n\t\ttext = text[m:]\n\t\ti = 0\n\t\tsetConsoleTextAttribute.Call(fd, uintptr(attributes))\n\t}\n\n\t// Write out the remaining text\n\tfile.WriteString(text)\n}\n"
  },
  {
    "path": "lib/esbuild/sourcemap/sourcemap.go",
    "content": "package sourcemap\n\nimport (\n\t\"bytes\"\n\t\"unicode/utf8\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/helpers\"\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\ntype Mapping struct {\n\tGeneratedLine   int32 // 0-based\n\tGeneratedColumn int32 // 0-based count of UTF-16 code units\n\n\tSourceIndex    int32 // 0-based\n\tOriginalLine   int32 // 0-based\n\tOriginalColumn int32 // 0-based count of UTF-16 code units\n}\n\ntype SourceMap struct {\n\tSources        []string\n\tSourcesContent []SourceContent\n\tMappings       []Mapping\n}\n\ntype SourceContent struct {\n\t// This stores both the unquoted and the quoted values. We try to use the\n\t// already-quoted value if possible so we don't need to re-quote it\n\t// unnecessarily for maximum performance.\n\tQuoted string\n\n\t// But sometimes we need to re-quote the value, such as when it contains\n\t// non-ASCII characters and we are in ASCII-only mode. In that case we quote\n\t// this parsed UTF-16 value.\n\tValue []uint16\n}\n\nfunc (sm *SourceMap) Find(line int32, column int32) *Mapping {\n\tmappings := sm.Mappings\n\n\t// Binary search\n\tcount := len(mappings)\n\tindex := 0\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := index + step\n\t\tmapping := mappings[i]\n\t\tif mapping.GeneratedLine < line || (mapping.GeneratedLine == line && mapping.GeneratedColumn <= column) {\n\t\t\tindex = i + 1\n\t\t\tcount -= step + 1\n\t\t} else {\n\t\t\tcount = step\n\t\t}\n\t}\n\n\t// Handle search failure\n\tif index > 0 {\n\t\tmapping := &mappings[index-1]\n\n\t\t// Match the behavior of the popular \"source-map\" library from Mozilla\n\t\tif mapping.GeneratedLine == line {\n\t\t\treturn mapping\n\t\t}\n\t}\n\treturn nil\n}\n\nvar base64 = []byte(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\")\n\n// A single base 64 digit can contain 6 bits of data. For the base 64 variable\n// length quantities we use in the source map spec, the first bit is the sign,\n// the next four bits are the actual value, and the 6th bit is the continuation\n// bit. The continuation bit tells us whether there are more digits in this\n// value following this digit.\n//\n//   Continuation\n//   |    Sign\n//   |    |\n//   V    V\n//   101011\n//\nfunc EncodeVLQ(value int) []byte {\n\tvar vlq int\n\tif value < 0 {\n\t\tvlq = ((-value) << 1) | 1\n\t} else {\n\t\tvlq = value << 1\n\t}\n\n\t// Handle the common case up front without allocations\n\tif (vlq >> 5) == 0 {\n\t\tdigit := vlq & 31\n\t\treturn base64[digit : digit+1]\n\t}\n\n\tencoded := []byte{}\n\tfor {\n\t\tdigit := vlq & 31\n\t\tvlq >>= 5\n\n\t\t// If there are still more digits in this value, we must make sure the\n\t\t// continuation bit is marked\n\t\tif vlq != 0 {\n\t\t\tdigit |= 32\n\t\t}\n\n\t\tencoded = append(encoded, base64[digit])\n\n\t\tif vlq == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\treturn encoded\n}\n\nfunc DecodeVLQ(encoded []byte, start int) (int, int) {\n\tshift := 0\n\tvlq := 0\n\n\t// Scan over the input\n\tfor {\n\t\tindex := bytes.IndexByte(base64, encoded[start])\n\t\tif index < 0 {\n\t\t\tbreak\n\t\t}\n\n\t\t// Decode a single byte\n\t\tvlq |= (index & 31) << shift\n\t\tstart++\n\t\tshift += 5\n\n\t\t// Stop if there's no continuation bit\n\t\tif (index & 32) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Recover the value\n\tvalue := vlq >> 1\n\tif (vlq & 1) != 0 {\n\t\tvalue = -value\n\t}\n\treturn value, start\n}\n\nfunc DecodeVLQUTF16(encoded []uint16) (int, int, bool) {\n\tn := len(encoded)\n\tif n == 0 {\n\t\treturn 0, 0, false\n\t}\n\n\t// Scan over the input\n\tcurrent := 0\n\tshift := 0\n\tvlq := 0\n\tfor {\n\t\tif current >= n {\n\t\t\treturn 0, 0, false\n\t\t}\n\t\tindex := bytes.IndexByte(base64, byte(encoded[current]))\n\t\tif index < 0 {\n\t\t\treturn 0, 0, false\n\t\t}\n\n\t\t// Decode a single byte\n\t\tvlq |= (index & 31) << shift\n\t\tcurrent++\n\t\tshift += 5\n\n\t\t// Stop if there's no continuation bit\n\t\tif (index & 32) == 0 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// Recover the value\n\tvar value = vlq >> 1\n\tif (vlq & 1) != 0 {\n\t\tvalue = -value\n\t}\n\treturn value, current, true\n}\n\ntype LineColumnOffset struct {\n\tLines   int\n\tColumns int\n}\n\nfunc (a LineColumnOffset) ComesBefore(b LineColumnOffset) bool {\n\treturn a.Lines < b.Lines || (a.Lines == b.Lines && a.Columns < b.Columns)\n}\n\nfunc (a *LineColumnOffset) Add(b LineColumnOffset) {\n\tif b.Lines == 0 {\n\t\ta.Columns += b.Columns\n\t} else {\n\t\ta.Lines += b.Lines\n\t\ta.Columns = b.Columns\n\t}\n}\n\nfunc (offset *LineColumnOffset) AdvanceBytes(bytes []byte) {\n\tcolumns := offset.Columns\n\tfor len(bytes) > 0 {\n\t\tc, width := utf8.DecodeRune(bytes)\n\t\tbytes = bytes[width:]\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && len(bytes) > 0 && bytes[0] == '\\n' {\n\t\t\t\tcolumns++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\toffset.Lines++\n\t\t\tcolumns = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumns++\n\t\t\t} else {\n\t\t\t\tcolumns += 2\n\t\t\t}\n\t\t}\n\t}\n\toffset.Columns = columns\n}\n\nfunc (offset *LineColumnOffset) AdvanceString(text string) {\n\tcolumns := offset.Columns\n\tfor i, c := range text {\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && i+1 < len(text) && text[i+1] == '\\n' {\n\t\t\t\tcolumns++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\toffset.Lines++\n\t\t\tcolumns = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumns++\n\t\t\t} else {\n\t\t\t\tcolumns += 2\n\t\t\t}\n\t\t}\n\t}\n\toffset.Columns = columns\n}\n\ntype SourceMapPieces struct {\n\tPrefix   []byte\n\tMappings []byte\n\tSuffix   []byte\n}\n\nfunc (pieces SourceMapPieces) HasContent() bool {\n\treturn len(pieces.Prefix)+len(pieces.Mappings)+len(pieces.Suffix) > 0\n}\n\ntype SourceMapShift struct {\n\tBefore LineColumnOffset\n\tAfter  LineColumnOffset\n}\n\nfunc (pieces SourceMapPieces) Finalize(shifts []SourceMapShift) []byte {\n\t// An optimized path for when there are no shifts\n\tif len(shifts) == 1 {\n\t\tbytes := pieces.Prefix\n\t\tminCap := len(bytes) + len(pieces.Mappings) + len(pieces.Suffix)\n\t\tif cap(bytes) < minCap {\n\t\t\tbytes = append(make([]byte, 0, minCap), bytes...)\n\t\t}\n\t\tbytes = append(bytes, pieces.Mappings...)\n\t\tbytes = append(bytes, pieces.Suffix...)\n\t\treturn bytes\n\t}\n\n\tstartOfRun := 0\n\tcurrent := 0\n\tgenerated := LineColumnOffset{}\n\tprevShiftColumnDelta := 0\n\tj := helpers.Joiner{}\n\n\t// Start the source map\n\tj.AddBytes(pieces.Prefix)\n\n\t// This assumes that a) all mappings are valid and b) all mappings are ordered\n\t// by increasing generated position. This should be the case for all mappings\n\t// generated by esbuild, which should be the only mappings we process here.\n\tfor current < len(pieces.Mappings) {\n\t\t// Handle a line break\n\t\tif pieces.Mappings[current] == ';' {\n\t\t\tgenerated.Lines++\n\t\t\tgenerated.Columns = 0\n\t\t\tprevShiftColumnDelta = 0\n\t\t\tcurrent++\n\t\t\tcontinue\n\t\t}\n\n\t\tpotentialEndOfRun := current\n\n\t\t// Read the generated column\n\t\tgeneratedColumnDelta, next := DecodeVLQ(pieces.Mappings, current)\n\t\tgenerated.Columns += generatedColumnDelta\n\t\tcurrent = next\n\n\t\tpotentialStartOfRun := current\n\n\t\t// Skip over the original position information\n\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original source\n\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original line\n\t\t_, current = DecodeVLQ(pieces.Mappings, current) // The original column\n\n\t\t// Skip a trailing comma\n\t\tif current < len(pieces.Mappings) && pieces.Mappings[current] == ',' {\n\t\t\tcurrent++\n\t\t}\n\n\t\t// Detect crossing shift boundaries\n\t\tdidCrossBoundary := false\n\t\tfor len(shifts) > 1 && shifts[1].Before.ComesBefore(generated) {\n\t\t\tshifts = shifts[1:]\n\t\t\tdidCrossBoundary = true\n\t\t}\n\t\tif !didCrossBoundary {\n\t\t\tcontinue\n\t\t}\n\n\t\t// This shift isn't relevant if the next mapping after this shift is on a\n\t\t// following line. In that case, don't split and keep scanning instead.\n\t\tshift := shifts[0]\n\t\tif shift.After.Lines != generated.Lines {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Add all previous mappings in a single run for efficiency. Since source\n\t\t// mappings are relative, no data needs to be modified inside this run.\n\t\tj.AddBytes(pieces.Mappings[startOfRun:potentialEndOfRun])\n\n\t\t// Then modify the first mapping across the shift boundary with the updated\n\t\t// generated column value. It's simplest to only support column shifts. This\n\t\t// is reasonable because import paths should not contain newlines.\n\t\tif shift.Before.Lines != shift.After.Lines {\n\t\t\tpanic(\"Unexpected line change when shifting source maps\")\n\t\t}\n\t\tshiftColumnDelta := shift.After.Columns - shift.Before.Columns\n\t\tj.AddBytes(EncodeVLQ(generatedColumnDelta + shiftColumnDelta - prevShiftColumnDelta))\n\t\tprevShiftColumnDelta = shiftColumnDelta\n\n\t\t// Finally, start the next run after the end of this generated column offset\n\t\tstartOfRun = potentialStartOfRun\n\t}\n\n\t// Finish the source map\n\tj.AddBytes(pieces.Mappings[startOfRun:])\n\tj.AddBytes(pieces.Suffix)\n\treturn j.Done()\n}\n\n// Coordinates in source maps are stored using relative offsets for size\n// reasons. When joining together chunks of a source map that were emitted\n// in parallel for different parts of a file, we need to fix up the first\n// segment of each chunk to be relative to the end of the previous chunk.\ntype SourceMapState struct {\n\t// This isn't stored in the source map. It's only used by the bundler to join\n\t// source map chunks together correctly.\n\tGeneratedLine int\n\n\t// These are stored in the source map in VLQ format.\n\tGeneratedColumn int\n\tSourceIndex     int\n\tOriginalLine    int\n\tOriginalColumn  int\n}\n\n// Source map chunks are computed in parallel for speed. Each chunk is relative\n// to the zero state instead of being relative to the end state of the previous\n// chunk, since it's impossible to know the end state of the previous chunk in\n// a parallel computation.\n//\n// After all chunks are computed, they are joined together in a second pass.\n// This rewrites the first mapping in each chunk to be relative to the end\n// state of the previous chunk.\nfunc AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startState SourceMapState, sourceMap []byte) {\n\t// Handle line breaks in between this mapping and the previous one\n\tif startState.GeneratedLine != 0 {\n\t\tj.AddBytes(bytes.Repeat([]byte{';'}, startState.GeneratedLine))\n\t\tprevEndState.GeneratedColumn = 0\n\t}\n\n\t// Skip past any leading semicolons, which indicate line breaks\n\tsemicolons := 0\n\tfor sourceMap[semicolons] == ';' {\n\t\tsemicolons++\n\t}\n\tif semicolons > 0 {\n\t\tj.AddBytes(sourceMap[:semicolons])\n\t\tsourceMap = sourceMap[semicolons:]\n\t\tprevEndState.GeneratedColumn = 0\n\t\tstartState.GeneratedColumn = 0\n\t}\n\n\t// Strip off the first mapping from the buffer. The first mapping should be\n\t// for the start of the original file (the printer always generates one for\n\t// the start of the file).\n\tgeneratedColumn, i := DecodeVLQ(sourceMap, 0)\n\tsourceIndex, i := DecodeVLQ(sourceMap, i)\n\toriginalLine, i := DecodeVLQ(sourceMap, i)\n\toriginalColumn, i := DecodeVLQ(sourceMap, i)\n\tsourceMap = sourceMap[i:]\n\n\t// Rewrite the first mapping to be relative to the end state of the previous\n\t// chunk. We now know what the end state is because we're in the second pass\n\t// where all chunks have already been generated.\n\tstartState.SourceIndex += sourceIndex\n\tstartState.GeneratedColumn += generatedColumn\n\tstartState.OriginalLine += originalLine\n\tstartState.OriginalColumn += originalColumn\n\tj.AddBytes(appendMappingToBuffer(nil, j.LastByte(), prevEndState, startState))\n\n\t// Then append everything after that without modification.\n\tj.AddBytes(sourceMap)\n}\n\nfunc appendMappingToBuffer(buffer []byte, lastByte byte, prevState SourceMapState, currentState SourceMapState) []byte {\n\t// Put commas in between mappings\n\tif lastByte != 0 && lastByte != ';' && lastByte != '\"' {\n\t\tbuffer = append(buffer, ',')\n\t}\n\n\t// Record the generated column (the line is recorded using ';' elsewhere)\n\tbuffer = append(buffer, EncodeVLQ(currentState.GeneratedColumn-prevState.GeneratedColumn)...)\n\tprevState.GeneratedColumn = currentState.GeneratedColumn\n\n\t// Record the generated source\n\tbuffer = append(buffer, EncodeVLQ(currentState.SourceIndex-prevState.SourceIndex)...)\n\tprevState.SourceIndex = currentState.SourceIndex\n\n\t// Record the original line\n\tbuffer = append(buffer, EncodeVLQ(currentState.OriginalLine-prevState.OriginalLine)...)\n\tprevState.OriginalLine = currentState.OriginalLine\n\n\t// Record the original column\n\tbuffer = append(buffer, EncodeVLQ(currentState.OriginalColumn-prevState.OriginalColumn)...)\n\tprevState.OriginalColumn = currentState.OriginalColumn\n\n\treturn buffer\n}\n\ntype LineOffsetTable struct {\n\t// The source map specification is very loose and does not specify what\n\t// column numbers actually mean. The popular \"source-map\" library from Mozilla\n\t// appears to interpret them as counts of UTF-16 code units, so we generate\n\t// those too for compatibility.\n\t//\n\t// We keep mapping tables around to accelerate conversion from byte offsets\n\t// to UTF-16 code unit counts. However, this mapping takes up a lot of memory\n\t// and generates a lot of garbage. Since most JavaScript is ASCII and the\n\t// mapping for ASCII is 1:1, we avoid creating a table for ASCII-only lines\n\t// as an optimization.\n\tcolumnsForNonASCII        []int32\n\tbyteOffsetToFirstNonASCII int32\n\n\tbyteOffsetToStartOfLine int32\n}\n\nfunc GenerateLineOffsetTables(contents string, approximateLineCount int32) []LineOffsetTable {\n\tvar ColumnsForNonASCII []int32\n\tByteOffsetToFirstNonASCII := int32(0)\n\tlineByteOffset := 0\n\tcolumnByteOffset := 0\n\tcolumn := int32(0)\n\n\t// Preallocate the top-level table using the approximate line count from the lexer\n\tlineOffsetTables := make([]LineOffsetTable, 0, approximateLineCount)\n\n\tfor i, c := range contents {\n\t\t// Mark the start of the next line\n\t\tif column == 0 {\n\t\t\tlineByteOffset = i\n\t\t}\n\n\t\t// Start the mapping if this character is non-ASCII\n\t\tif c > 0x7F && ColumnsForNonASCII == nil {\n\t\t\tcolumnByteOffset = i - lineByteOffset\n\t\t\tByteOffsetToFirstNonASCII = int32(columnByteOffset)\n\t\t\tColumnsForNonASCII = []int32{}\n\t\t}\n\n\t\t// Update the per-byte column offsets\n\t\tif ColumnsForNonASCII != nil {\n\t\t\tfor lineBytesSoFar := i - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {\n\t\t\t\tColumnsForNonASCII = append(ColumnsForNonASCII, column)\n\t\t\t}\n\t\t}\n\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' && i+1 < len(contents) && contents[i+1] == '\\n' {\n\t\t\t\tcolumn++\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tlineOffsetTables = append(lineOffsetTables, LineOffsetTable{\n\t\t\t\tbyteOffsetToStartOfLine:   int32(lineByteOffset),\n\t\t\t\tbyteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,\n\t\t\t\tcolumnsForNonASCII:        ColumnsForNonASCII,\n\t\t\t})\n\t\t\tcolumnByteOffset = 0\n\t\t\tByteOffsetToFirstNonASCII = 0\n\t\t\tColumnsForNonASCII = nil\n\t\t\tcolumn = 0\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tcolumn++\n\t\t\t} else {\n\t\t\t\tcolumn += 2\n\t\t\t}\n\t\t}\n\t}\n\n\t// Mark the start of the next line\n\tif column == 0 {\n\t\tlineByteOffset = len(contents)\n\t}\n\n\t// Do one last update for the column at the end of the file\n\tif ColumnsForNonASCII != nil {\n\t\tfor lineBytesSoFar := len(contents) - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {\n\t\t\tColumnsForNonASCII = append(ColumnsForNonASCII, column)\n\t\t}\n\t}\n\n\tlineOffsetTables = append(lineOffsetTables, LineOffsetTable{\n\t\tbyteOffsetToStartOfLine:   int32(lineByteOffset),\n\t\tbyteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,\n\t\tcolumnsForNonASCII:        ColumnsForNonASCII,\n\t})\n\treturn lineOffsetTables\n}\n\ntype Chunk struct {\n\tBuffer []byte\n\n\t// This end state will be used to rewrite the start of the following source\n\t// map chunk so that the delta-encoded VLQ numbers are preserved.\n\tEndState SourceMapState\n\n\t// There probably isn't a source mapping at the end of the file (nor should\n\t// there be) but if we're appending another source map chunk after this one,\n\t// we'll need to know how many characters were in the last line we generated.\n\tFinalGeneratedColumn int\n\n\tShouldIgnore bool\n}\n\ntype ChunkBuilder struct {\n\tinputSourceMap      *SourceMap\n\tsourceMap           []byte\n\tlineOffsetTables    []LineOffsetTable\n\tprevState           SourceMapState\n\tlastGeneratedUpdate int\n\tgeneratedColumn     int\n\tprevLoc             logger.Loc\n\thasPrevState        bool\n\n\t// This is a workaround for a bug in the popular \"source-map\" library:\n\t// https://github.com/mozilla/source-map/issues/261. The library will\n\t// sometimes return null when querying a source map unless every line\n\t// starts with a mapping at column zero.\n\t//\n\t// The workaround is to replicate the previous mapping if a line ends\n\t// up not starting with a mapping. This is done lazily because we want\n\t// to avoid replicating the previous mapping if we don't need to.\n\tlineStartsWithMapping     bool\n\tcoverLinesWithoutMappings bool\n}\n\nfunc MakeChunkBuilder(inputSourceMap *SourceMap, lineOffsetTables []LineOffsetTable) ChunkBuilder {\n\treturn ChunkBuilder{\n\t\tinputSourceMap:   inputSourceMap,\n\t\tprevLoc:          logger.Loc{Start: -1},\n\t\tlineOffsetTables: lineOffsetTables,\n\n\t\t// We automatically repeat the previous source mapping if we ever generate\n\t\t// a line that doesn't start with a mapping. This helps give files more\n\t\t// complete mapping coverage without gaps.\n\t\t//\n\t\t// However, we probably shouldn't do this if the input file has a nested\n\t\t// source map that we will be remapping through. We have no idea what state\n\t\t// that source map is in and it could be pretty scrambled.\n\t\t//\n\t\t// I've seen cases where blindly repeating the last mapping for subsequent\n\t\t// lines gives very strange and unhelpful results with source maps from\n\t\t// other tools.\n\t\tcoverLinesWithoutMappings: inputSourceMap == nil,\n\t}\n}\n\nfunc (b *ChunkBuilder) AddSourceMapping(loc logger.Loc, output []byte) {\n\tif loc == b.prevLoc {\n\t\treturn\n\t}\n\tb.prevLoc = loc\n\n\t// Binary search to find the line\n\tlineOffsetTables := b.lineOffsetTables\n\tcount := len(lineOffsetTables)\n\toriginalLine := 0\n\tfor count > 0 {\n\t\tstep := count / 2\n\t\ti := originalLine + step\n\t\tif lineOffsetTables[i].byteOffsetToStartOfLine <= loc.Start {\n\t\t\toriginalLine = i + 1\n\t\t\tcount = count - step - 1\n\t\t} else {\n\t\t\tcount = step\n\t\t}\n\t}\n\toriginalLine--\n\n\t// Use the line to compute the column\n\tline := &lineOffsetTables[originalLine]\n\toriginalColumn := int(loc.Start - line.byteOffsetToStartOfLine)\n\tif line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) {\n\t\toriginalColumn = int(line.columnsForNonASCII[originalColumn-int(line.byteOffsetToFirstNonASCII)])\n\t}\n\n\tb.updateGeneratedLineAndColumn(output)\n\n\t// If this line doesn't start with a mapping and we're about to add a mapping\n\t// that's not at the start, insert a mapping first so the line starts with one.\n\tif b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.generatedColumn > 0 && b.hasPrevState {\n\t\tb.appendMappingWithoutRemapping(SourceMapState{\n\t\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\t\tGeneratedColumn: 0,\n\t\t\tSourceIndex:     b.prevState.SourceIndex,\n\t\t\tOriginalLine:    b.prevState.OriginalLine,\n\t\t\tOriginalColumn:  b.prevState.OriginalColumn,\n\t\t})\n\t}\n\n\tb.appendMapping(SourceMapState{\n\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\tGeneratedColumn: b.generatedColumn,\n\t\tOriginalLine:    originalLine,\n\t\tOriginalColumn:  originalColumn,\n\t})\n\n\t// This line now has a mapping on it, so don't insert another one\n\tb.lineStartsWithMapping = true\n}\n\nfunc (b *ChunkBuilder) GenerateChunk(output []byte) Chunk {\n\tb.updateGeneratedLineAndColumn(output)\n\tshouldIgnore := true\n\tfor _, c := range b.sourceMap {\n\t\tif c != ';' {\n\t\t\tshouldIgnore = false\n\t\t\tbreak\n\t\t}\n\t}\n\treturn Chunk{\n\t\tBuffer:               b.sourceMap,\n\t\tEndState:             b.prevState,\n\t\tFinalGeneratedColumn: b.generatedColumn,\n\t\tShouldIgnore:         shouldIgnore,\n\t}\n}\n\n// Scan over the printed text since the last source mapping and update the\n// generated line and column numbers\nfunc (b *ChunkBuilder) updateGeneratedLineAndColumn(output []byte) {\n\tfor i, c := range string(output[b.lastGeneratedUpdate:]) {\n\t\tswitch c {\n\t\tcase '\\r', '\\n', '\\u2028', '\\u2029':\n\t\t\t// Handle Windows-specific \"\\r\\n\" newlines\n\t\t\tif c == '\\r' {\n\t\t\t\tnewlineCheck := b.lastGeneratedUpdate + i + 1\n\t\t\t\tif newlineCheck < len(output) && output[newlineCheck] == '\\n' {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If we're about to move to the next line and the previous line didn't have\n\t\t\t// any mappings, add a mapping at the start of the previous line.\n\t\t\tif b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.hasPrevState {\n\t\t\t\tb.appendMappingWithoutRemapping(SourceMapState{\n\t\t\t\t\tGeneratedLine:   b.prevState.GeneratedLine,\n\t\t\t\t\tGeneratedColumn: 0,\n\t\t\t\t\tSourceIndex:     b.prevState.SourceIndex,\n\t\t\t\t\tOriginalLine:    b.prevState.OriginalLine,\n\t\t\t\t\tOriginalColumn:  b.prevState.OriginalColumn,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\tb.prevState.GeneratedLine++\n\t\t\tb.prevState.GeneratedColumn = 0\n\t\t\tb.generatedColumn = 0\n\t\t\tb.sourceMap = append(b.sourceMap, ';')\n\n\t\t\t// This new line doesn't have a mapping yet\n\t\t\tb.lineStartsWithMapping = false\n\n\t\tdefault:\n\t\t\t// Mozilla's \"source-map\" library counts columns using UTF-16 code units\n\t\t\tif c <= 0xFFFF {\n\t\t\t\tb.generatedColumn++\n\t\t\t} else {\n\t\t\t\tb.generatedColumn += 2\n\t\t\t}\n\t\t}\n\t}\n\n\tb.lastGeneratedUpdate = len(output)\n}\n\nfunc (b *ChunkBuilder) appendMapping(currentState SourceMapState) {\n\t// If the input file had a source map, map all the way back to the original\n\tif b.inputSourceMap != nil {\n\t\tmapping := b.inputSourceMap.Find(\n\t\t\tint32(currentState.OriginalLine),\n\t\t\tint32(currentState.OriginalColumn))\n\n\t\t// Some locations won't have a mapping\n\t\tif mapping == nil {\n\t\t\treturn\n\t\t}\n\n\t\tcurrentState.SourceIndex = int(mapping.SourceIndex)\n\t\tcurrentState.OriginalLine = int(mapping.OriginalLine)\n\t\tcurrentState.OriginalColumn = int(mapping.OriginalColumn)\n\t}\n\n\tb.appendMappingWithoutRemapping(currentState)\n}\n\nfunc (b *ChunkBuilder) appendMappingWithoutRemapping(currentState SourceMapState) {\n\tvar lastByte byte\n\tif len(b.sourceMap) != 0 {\n\t\tlastByte = b.sourceMap[len(b.sourceMap)-1]\n\t}\n\n\tb.sourceMap = appendMappingToBuffer(b.sourceMap, lastByte, b.prevState, currentState)\n\tb.prevState = currentState\n\tb.hasPrevState = true\n}\n"
  },
  {
    "path": "lib/esbuild/test/diff.go",
    "content": "package test\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\nfunc diff(old string, new string, color bool) string {\n\treturn strings.Join(diffRec(nil, strings.Split(old, \"\\n\"), strings.Split(new, \"\\n\"), color), \"\\n\")\n}\n\n// This is a simple recursive line-by-line diff implementation\nfunc diffRec(result []string, old []string, new []string, color bool) []string {\n\to, n, common := lcSubstr(old, new)\n\n\tif common == 0 {\n\t\t// Everything changed\n\t\tfor _, line := range old {\n\t\t\tif color {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"%s-%s%s\", logger.TerminalColors.Red, line, logger.TerminalColors.Reset))\n\t\t\t} else {\n\t\t\t\tresult = append(result, \"-\"+line)\n\t\t\t}\n\t\t}\n\t\tfor _, line := range new {\n\t\t\tif color {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"%s+%s%s\", logger.TerminalColors.Green, line, logger.TerminalColors.Reset))\n\t\t\t} else {\n\t\t\t\tresult = append(result, \"+\"+line)\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// Something in the middle stayed the same\n\t\tresult = diffRec(result, old[:o], new[:n], color)\n\t\tfor _, line := range old[o : o+common] {\n\t\t\tif color {\n\t\t\t\tresult = append(result, fmt.Sprintf(\"%s %s%s\", logger.TerminalColors.Dim, line, logger.TerminalColors.Reset))\n\t\t\t} else {\n\t\t\t\tresult = append(result, \" \"+line)\n\t\t\t}\n\t\t}\n\t\tresult = diffRec(result, old[o+common:], new[n+common:], color)\n\t}\n\n\treturn result\n}\n\n// From: https://en.wikipedia.org/wiki/Longest_common_substring_problem\nfunc lcSubstr(S []string, T []string) (int, int, int) {\n\tr := len(S)\n\tn := len(T)\n\tLprev := make([]int, n)\n\tLnext := make([]int, n)\n\tz := 0\n\tretI := 0\n\tretJ := 0\n\n\tfor i := 0; i < r; i++ {\n\t\tfor j := 0; j < n; j++ {\n\t\t\tif S[i] == T[j] {\n\t\t\t\tif j == 0 {\n\t\t\t\t\tLnext[j] = 1\n\t\t\t\t} else {\n\t\t\t\t\tLnext[j] = Lprev[j-1] + 1\n\t\t\t\t}\n\t\t\t\tif Lnext[j] > z {\n\t\t\t\t\tz = Lnext[j]\n\t\t\t\t\tretI = i + 1\n\t\t\t\t\tretJ = j + 1\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tLnext[j] = 0\n\t\t\t}\n\t\t}\n\t\tLprev, Lnext = Lnext, Lprev\n\t}\n\n\treturn retI - z, retJ - z, z\n}\n"
  },
  {
    "path": "lib/esbuild/test/util.go",
    "content": "package test\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/withastro/compiler/lib/esbuild/logger\"\n)\n\nfunc AssertEqual(t *testing.T, observed interface{}, expected interface{}) {\n\tt.Helper()\n\tif observed != expected {\n\t\tt.Fatalf(\"%s != %s\", observed, expected)\n\t}\n}\n\nfunc AssertEqualWithDiff(t *testing.T, observed interface{}, expected interface{}) {\n\tt.Helper()\n\tif observed != expected {\n\t\tstringA := fmt.Sprintf(\"%v\", observed)\n\t\tstringB := fmt.Sprintf(\"%v\", expected)\n\t\tcolor := true\n\t\tt.Fatal(diff(stringB, stringA, color))\n\t}\n}\n\nfunc SourceForTest(contents string) logger.Source {\n\treturn logger.Source{\n\t\tIndex:          0,\n\t\tKeyPath:        logger.Path{Text: \"<stdin>\"},\n\t\tPrettyPath:     \"<stdin>\",\n\t\tContents:       contents,\n\t\tIdentifierName: \"stdin\",\n\t}\n}\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"root\",\n  \"version\": \"0.0.0\",\n  \"private\": true,\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/withastro/compiler.git\"\n  },\n  \"scripts\": {\n    \"build\": \"make wasm\",\n    \"build:compiler\": \"pnpm --filter @astrojs/compiler run build\",\n    \"build:all\": \"pnpm run build && pnpm run build:compiler\",\n    \"check\": \"biome check\",\n    \"ci\": \"biome ci --diagnostic-level=warn\",\n    \"check:write\": \"biome check --write\",\n    \"prerelease\": \"pnpm run build:compiler\",\n    \"release\": \"changeset publish\",\n    \"test\": \"tsx node_modules/uvu/bin.js packages test -i utils -i stress\",\n    \"test:only\": \"tsx node_modules/uvu/bin.js packages\",\n    \"test:stress\": \"tsx packages/compiler/test/stress/index.ts\",\n    \"test:ci\": \"pnpm run test && pnpm run test:stress\"\n  },\n  \"packageManager\": \"pnpm@10.22.0\",\n  \"workspaces\": [\n    \"packages/*\"\n  ],\n  \"devDependencies\": {\n    \"@biomejs/biome\": \"1.8.1\",\n    \"@changesets/cli\": \"^2.25.0\",\n    \"sass\": \"^1.55.0\",\n    \"tsx\": \"^4.16.2\",\n    \"typescript\": \"~5.5.3\",\n    \"uvu\": \"^0.5.6\"\n  },\n  \"engines\": {\n    \"node\": \"^12.20.0 || ^14.13.1 || >=16.0.0\"\n  }\n}\n"
  },
  {
    "path": "packages/compiler/.gitignore",
    "content": "dist\nwasm\n"
  },
  {
    "path": "packages/compiler/CHANGELOG.md",
    "content": "# @astrojs/compiler\n\n## 3.0.1\n\n### Patch Changes\n\n- 05ef961: Fix scoped CSS nesting so descendant selectors without `&` inside nested rules are not incorrectly re-scoped.\n\n## 3.0.0\n\n### Major Changes\n\n- c05e16e: Removes the first argument of `$$result.createAstro()`\n\n  `$$result.createAstro()` does not accept an `AstroGlobalPartial` as the first argument anymore:\n\n  ```diff\n  -const Astro = $$result.createAstro($$Astro, $$props, $$slots);\n  +const Astro = $$result.createAstro($$props, $$slots);\n  ```\n\n- c05e16e: Removes `renderScript` from `TransformOptions`. It is now the default and only behavior\n- c05e16e: Removes `experimentalScriptOrder` from `TransformOptions`. It is now the default and only behavior\n\n### Patch Changes\n\n- 811e90f: Fixes an issue where `server:defer` was treated like a transition directive, causing ViewTransitions CSS to be included even when no `transition:*` directives were used.\n- 755f046: Fixes a CSS scoping regression where selectors using the nesting selector (`&`) with pseudo-classes or pseudo-elements (e.g. `&:last-of-type`, `&::before`) inside `:global()` contexts would incorrectly receive a duplicate scope attribute.\n- f89451a: Fixed an issue where explicit `<html>` and `<head>` tags were removed from output when a JSX comment appeared between DOCTYPE and the `<html>` tag.\n- 8275bdd: Fixes a bug where trailing whitespaces were preserved before `<style>` tags after transformation, in certain cases. Now trailing whitespaces are correctly removed.\n- 56ef0ca: Fixes TSX output to transform top-level returns into throws in order to avoid downstream TypeScript parsing issues\n- e329d20: Fix slot attribute stripped inside expression\n- 02de370: fixed a bug where the Astro compiler incorrectly handled the 'as' property name in Props interfaces.\n\n  This allows Astro components to use 'as' as a prop name (common pattern for polymorphic components) without breaking TypeScript type inference. The Props type is now correctly preserved when destructuring objects with an 'as'\n  property.\n\n- 615eb21: Fix CSS nesting so nested selectors without an ampersand are parsed and scoped correctly.\n\n## 3.0.0-beta.1\n\n### Patch Changes\n\n- 755f046: Fixes a CSS scoping regression where selectors using the nesting selector (`&`) with pseudo-classes or pseudo-elements (e.g. `&:last-of-type`, `&::before`) inside `:global()` contexts would incorrectly receive a duplicate scope attribute.\n- f89451a: Fixed an issue where explicit `<html>` and `<head>` tags were removed from output when a JSX comment appeared between DOCTYPE and the `<html>` tag.\n- 8275bdd: Fixes a bug where trailing whitespaces were preserved before `<style>` tags after transformation, in certain cases. Now trailing whitespaces are correctly removed.\n- e329d20: Fix slot attribute stripped inside expression\n- 615eb21: Fix CSS nesting so nested selectors without an ampersand are parsed and scoped correctly.\n\n## 3.0.0-beta.0\n\n### Major Changes\n\n- c05e16e: Removes the first argument of `$$result.createAstro()`\n\n  `$$result.createAstro()` does not accept an `AstroGlobalPartial` as the first argument anymore:\n\n  ```diff\n  -const Astro = $$result.createAstro($$Astro, $$props, $$slots);\n  +const Astro = $$result.createAstro($$props, $$slots);\n  ```\n\n- c05e16e: Removes `renderScript` from `TransformOptions`. It is now the default and only behavior\n- c05e16e: Removes `experimentalScriptOrder` from `TransformOptions`. It is now the default and only behavior\n\n## 2.13.1\n\n### Patch Changes\n\n- 357b8fe: Fixes a panic when parsing files with a closing frontmatter fence (---) but no opening fence. The compiler now returns a helpful diagnostic error instead of crashing.\n- cba568f: Fixes the \"Unterminated string literal\" error when using multiline attribute values on components.\n\n## 2.13.0\n\n### Minor Changes\n\n- 59f77593: Support HTML <selectedcontent> element\n\n  Based on the recent commit history, this change appears to be related to fixing issue #1093 regarding selectedcontent parsing in customizable selects. The <selectedcontent> element is part of the new Customizable Select Element API\n  in HTML, used within <selectlist> elements to display the currently selected option(s).\n\n- 89c80fee: Adds a `walkAsync` utility function that returns a Promise from the tree traversal process.\n\n  Unlike the existing `walk` function which doesn't provide a way to wait for traversal completion, `walkAsync` allows consumers to `await` the full traversal of the AST.\n\n### Patch Changes\n\n- 2a27aca7: Fixes a potential parsing issue with head content defined in a component where another component is rendered first.\n- 1264286c: Fixes a CSS scoping issue when a selector contains only pseudo selectors.\n\n## 2.12.2\n\n### Patch Changes\n\n- 950635e: Reverts a change where view transitions were made async to accomodate the CSP requirements.\n\n## 2.12.1\n\n### Patch Changes\n\n- 138c07f: Improves detection of function body opening curly brace for exported functions.\n- 4a967ab: Fixes a bug where view transition names got lost after update to Astro 5.9\n\n## 2.12.0\n\n### Minor Changes\n\n- e428ae0: Add head propagation metadata to server islands\n\n## 2.11.0\n\n### Minor Changes\n\n- 0399d55: Add an experimental flag `experimentalScriptOrder` that corrects the order styles & scripts are rendered within a component. When enabled, the order styles & scripts are rendered will be consistent with the order they are defined.\n\n### Patch Changes\n\n- c758d7e: Add async properly when await used inside fragment\n\n## 2.10.4\n\n### Patch Changes\n\n- 8cae811: Fixes an issue with the conditional rendering of scripts.\n\n  **This change updates a v5.0 breaking change when `experimental.directRenderScript` became the default script handling behavior.** If you have already successfully upgraded to Astro v5, you may need to review your script tags again and make sure they still behave as desired after this release. [See the v5 Upgrade Guide for more details.](https://docs.astro.build/en/guides/upgrade-to/v5/#script-tags-are-rendered-directly-as-declared)\n\n- 970f085: Fixes an issue when parsing elements inside foreign content (e.g. SVG), when they were inside an expression\n- 6b6a134: Fixes a bug caused by having an extra space in the fragment tag in the TSX output\n\n## 2.10.3\n\n### Patch Changes\n\n- 5d0023d: Fixes sourcemapping for CRLF line endings wrongfully including the last character\n- f55a2af: Resolves an issue where the `class:list` directive was not correctly merging with the class attribute.\n\n## 2.10.2\n\n### Patch Changes\n\n- f05a7cc: Adjust TSX output to return ranges using UTF-16 code units, as it would in JavaScript\n\n## 2.10.1\n\n### Patch Changes\n\n- 21b7b95: Revert the transformation of top-level returns into throws in TSX as it was buggy in numerous situations\n- af471f5: Fixes positions for extracted tags being wrong when using IncludeStyles and IncludeScripts set to false\n\n## 2.10.0\n\n### Minor Changes\n\n- 1d684b1: Adds detected language to extracted style tags in TSX\n\n### Patch Changes\n\n- 7fa6577: Transform top level returns into throws in the TSX output\n\n## 2.9.2\n\n### Patch Changes\n\n- a765f47: Escape script tags with unknown types\n\n## 2.9.1\n\n### Patch Changes\n\n- 9549bb7: Fixes style and script tags sometimes being forcefully put into the body / head tags in the AST\n\n## 2.9.0\n\n### Minor Changes\n\n- 3e25858: Adds two new options to `convertToTSX`: `includeScripts` and `includeStyles`. These options allow you to optionally remove scripts and styles from the output TSX file.\n\n  Additionally this PR makes it so scripts and styles metadata are now included in the `metaRanges` property of the result of `convertToTSX`. This is notably useful in order to extract scripts and styles from the output TSX file into separate files for language servers.\n\n- 9fb8d5d: Adds `serverComponents` metadata\n\n  This adds a change necessary to support server islands. During transformation the compiler discovers `server:defer` directives and appends them to the `serverComponents` array. This is exported along with the other metadata so that it can be used inside of Astro.\n\n## 2.8.2\n\n### Patch Changes\n\n- 6b7c12f: Avoids stringifying `undefined` in scoped class attributes\n- 8803da6: Fixes newlines in opening tag generating buggy code in TSX\n\n## 2.8.1\n\n### Patch Changes\n\n- 0bb2746: Allow `data-astro-reload` to take a value\n\n## 2.8.0\n\n### Minor Changes\n\n- 17f8932: The WASM binaries for the compiler are now built using Go 1.22.\n\n### Patch Changes\n\n- e8b6cdf: Skips printing `createAstro` code if the `Astro` global is not referenced\n- ecd7e90: Skips printing `async` for component functions if `await` is not used\n\n## 2.7.1\n\n### Patch Changes\n\n- 5467f40: Fix issue with head content being pushed into body\n- d587ca6: Adds warnings indicating that the `data-astro-rerun` attribute can not be used on an external module `<script>` and that `data-astro-reload` is only supported on `<a>`, `<area>` and `<form>` elements.\n\n## 2.7.0\n\n### Minor Changes\n\n- 50fc0a9: Implement the `transition:persist-props` transformation\n\n### Patch Changes\n\n- f45dbfd: Updates deprecated Node.js 16 github actions.\n\n## 2.6.0\n\n### Minor Changes\n\n- a90d99e: Adds a new `renderScript` option to render non-inline script tags using a `renderScript` function from `internalURL`, instead of stripping the script entirely\n\n### Patch Changes\n\n- 6ffa54b: Fix TSX output prefixing output with unnecessary jsdoc comment\n- 86221d6: Adds a lint rule to display a message when attributes are added to a script tag, explaining that the script will be treated as `is:inline`.\n\n## 2.5.3\n\n### Patch Changes\n\n- c17734d: Rollbacks the dynamic slot generation feature to rework it\n\n## 2.5.2\n\n### Patch Changes\n\n- 418558c: Fixes an issue where a slotted element in an expression would cause subsequent ones to be incorrectly printed\n- db93975: Fixes an issue where an expression inside a `th` tag would cause an infinite loop\n\n## 2.5.1\n\n### Patch Changes\n\n- d071b0b: Fixes an issue which caused the hydration script of default exported components to fail loading in some cases.\n\n## 2.5.0\n\n### Minor Changes\n\n- db13db9: - Adds support for dynamic slots inside loops\n  - Fixes an issue where successive named slotted elements would cause a runtime error\n  - Fixes an issue in which if there was an implicit default slotted element next to named one, the former would get swallowed by the later.\n\n## 2.4.2\n\n### Patch Changes\n\n- 9938bc1: Fixes a sourcemap-related crash when using multibyte characters\n\n## 2.4.1\n\n### Patch Changes\n\n- 7a07089: Fixes a bug where expressions starting with whitespace, followed by anything else, weren't printed correctly.\n\n## 2.4.0\n\n### Minor Changes\n\n- 9ff6342: Return generated frontmatter and body ranges in TSX output\n\n### Patch Changes\n\n- b52f7d1: Fixes an issue where unterminated quoted attributes caused the compiler to crash\n- 24e2886: Fixes a regression that caused whitespace between elements in an expression to result invalid code\n- c5bcbd0: Prefix TSX output with a JSX pragma to ensure proper types are used\n- 4f74c05: Fixes an issue where HTML and JSX comments lead to subsequent content being incorrectly treated as plain text when they have parent expressions.\n- cad2606: Fixes an issue where components with template literal attributes were printed with the name of the attribute as value.\n- 14ccba5: Fixes an issue where a `tr` element which contained an expression would cause its parent table to swallow any trailing element inside said table\n- f9373f2: Fixes an issue where Astro fragments used inside a `table` element would cause lots of missing pieces of markup\n- 4de359b: Preserve whitespace in expressions\n- fe2f0c8: Fixes an issue where `/` or `*/` would cause prematurely closed comments in the tsx output\n\n## 2.3.4\n\n### Patch Changes\n\n- 56e1959: Fixes a memory reference error when an expression is the final node in a file\n\n## 2.3.3\n\n### Patch Changes\n\n- 5b450df: Fixed an `index out of range` error when multibyte characters were rendered as markup\n- 852fc1b: Fix `index out of range [0]` error when there is a component before the `<html>` tag\n- 05ecaff: Fixes an issue where when there are nested expressions, subsequent content was incorrectly treated as plain text in some cases.\n- 8c0cffb: Fixes an issue causing `index out of range` errors when handling some multibyte characters like `\\u2028`.\n\n## 2.3.2\n\n### Patch Changes\n\n- 2bdb4bb: Revert table related parsing change as it resulted in a regression\n\n## 2.3.1\n\n### Patch Changes\n\n- e241f2d: Fix generated code for expressions within `td` elements\n- 5ce5cc6: Fix compact collapse for empty text nodes between elements\n\n## 2.3.0\n\n### Minor Changes\n\n- 0c24ea1: Add a new `annotateSourceFile` option. This option makes it so the compiler will annotate every element with its source file location. This is notably useful for dev tools to be able to provide features like a \"Open in editor\" button. This option is disabled by default.\n\n  ```html\n  <div>\n    <span>hello world</span>\n  </div>\n  ```\n\n  Results in:\n\n  ```html\n  <div\n    data-astro-source-file=\"/Users/erika/Projects/...\"\n    data-astro-source-loc=\"1:1\"\n  >\n    <span\n      data-astro-source-file=\"/Users/erika/Projects/...\"\n      data-astro-source-loc=\"2:2\"\n      >hello world</span\n    >\n  </div>\n  ```\n\n  In Astro, this option is enabled only in development mode.\n\n## 2.2.2\n\n### Patch Changes\n\n- bf76663: [TSX] Add `ASTRO__MergeUnion` util to allow destructuring from automatically inferred union Prop types\n\n## 2.2.1\n\n### Patch Changes\n\n- a52c181: Fixed an issue where spread attributes could not include double quotation marks.\n\n## 2.2.0\n\n### Minor Changes\n\n- 7579d7c: Support CSS `@starting-style` rule (From: https://github.com/evanw/esbuild/pull/3249)\n- 09abfe4: Adds ability for TSX output to automatically infer `Astro.props` and `Astro.params` when `getStaticPaths` is used\n\n## 2.1.0\n\n### Minor Changes\n\n- 2584348: Add propagation metadata to the TransformResult\n\n## 2.0.1\n\n### Patch Changes\n\n- 4e1e907: Remove experimental flags from `transition:` directives. They are now enabled by default.\n\n## 2.0.0\n\n### Major Changes\n\n- cd93272: The scope hash created by the compiler is now **lowercase**.\n\n  This aligns with the HTML spec of the attribute names, where they are lowercase by spec.\n\n  This change is needed because the compiler now creates data attributes that contain the hash in their name.\n\n## 1.8.2\n\n### Patch Changes\n\n- 80b7e42: Pass the type of the current component as a type argument to the AstroGlobal in order to type Astro.self\n\n## 1.8.1\n\n### Patch Changes\n\n- 52fe144: Change the value of the generated attribute\n\n## 1.8.0\n\n### Minor Changes\n\n- 365710c: Support the transition:persist directive\n\n## 1.7.0\n\n### Minor Changes\n\n- 5c19809: Add a `scopedStyleStrategy` called `\"attribute\"`. The strategy will print styles using data attributes.\n\n## 1.6.3\n\n### Patch Changes\n\n- 6b4873d: Pass transition directives onto components\n\n## 1.6.2\n\n### Patch Changes\n\n- ce5cf31: Pass transition:animate expressions\n\n## 1.6.1\n\n### Patch Changes\n\n- 486614b: Fixes use of expression in transition:name\n\n## 1.6.0\n\n### Minor Changes\n\n- 2906df2: Support for view transition directives\n\n  This adds support for `transition:animate` and `transition:name` which get passed into the new `renderTransition` runtime function.\n\n## 1.5.7\n\n### Patch Changes\n\n- 34fcf01: [TSX] escape additional invalid characters\n- 5fe952d: [TSX] fix sourcemaps for quoted attributes that span multiple lines\n\n## 1.5.6\n\n### Patch Changes\n\n- 3d69f4e: [TSX] maintain trailing whitespace before an element is closed, fixing TypeScript completion in some cases\n\n## 1.5.5\n\n### Patch Changes\n\n- 101c18e: [AST] Include end position for frontmatter node when it is the only item in the file\n- 35ccd5e: [AST] add raw attribute values to AST\n- 325d3c3: [TSX] fix compiler crash when file only contains an unamed fragment\n\n## 1.5.4\n\n### Patch Changes\n\n- a35468a: Do not remove surrounding whitespace from text surrounded by newlines when `compressHTML` is enabled\n- 4aba173: Fix props detection when importing `Props` from another file (see [#814](https://github.com/withastro/compiler/issues/814))\n\n## 1.5.3\n\n### Patch Changes\n\n- 5a2ce3e: Update compiler output for `style` objects when used with `define:vars`\n\n## 1.5.2\n\n### Patch Changes\n\n- 73a98c2: Fix `compressHTML` edge case when both leading and trailing whitespace is present\n\n## 1.5.1\n\n### Patch Changes\n\n- a51227d: Move `declare const` for Props type at the bottom of the file to make mapping easier downstream\n\n## 1.5.0\n\n### Minor Changes\n\n- 4255b03: Export package as dual CJS / ESM\n\n### Patch Changes\n\n- ae67f1b: Apply `define:vars` to non-root elements\n\n## 1.4.2\n\n### Patch Changes\n\n- e104c1c: Polyfill the entire crypto object if node >= v16.17.0\n- 6f7b2f6: Fix crash when transforming files with Windows line endings\n\n## 1.4.1\n\n### Patch Changes\n\n- 0803e86: Handle crashes when using `parse` and `convertToTSX` by restarting the service\n\n## 1.4.0\n\n### Minor Changes\n\n- fc0f470: Implements the scopedStyleStrategy option\n\n## 1.3.2\n\n### Patch Changes\n\n- 19c0176: Fix TSX sourcemapping for components using Windows-style line returns\n- b0e0cfd: Add a sync entrypoint\n\n## 1.3.1\n\n### Patch Changes\n\n- e0baa85: Preserve whitespace in slots\n\n## 1.3.0\n\n### Minor Changes\n\n- 95a6610: Expose the `convertToTSX` function in the compiler browser bundle\n- 6d168dd: Add ContainsHead flag for metadata\n\n## 1.2.2\n\n### Patch Changes\n\n- a8a845f: Fix regression related to self-closing tags\n\n## 1.2.1\n\n### Patch Changes\n\n- 348840b: Fix getStaticPaths export when used with a TypeScript type ([#4929](https://github.com/withastro/astro/issues/4929))\n- 8ed067e: Fix parse error for multiline `export type` using Unions or Intersections\n- 6354e50: Improve handling of self-closing tags returned from expression\n- 5a5f91d: Fix `define:vars` when used with a `style` attribute\n- b637e9a: Fix ignored `form` elements after a `form` element that contains an expression\n- 2658ed4: Correctly apply style when `class` and `class:list` are both used\n\n## 1.2.0\n\n### Minor Changes\n\n- b2cfd00: Add teardown API to remove WASM instance after using the compiler\n\n## 1.1.2\n\n### Patch Changes\n\n- 2de6128: Preserve namespaced attributes when using expressions\n- af13f2d: Fix incorrect `convertToTSX` types. The function accepts `filename`, not `sourcefile`.\n- 5eb4fff: Compile `set:html` and `set:text` quoted and template literal attributes as strings\n\n## 1.1.1\n\n### Patch Changes\n\n- 6765f01: Fix attributes starting with : not being properly transformed in the TSX output\n\n## 1.1.0\n\n### Minor Changes\n\n- a75824d: Allow passing through result to slot call\n\n## 1.0.2\n\n### Patch Changes\n\n- 0c27f3f: Collapse multiple trailing text nodes if present\n\n## 1.0.1\n\n### Patch Changes\n\n- 94b2c02: Prevent insertion of maybeRenderHead on hoisted scripts\n\n## 1.0.0\n\n### Major Changes\n\n- 8e86bc6: The Astro compiler is officially stable! This release is entirely ceremonial, the code is the same as [`@astrojs/compiler@0.33.0`](https://github.com/withastro/compiler/releases/tag/%40astrojs%2Fcompiler%400.33.0)\n\n## 0.33.0\n\n### Minor Changes\n\n- 1adac72: Improve error recovery when using the `transform` function. The compiler will now properly reject the promise with a useful message and stacktrace rather than print internal errors to stdout.\n\n### Patch Changes\n\n- 68d3c0c: Fix edge case where `export type` could hang the compiler\n- ec1ddf0: Handle edge case with TypeScript generics handling and our TSX output\n- 23d1fc0: Ignore trailing whitespace in components\n\n## 0.32.0\n\n### Minor Changes\n\n- 2404848: Remove `pathname` option in favour of `sourcefile` option\n- 2ca86f6: Remove `site` and `projectRoot` options in favour of the `astroGlobalArgs` option\n- edd3e0e: Merge `sourcefile` and `moduleId` options as a single `filename` option. Add a new `normalizedFilename` option to generate stable hashes instead.\n- 08843bd: Remove `experimentalStaticExtraction` option. It is now the default.\n\n## 0.31.4\n\n### Patch Changes\n\n- 960b853: Rename `SerializeOtions` interface to `SerializeOptions`\n- fcab891: Fixes export hoisting edge case\n- 47de01a: Handle module IDs containing quotes\n\n## 0.31.3\n\n### Patch Changes\n\n- fd5cb57: Rollback https://github.com/withastro/compiler/pull/674\n\n## 0.31.2\n\n### Patch Changes\n\n- 89c0cee: fix: corner case that component in head expression will case body tag missing\n- 20497f4: Improve fidelity of sourcemaps for frontmatter\n\n## 0.31.1\n\n### Patch Changes\n\n- 24dcf7e: Allow `script` and `style` before HTML\n- ef391fa: fix: corner case with slot expression in head will cause body tag missing\n\n## 0.31.0\n\n### Minor Changes\n\n- abdddeb: Update Go to 1.19\n\n## 0.30.1\n\n### Patch Changes\n\n- ff9e7ba: Fix edge case where `<` was not handled properly inside of expressions\n- f31d535: Fix edge case with Prop detection for TSX output\n\n## 0.30.0\n\n### Minor Changes\n\n- 963aaab: Provide the moduleId of the astro component\n\n## 0.29.19\n\n### Patch Changes\n\n- 3365233: Replace internal tokenizer state logs with proper warnings\n\n## 0.29.18\n\n### Patch Changes\n\n- 80de395: fix: avoid nil pointer dereference in table parsing\n- aa3ad9d: Fix `parse` output to properly account for the location of self-closing tags\n- b89dec4: Internally, replace `astro.ParseFragment` in favor of `astro.ParseFragmentWithOptions`. We now check whether an error handler is passed when calling `astro.ParseFragmentWithOptions`\n\n## 0.29.17\n\n### Patch Changes\n\n- 1e7e098: Add warning for invalid spread attributes\n- 3cc6f55: Fix handling of unterminated template literal attributes\n- 48c5677: Update default `internalURL` to `astro/runtime/server/index.js`\n- 2893f33: Fix a number of `table` and `expression` related bugs\n\n## 0.29.16\n\n### Patch Changes\n\n- ec745f4: Self-closing tags will now retrieve \"end\" positional data\n- a6c2822: Fix a few TSX output errors\n\n## 0.29.15\n\n### Patch Changes\n\n- 5f6e69b: Fix expression literal handling\n\n## 0.29.14\n\n### Patch Changes\n\n- 6ff1d80: Fix regression introduced by https://github.com/withastro/compiler/pull/617\n\n## 0.29.13\n\n### Patch Changes\n\n- 8f3e488: Fix regression introduced to `parse` handling in the last patch\n\n## 0.29.12\n\n### Patch Changes\n\n- a41982a: Fix expression edge cases, improve literal parsing\n\n## 0.29.11\n\n### Patch Changes\n\n- ee907f1: Fix #5308, duplicate style bug when using `define:vars`\n\n## 0.29.10\n\n### Patch Changes\n\n- 07a65df: Print `\\r` when printing TSX output\n- 1250d0b: Add warning when `define:vars` won't work because of compilation limitations\n\n## 0.29.9\n\n### Patch Changes\n\n- 1fe92c0: Fix TSX sourcemaps on Windows (take 4)\n\n## 0.29.8\n\n### Patch Changes\n\n- 01b62ea: Fix sourcemap bug on Windows (again x2)\n\n## 0.29.7\n\n### Patch Changes\n\n- 108c6c9: Fix TSX sourcemap bug on Windows (again)\n\n## 0.29.6\n\n### Patch Changes\n\n- 4b3fafa: Fix TSX sourcemaps on Windows\n\n## 0.29.5\n\n### Patch Changes\n\n- 73a2b69: Use an IIFE for define:vars scripts\n\n## 0.29.4\n\n### Patch Changes\n\n- 4381efa: Return proper diagnostic code for warnings\n\n## 0.29.3\n\n### Patch Changes\n\n- 85e1d31: AST: move `start` position of elements to the first index of their opening tag\n\n## 0.29.2\n\n### Patch Changes\n\n- 035829b: AST: move end position of elements to the last index of their end tag\n\n## 0.29.1\n\n### Patch Changes\n\n- a99c014: Ensure comment and text nodes have end positions when generating an AST from `parse`\n\n## 0.29.0\n\n### Minor Changes\n\n- fd2fc28: Fix some utf8 compatibility issues\n\n### Patch Changes\n\n- 4b68670: TSX: fix edge case with spread attribute printing\n- 6b204bd: Fix bug with trailing `style` tags being moved into the `html` element\n- 66fe230: Fix: include element end location in `parse` AST\n\n## 0.28.1\n\n### Patch Changes\n\n- aac8c89: Fix end tag sourcemappings for TSX mode\n- d7f3288: TSX: Improve self-closing tag behavior and mappings\n- 75dd7cc: Fix spread attribute mappings\n\n## 0.28.0\n\n### Minor Changes\n\n- 5da0dc2: Add `resolvePath` option to control hydration path resolution\n- e816a61: Remove metadata export if `resolvePath` option provided\n\n## 0.27.2\n\n### Patch Changes\n\n- 959f96b: Fix \"missing sourcemap\" issue\n- 94f6f3e: Fix edge case with multi-line comment usage\n- 85a654a: Fix `parse` causing a compiler panic when a component with a client directive was imported but didn't have a matching import\n- 5e32cbe: Improvements to TSX output\n\n## 0.27.1\n\n### Patch Changes\n\n- cc9f174: fixed regression caused by #546\n\n## 0.27.0\n\n### Minor Changes\n\n- c770e7b: The compiler will now return `diagnostics` and unique error codes to be handled by the consumer. For example:\n\n  ```js\n  import type {\n    DiagnosticSeverity,\n    DiagnosticCode,\n  } from \"@astrojs/compiler/types\";\n  import { transform } from \"@astrojs/compiler\";\n\n  async function run() {\n    const { diagnostics } = await transform(file, opts);\n\n    function log(severity: DiagnosticSeverity, message: string) {\n      switch (severity) {\n        case DiagnosticSeverity.Error:\n          return console.error(message);\n        case DiagnosticSeverity.Warning:\n          return console.warn(message);\n        case DiagnosticSeverity.Information:\n          return console.info(message);\n        case DiagnosticSeverity.Hint:\n          return console.info(message);\n      }\n    }\n\n    for (const diagnostic of diagnostics) {\n      let message = diagnostic.text;\n      if (diagnostic.hint) {\n        message += `\\n\\n[hint] ${diagnostic.hint}`;\n      }\n\n      // Or customize messages for a known DiagnosticCode\n      if (diagnostic.code === DiagnosticCode.ERROR_UNMATCHED_IMPORT) {\n        message = `My custom message about an unmatched import!`;\n      }\n      log(diagnostic.severity, message);\n    }\n  }\n  ```\n\n### Patch Changes\n\n- 0b24c24: Implement automatic typing for Astro.props in the TSX output\n\n## 0.26.1\n\n### Patch Changes\n\n- 920898c: Handle edge case with `noscript` tags\n- 8ee78a6: handle slots that contains the head element\n- 244e43e: Do not hoist import inside object\n- b8cd954: Fix edge case with line comments and export hoisting\n- 52ebfb7: Fix parse/tsx output to gracefully handle invalid HTML (style outside of body, etc)\n- 884efc6: Fix edge case with multi-line export hoisting\n\n## 0.26.0\n\n### Minor Changes\n\n- 0be58ab: Improve sourcemap support for TSX output\n\n### Patch Changes\n\n- e065e29: Prevent head injection from removing script siblings\n\n## 0.25.2\n\n### Patch Changes\n\n- 3a51b8e: Ensure that head injection occurs if there is only a hoisted script\n\n## 0.25.1\n\n### Patch Changes\n\n- 41fae67: Do not scope empty style blocks\n- 1ab8280: fix(#517): fix edge case with TypeScript transform\n- a3678f9: Fix import.meta.env usage above normal imports\n\n## 0.25.0\n\n### Minor Changes\n\n- 6446ea3: Make Astro styles being printed after user imports\n\n### Patch Changes\n\n- 51bc60f: Fix edge cases with `getStaticPaths` where valid JS syntax was improperly handled\n\n## 0.24.0\n\n### Minor Changes\n\n- 6ebcb4f: Allow preprocessStyle to return an error\n\n### Patch Changes\n\n- abda605: Include filename when calculating scope\n\n## 0.23.5\n\n### Patch Changes\n\n- 6bc8e0b: Prevent import assertion from being scanned too soon\n\n## 0.23.4\n\n### Patch Changes\n\n- 3b9f0d2: Remove css print escape for experimentalStaticExtraction\n\n## 0.23.3\n\n### Patch Changes\n\n- 7693d76: Fix resolution of .jsx modules\n\n## 0.23.2\n\n### Patch Changes\n\n- 167ad21: Improve handling of namespaced components when they are multiple levels deep\n- 9283258: Fix quotations in pre-quoted attributes\n- 76fcef3: Better handling for imports which use special characters\n\n## 0.23.1\n\n### Patch Changes\n\n- 79376f3: Fix regression with expression rendering\n\n## 0.23.0\n\n### Minor Changes\n\n- d8448e2: Prevent printing the doctype in the JS output\n\n### Patch Changes\n\n- a28c3d8: Fix handling of unbalanced quotes in expression attributes\n- 28d1d4d: Fix handling of TS generics inside of expressions\n- 356d3b6: Prevent wrapping module scripts with scope\n\n## 0.22.1\n\n### Patch Changes\n\n- 973103c: Prevents unescaping attribute expressions\n\n## 0.22.0\n\n### Minor Changes\n\n- 558c9dd: Generate a stable scoped class that does _NOT_ factor in local styles. This will allow us to safely do style HMR without needing to update the DOM as well.\n- c19cd8c: Update Astro's CSS scoping algorithm to implement zero-specificity scoping, according to [RFC0012](https://github.com/withastro/rfcs/blob/main/proposals/0012-scoped-css-with-preserved-specificity.md).\n\n## 0.21.0\n\n### Minor Changes\n\n- 8960d82: New handling for `define:vars` scripts and styles\n\n### Patch Changes\n\n- 4b318d5: Do not attempt to hoist styles or scripts inside of `<noscript>`\n- d6ebab6: Fixing missing semicolon on TSX Frontmatter last-entries\n\n## 0.20.0\n\n### Minor Changes\n\n- 48d33ff: Removes compiler special casing for the Markdown component\n- 4a5352e: Removes limitation where imports/exports must be at the top of an `.astro` file. Fixes various edge cases around `getStaticPaths` hoisting.\n\n### Patch Changes\n\n- 245d73e: Add support for HTML minification by passing `compact: true` to `transform`.\n- 3ecdd24: Update TSX output to also generate TSX-compatible code for attributes containing dots\n\n## 0.19.0\n\n### Minor Changes\n\n- fcb4834: Removes fallback for the site configuration\n\n### Patch Changes\n\n- 02add77: Fixes many edge cases around tables when used with components, slots, or expressions\n- b23dd4d: Fix handling of unmatched close brace in template literals\n- 9457a91: Fix issue with `{` in template literal attributes\n- c792161: Fix nested expression handling with a proper expression tokenizer stack\n\n## 0.18.2\n\n### Patch Changes\n\n- f8547a7: Revert [#448](https://github.com/withastro/compiler/pull/448) for now\n\n## 0.18.1\n\n### Patch Changes\n\n- aff2f23: Warning on client: usage on scripts\n\n## 0.18.0\n\n### Minor Changes\n\n- 4b02776: Fix handling of `slot` attribute used inside of expressions\n\n### Patch Changes\n\n- 62d2a8e: Properly handle nested expressions that return multiple elements\n- 571d6b9: Ensure `html` and `body` elements are scoped\n\n## 0.17.1\n\n### Patch Changes\n\n- 3885217: Support `<slot is:inline />` and preserve slot attribute when not inside component\n- ea94a26: Fix issue with fallback content inside of slots\n\n## 0.17.0\n\n### Minor Changes\n\n- 3a9d166: Add renderHead injection points\n\n## 0.16.1\n\n### Patch Changes\n\n- 9fcc43b: Build JS during the release\n\n## 0.16.0\n\n### Minor Changes\n\n- 470efc0: Adds component metadata to the TransformResult\n\n### Patch Changes\n\n- c104d4f: Fix #418: duplicate text when only text\n\n## 0.15.2\n\n### Patch Changes\n\n- f951822: Fix wasm `parse` to save attribute namespace\n- 5221e09: Fix serialize spread attribute\n\n## 0.15.1\n\n### Patch Changes\n\n- 26cbcdb: Prevent side-effectual CSS imports from becoming module metadata\n\n## 0.15.0\n\n### Minor Changes\n\n- 702e848: Trailing space at the end of Astro files is now stripped from Component output.\n\n### Patch Changes\n\n- 3a1a24b: Fix long-standing bug where a `class` attribute inside of a spread prop will cause duplicate `class` attributes\n- 62faceb: Fixes an issue where curly braces in `<math>` elements would get parsed as expressions instead of raw text.\n\n## 0.14.3\n\n### Patch Changes\n\n- 6177620: Fix edge case with expressions inside of tables\n- 79b1ed6: Provides a better error message when we can't match client:only usage to an import statement\n- a4e1957: Fix Astro scoping when `class:list` is used\n- fda859a: Fix json escape\n\n## 0.14.2\n\n### Patch Changes\n\n- 6f30e2e: Fix edge case with nested expression inside `<>`\n- 15e3ff8: Fix panic when using a `<slot />` in `head`\n- c048567: Fix edge case with `select` elements and expression children\n- 13d2fc2: Fix #340, fixing behavior of content after an expression inside of `<select>`\n- 9e37a72: Fix issue when multiple client-only components are used\n- 67993d5: Add support for block comment only expressions, block comment only shorthand attributes and block comments in shorthand attributes\n- 59fbea2: Fix #343, edge case with `<tr>` inside component\n- 049dadf: Fix usage of expressions inside `caption` and `colgroup` elements\n\n## 0.14.1\n\n### Patch Changes\n\n- 1a82892: Fix bug with `<script src>` not being hoisted\n\n## 0.14.0\n\n### Minor Changes\n\n- c0da4fe: Implements [RFC0016](https://github.com/withastro/rfcs/blob/main/proposals/0016-style-script-defaults.md), the new `script` and `style` behavior.\n\n## 0.13.2\n\n### Patch Changes\n\n- 014370d: Fix issue with named slots in <head> element\n- da831c1: Fix handling of RegExp literals in frontmatter\n\n## 0.13.1\n\n### Patch Changes\n\n- 2f8334c: Update `parse` and `serialize` functions to combine `attributes` and `directives`, fix issue with `serialize` not respecting `attributes`.\n- b308955: Add self-close option to serialize util\n\n## 0.13.0\n\n### Minor Changes\n\n- ce3f1a5: Update CSS parser to use `esbuild`, adding support for CSS nesting, `@container`, `@layer`, and other modern syntax features\n\n### Patch Changes\n\n- 24a1185: Parser: Always output the `children` property in an element node, even if it has no children\n\n## 0.12.1\n\n### Patch Changes\n\n- 097ac47: Parser: Always output the `attribute` property in an element node, even if empty\n- ad62437: Add `serialize` util\n- eb7eb95: Parse: fix escaping of `&` characters in AST output\n\n## 0.12.0\n\n### Minor Changes\n\n- c6dd41d: Do not render implicit tags created during the parsing process\n- c6dd41d: Remove \"as\" option, treats all documents as fragments that generate no implicit tags\n- c6dd41d: Add `parse` function which generates an AST\n- c6dd41d: Adds support for `Astro.self` (as accepted in the [Recursive Components RFC](https://github.com/withastro/rfcs/blob/main/active-rfcs/0000-recursive-components.md)).\n\n### Patch Changes\n\n- c6dd41d: Add `fragment` node types to AST definitions, expose Fragment helper to utils\n- c6dd41d: Adds metadata on client:only components\n- c6dd41d: Expose AST types via `@astrojs/compiler/types`\n- c6dd41d: Export `./types` rather than `./types.d.ts`\n- c6dd41d: Fix edge case with Fragment parsing in head, add `fragment` node to AST output\n- c6dd41d: Fix <slot> behavior inside of head\n- c6dd41d: Improve head injection behavior\n- ef0b4b3: Move `typescript` dependency to development dependencies, as it is not needed in the package runtime.\n- c6dd41d: Update exposed types\n- c6dd41d: Remove usage of `escapeHTML` util\n- c6dd41d: Export all types from shared types\n- c6dd41d: Fix `head` behavior and a bug related to ParseFragment\n- c6dd41d: Adds a warning when using an expression with a hoisted script\n\n## 0.12.0-next.9\n\n### Patch Changes\n\n- 95ec808: Fix <slot> behavior inside of head\n- 95ec808: Remove usage of `escapeHTML` util\n\n## 0.12.0-next.8\n\n### Patch Changes\n\n- 4497628: Improve head injection behavior\n\n## 0.12.0-next.7\n\n### Patch Changes\n\n- e26b9d6: Fix edge case with Fragment parsing in head, add `fragment` node to AST output\n\n## 0.12.0-next.6\n\n### Patch Changes\n\n- 37ef1c1: Fix `head` behavior and a bug related to ParseFragment\n\n## 0.12.0-next.5\n\n### Patch Changes\n\n- 97cf66b: Adds metadata on client:only components\n\n## 0.12.0-next.4\n\n### Patch Changes\n\n- e2061dd: Export all types from shared types\n\n## 0.12.0-next.3\n\n### Patch Changes\n\n- ef69b74: Export `./types` rather than `./types.d.ts`\n\n## 0.12.0-next.2\n\n### Patch Changes\n\n- 073b0f1: Adds a warning when using an expression with a hoisted script\n\n## 0.12.0-next.1\n\n### Patch Changes\n\n- a539d53: Update exposed types\n\n## 0.12.0-next.0\n\n### Minor Changes\n\n- 8ce39c7: Do not render implicit tags created during the parsing process\n- 41b825a: Remove \"as\" option, treats all documents as fragments that generate no implicit tags\n- 483b34b: Add `parse` function which generates an AST\n- 9e5e2f8: Adds support for `Astro.self` (as accepted in the [Recursive Components RFC](https://github.com/withastro/rfcs/blob/main/active-rfcs/0000-recursive-components.md)).\n\n### Patch Changes\n\n- 16b167c: Expose AST types via `@astrojs/compiler/types`\n\n## 0.11.4\n\n### Patch Changes\n\n- 99b5de2: Reset tokenizer state when a raw element that is self-closing is encountered.\n\n  This fixes the handling of self-closing elements like `<title />` and `<script />` when used with `set:html`.\n\n## 0.11.3\n\n### Patch Changes\n\n- dcf15bf: Fixes bug causing a crash when using Astro.resolve on a hoisted script\n\n## 0.11.2\n\n### Patch Changes\n\n- 41cc6ef: Fix memory issue caused by duplicate WASM instantiations\n\n## 0.11.1\n\n### Patch Changes\n\n- 4039682: Fixes hoist script tracking when passed a variable\n\n## 0.11.0\n\n### Minor Changes\n\n- f5d4006: Switch from TinyGo to Go's built-in WASM output. While this is an unfortunate size increase for our `.wasm` file, it should also be significantly more stable and cut down on hard-to-reproduce bugs.\n\n  Please see https://github.com/withastro/compiler/pull/291 for more details.\n\n## 0.11.0-next--wasm.0\n\n### Minor Changes\n\n- 9212ccc: Switch from TinyGo to Go's built-in WASM output. While this is an unfortunate size increase for our `WASM` file, it should also be significantly more stable and cut down on hard-to-reproduce bugs.\n\n  Please see https://github.com/withastro/compiler/pull/291 for more details.\n\n## 0.10.2\n\n### Patch Changes\n\n- 7f7c65c: Fix conditional rendering for special elements like `iframe` and `noscript`\n- 9d789c9: Fix handling of nested template literals inside of expressions\n- 5fa9e53: Fix handling of special characters inside of expressions\n- 8aaa956: Formalize support for magic `data-astro-raw` attribute with new, official `is:raw` directive\n- c698350: Improve MathML support. `{}` inside of `<math>` is now treated as raw text rather than an expression construct.\n\n## 0.10.1\n\n### Patch Changes\n\n- 38ae39a: Add support for `set:html` and `set:text` directives, as designed in the [`set:html` RFC](https://github.com/withastro/rfcs/blob/main/active-rfcs/0000-set-html.md).\n\n## 0.10.0\n\n### Minor Changes\n\n- 02d41a8: Adds support for `Astro.self` (as accepted in the [Recursive Components RFC](https://github.com/withastro/rfcs/blob/main/active-rfcs/0000-recursive-components.md)).\n\n### Patch Changes\n\n- 4fe522b: Fixes inclusion of define:vars scripts/styles using the StaticExtraction flag\n\n## 0.9.2\n\n### Patch Changes\n\n- 92cc76b: Fix wasm build for use in Astro\n\n## 0.9.1\n\n### Patch Changes\n\n- 85d35a5: Revert previous change that broke Windows\n\n## 0.9.0\n\n### Minor Changes\n\n- c1a0172: changing raw_with_expression_loop in tokenizer to only handle string that has '`' differently otherwise it should treat it as normal string\n\n### Patch Changes\n\n- 1fa2162: Improved types for TransformResult with hoisted scripts\n\n## 0.8.2\n\n### Patch Changes\n\n- 502f8b8: Adds a new property, `scripts`, to `TransformResult`\n\n## 0.8.1\n\n### Patch Changes\n\n- cd277e2: Fix bug with data-astro-raw detection\n\n## 0.8.0\n\n### Minor Changes\n\n- 3690968: Passes the Pathname to createAstro instead of import.meta.url\n\n## 0.7.4\n\n### Patch Changes\n\n- afc1e82: Remove console log (sorry!)\n\n## 0.7.3\n\n### Patch Changes\n\n- cc24069: Fix some edge cases with expressions inside of `<table>` elements\n- 086275c: Fix edge case with textarea inside expression\n\n## 0.7.2\n\n### Patch Changes\n\n- 899e48d: Fix issue with active formatting elements by marking expressions as unique scopes\n\n## 0.7.1\n\n### Patch Changes\n\n- fa039dd: Fix tokenization of attribute expression containing the solidus (`/`) character\n- e365c3c: Fix bug with expressions inside of <table> elements (without reverting a previous fix to expressions inside of <a> elements)\n- 7c5889f: Fix bug with `@keyframes` scoping\n- df74ab3: Fix bug where named grid columns (like `[content-start]`) would be scoped, producing invalid CSS\n- abe37ca: Fix handling of components and expressions inside of `<noscript>`\n- 8961cf4: Fix a logical error with expression tokenization when using nested functions. Previously, only the first brace pair would be respected and following pairs would be treated as expression boundaries.\n\n## 0.7.0\n\n### Minor Changes\n\n- 43cbac3: Adds metadata on hydration directives used by the component\n\n## 0.6.2\n\n### Patch Changes\n\n- e785310: Fix issue with import assertions creating additional imports\n\n## 0.6.1\n\n### Patch Changes\n\n- e40ea9c: Include LICENSE information\n\n## 0.6.0\n\n### Minor Changes\n\n- b9e2b4b: Adds option to make CSS be extracted statically\n\n## 0.5.7\n\n### Patch Changes\n\n- 75bd730: Fix regression with Components mixed with active formatting elements\n\n## 0.5.6\n\n### Patch Changes\n\n- 7ca419e: Improve behavior of empty expressions in body and attributes, where `{}` is equivalent to `{(void 0)}`\n\n## 0.5.5\n\n### Patch Changes\n\n- 7a41d7b: Fix `<>` syntax edge case inside of expressions\n- b0d35b9: Fix edge case with conditional scripts\n\n## 0.5.4\n\n### Patch Changes\n\n- f2e0322: Do not reconstruct active formatting elements on expression start\n- 0103285: Bugfix: expressions in table context\n\n## 0.5.3\n\n### Patch Changes\n\n- 50cbc57: Fix fragment expression behavior edge case\n\n## 0.5.2\n\n### Patch Changes\n\n- 8f0e3d7: Fix fragment parsing bugs when frontmatter is missing or top-level expressions are present\n\n## 0.5.1\n\n### Patch Changes\n\n- 1f0ba41: Fix bug when fragment parsing frontmatter is missing\n\n## 0.5.0\n\n### Minor Changes\n\n- 901faef: Passes projectRoot to createAstro\n\n## 0.4.0\n\n### Minor Changes\n\n- 7e1aded: Change behavior of `as: \"fragment\"` option to support arbitrary `head` and `body` tags\n\n## 0.3.9\n\n### Patch Changes\n\n- 2884a82: Bugfix: CSS comments insert semicolon\n\n## 0.3.8\n\n### Patch Changes\n\n- 2c8f5d8: Fix another component-only edge case\n\n## 0.3.7\n\n### Patch Changes\n\n- eb0d17f: Fix edge case with files that contain a single component\n\n## 0.3.6\n\n### Patch Changes\n\n- af003e9: Fix syntax error in transformed output\n\n## 0.3.5\n\n### Patch Changes\n\n- bca7e00: Fixed issue where an Astro Components could only add one style or script\n- 2a2f951: Fix regression where leading `<style>` elements could break generated tags\n- db162f8: Fix case-sensitivity of void elements\n- 44ee189: Fixed issue where expressions did not work within SVG elements\n- 9557113: Fix panic when preprocessed style is empty\n\n## 0.3.4\n\n### Patch Changes\n\n- 351f298: Fix edge case with with `textarea` inside of a Component when the document generated an implicit `head` tag\n- 0bcfd4b: Fix CSS scoping of \\* character inside of calc() expressions\n- 4be512f: Encode double quotes inside of quoted attributes\n- ad865e5: Fix behavior of expressions inside of <table> elements\n\n## 0.3.3\n\n### Patch Changes\n\n- 6d2a3c2: Fix handling of top-level component nodes with leading styles\n- 2ce10c6: Fix \"call to released function\" issue\n\n## 0.3.2\n\n### Patch Changes\n\n- 8800f80: Fix comments and strings inside of attribute expressions\n\n## 0.3.1\n\n### Patch Changes\n\n- 432eaaf: Fix for compiler regression causing nil pointer\n\n## 0.3.0\n\n### Minor Changes\n\n- 1255477: Drop support for elements inside of Frontmatter, which was undefined behavior that caused lots of TypeScript interop problems\n\n### Patch Changes\n\n- 44dc0c6: Fixes issue with \\x00 character on OSX\n- d74acfa: Fix regression with expressions inside of <select> elements\n- f50ae69: Bugfix: don’t treat import.meta as import statement\n\n## 0.2.27\n\n### Patch Changes\n\n- 460c1e2: Use `$metadata.resolvePath` utility to support the `client:only` directive\n\n## 0.2.26\n\n### Patch Changes\n\n- 3e5ef91: Implement getStaticPaths hoisting\n- 8a434f9: Fix namespace handling to support attributes like `xmlns:xlink`\n\n## 0.2.25\n\n### Patch Changes\n\n- 59f36cb: Fix custom-element slot behavior to remain spec compliant\n- 79b2e6f: Fix style/script ordering\n- 6041ee5: Add support for `client:only` directive\n- 2cd35f6: Fix apostrophe handling inside of elements which are inside of expressions ([#1478](https://github.com/snowpackjs/astro/issues/1478))\n\n## 0.2.24\n\n### Patch Changes\n\n- bfd1b94: Fix issue with `style` and `script` processing where siblings would be skipped\n- 726d272: Fix <Fragment> and <> handling\n- f052465: Fix CSS variable parsing in the scoped CSS transform\n\n## 0.2.23\n\n### Patch Changes\n\n- 632c29b: Fix nil pointer dereference when every element on page is a component\n- 105a159: Fix bug where text inside of elements inside of an expression was not read properly (https://github.com/snowpackjs/astro/issues/1617)\n\n## 0.2.22\n\n### Patch Changes\n\n- 04c1b63: Fix bug with dynamic classes\n\n## 0.2.21\n\n### Patch Changes\n\n- 7b46e9f: Revert automatic DOCTYPE injection to fix package\n\n## 0.2.20\n\n### Patch Changes\n\n- 39298e4: Fix small bugs with script/style hoisting behavior\n- bd1014a: Bugfix: style tags in SVG\n\n## 0.2.19\n\n### Patch Changes\n\n- 318dd69: Fix handling of self-closing \"raw\" tags like <script /> and <style />\n- 9372c10: Support `define:vars` with root `html` element on pages\n- c4491cd: Fix bug with <script define:vars> when not using the `hoist` attribute\n\n## 0.2.18\n\n### Patch Changes\n\n- 2f4b772: Prevents overrunning an array when checking for raw attribute\n\n## 0.2.17\n\n### Patch Changes\n\n- 4f9155a: Bugfix: fix character limit of 4096 characters\n- 83df04c: Upgrade to Go 1.17\n\n## 0.2.16\n\n### Patch Changes\n\n- 9ad8da7: Allows a data-astro-raw attr to parse children as raw text\n- 61b77de: Bugfix: CSS and selector scoping\n\n## 0.2.15\n\n### Patch Changes\n\n- 8fbae5e: Bugfix: fix component detection bug in parser\n- 37b5b6e: Bugfix: wait to release processStyle() until after fn call\n\n## 0.2.14\n\n### Patch Changes\n\n- f59c886: Bugfix: allow for detection of void tags (e.g. <img>)\n- 4c8d14a: Fixes textContent containing a forward slash\n\n## 0.2.13\n\n### Patch Changes\n\n- f262b61: Fix for string template usage within expressions\n\n## 0.2.12\n\n### Patch Changes\n\n- c9fa9eb: Fix for apostrophe within elements\n\n## 0.2.11\n\n### Patch Changes\n\n- 27629b2: Reverts the apostrophe change that broke markdown parsing\n\n## 0.2.10\n\n### Patch Changes\n\n- 57eb728: Fixes hydrated scripts not recognized when using fragment transformation\n\n## 0.2.9\n\n### Patch Changes\n\n- 3ea8d8c: Fix for string interpolation within titles\n- ef7cb1e: Fixes bug with textContent containing apostrophe character\n\n## 0.2.8\n\n### Patch Changes\n\n- b2d5564: Fixes wasm build\n\n## 0.2.6\n\n### Patch Changes\n\n- fix small issue with `preprocessStyle` handling of `null` or `undefined`\n\n## 0.2.5\n\n### Patch Changes\n\n- Fix issue with CI deployment\n\n## 0.2.4\n\n### Patch Changes\n\n- 4410c5a: Add support for a `preprocessStyle` function\n- 934e6a6: Chore: add linting, format code\n\n## 0.1.15\n\n### Patch Changes\n\n- 5c02abf: Fix split so it always splits on first non-import/export\n- 93c1cd9: Bugfix: handle RegExp in Astro files\n- 94c59fa: Bugfix: tokenizer tries to parse JS comments\n- 46a5c75: Adds the top-level Astro object\n- 7ab9148: Improve JS scanning algorithm to be more fault tolerant, less error prone\n\n## 0.1.12\n\n### Patch Changes\n\n- 96dc356: Adds hydrationMap support for custom elements\n\n## 0.1.11\n\n### Patch Changes\n\n- 939283d: Adds the component export for use in hydration\n\n## 0.1.10\n\n### Patch Changes\n\n- 3a336ef: Adds a hydration map to enable hydration within Astro components\n\n## 0.1.9\n\n### Patch Changes\n\n- 7d887de: Allows the Astro runtime to create the Astro.slots object\n\n## 0.1.8\n\n### Patch Changes\n\n- d159658: Publish via PR\n\n## 0.1.7\n\n### Patch Changes\n\n- c52e69b: Include astro.wasm in the package\n\n## 0.1.6\n\n### Patch Changes\n\n- bd05f7c: Actually include _any_ files?\n\n## 0.1.5\n\n### Patch Changes\n\n- c4ed69e: Includes the wasm binary in the npm package\n\n## 0.1.4\n\n### Patch Changes\n\n- 2f1f1b8: Pass custom element tag names to renderComponent as strings\n\n## 0.1.3\n\n### Patch Changes\n\n- e4e2de5: Update to [`tinygo@0.20.0`](https://github.com/tinygo-org/tinygo/releases/tag/v0.20.0) and remove `go@1.16.x` restriction.\n- ae71546: Add support for `fragment` compilation, to be used with components rather than pages\n- 8c2aaf9: Allow multiple top-level conditional expressions\n\n## 0.1.0\n\n### Patch Changes\n\n- c9407cd: Fix for using conditionals at the top-level\n"
  },
  {
    "path": "packages/compiler/README.md",
    "content": "# Astro Compiler\n\nAstro’s [Go](https://golang.org/) + WASM compiler.\n\n## Install\n\n```\nnpm install @astrojs/compiler\n```\n\n## Usage\n\n#### Transform `.astro` to valid TypeScript\n\nThe Astro compiler can convert `.astro` syntax to a TypeScript Module whose default export generates HTML.\n\n**Some notes**...\n\n- TypeScript is valid `.astro` syntax! The output code may need an additional post-processing step to generate valid JavaScript.\n- `.astro` files rely on a server implementation exposed as `astro/runtime/server/index.js` in the Node ecosystem. Other runtimes currently need to bring their own rendering implementation and reference it via `internalURL`. This is a pain point we're looking into fixing.\n\n```js\nimport { transform, type TransformResult } from \"@astrojs/compiler\";\n\nconst result = await transform(source, {\n  filename: \"/Users/astro/Code/project/src/pages/index.astro\",\n  sourcemap: \"both\",\n  internalURL: \"astro/runtime/server/index.js\",\n});\n```\n\n#### Parse `.astro` and return an AST\n\nThe Astro compiler can emit an AST using the `parse` method.\n\n**Some notes**...\n\n- Position data is currently incomplete and in some cases incorrect. We're working on it!\n- A `TextNode` can represent both HTML `text` and JavaScript/TypeScript source code.\n- The `@astrojs/compiler/utils` entrypoint exposes `walk` and `walkAsync` functions that can be used to traverse the AST. It also exposes the `is` helper which can be used as guards to derive the proper types for each `node`.\n\n```js\nimport { parse } from \"@astrojs/compiler\";\nimport { walk, walkAsync, is } from \"@astrojs/compiler/utils\";\n\nconst result = await parse(source, {\n  position: false, // defaults to `true`\n});\n\nwalk(result.ast, (node) => {\n  // `tag` nodes are `element` | `custom-element` | `component`\n  if (is.tag(node)) {\n    console.log(node.name);\n  }\n});\n\nawait walkAsync(result.ast, async (node) => {\n  if (is.tag(node)) {\n    node.value = await expensiveCalculation(node)\n  }\n});\n```\n\n## Develop\n\n### VSCode / CodeSpaces\n\nA `devcontainer` configuration is available for use with VSCode's [Remote Development extension pack](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack) and GitHub CodeSpaces.\n\n## Contributing\n\n[CONTRIBUTING.md](/CONTRIBUTING.md)\n"
  },
  {
    "path": "packages/compiler/package.json",
    "content": "{\n  \"name\": \"@astrojs/compiler\",\n  \"author\": \"withastro\",\n  \"license\": \"MIT\",\n  \"type\": \"module\",\n  \"bugs\": \"https://github.com/withastro/compiler/issues\",\n  \"homepage\": \"https://astro.build\",\n  \"version\": \"3.0.1\",\n  \"scripts\": {\n    \"build\": \"tsup\"\n  },\n  \"main\": \"./dist/node/index.js\",\n  \"types\": \"./dist/shared/types.d.ts\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/withastro/compiler.git\"\n  },\n  \"files\": [\n    \"dist\",\n    \"types.d.ts\",\n    \"utils.d.ts\",\n    \"sync.d.ts\"\n  ],\n  \"exports\": {\n    \".\": {\n      \"types\": \"./dist/node/index.d.ts\",\n      \"browser\": \"./dist/browser/index.js\",\n      \"import\": \"./dist/node/index.js\",\n      \"require\": \"./dist/node/index.cjs\",\n      \"default\": \"./dist/browser/index.js\"\n    },\n    \"./sync\": {\n      \"types\": \"./dist/node/sync.d.ts\",\n      \"import\": \"./dist/node/sync.js\",\n      \"require\": \"./dist/node/sync.cjs\",\n      \"default\": \"./dist/node/sync.js\"\n    },\n    \"./utils\": {\n      \"types\": \"./dist/node/utils.d.ts\",\n      \"browser\": \"./dist/browser/utils.js\",\n      \"import\": \"./dist/node/utils.js\",\n      \"require\": \"./dist/node/utils.cjs\",\n      \"default\": \"./dist/browser/utils.js\"\n    },\n    \"./astro.wasm\": \"./dist/astro.wasm\",\n    \"./types\": \"./dist/shared/types.d.ts\",\n    \"./package.json\": \"./package.json\"\n  },\n  \"devDependencies\": {\n    \"@jridgewell/trace-mapping\": \"^0.3.16\",\n    \"@types/node\": \"^18.15.11\",\n    \"@types/sass\": \"^1.43.1\",\n    \"acorn\": \"^8.8.1\",\n    \"esbuild\": \"^0.17.17\",\n    \"tsup\": \"^6.7.0\",\n    \"typescript\": \"~5.0.2\"\n  }\n}\n"
  },
  {
    "path": "packages/compiler/src/browser/index.ts",
    "content": "import type * as types from '../shared/types.js';\nimport Go from './wasm_exec.js';\n\nexport const transform: typeof types.transform = (input, options) => {\n\treturn ensureServiceIsRunning().transform(input, options);\n};\n\nexport const parse: typeof types.parse = (input, options) => {\n\treturn ensureServiceIsRunning().parse(input, options);\n};\n\nexport const convertToTSX: typeof types.convertToTSX = (input, options) => {\n\treturn ensureServiceIsRunning().convertToTSX(input, options);\n};\n\ninterface Service {\n\ttransform: typeof types.transform;\n\tparse: typeof types.parse;\n\tconvertToTSX: typeof types.convertToTSX;\n}\n\nlet initializePromise: Promise<Service> | undefined;\nlet longLivedService: Service | undefined;\n\nexport const teardown: typeof types.teardown = () => {\n\tinitializePromise = undefined;\n\tlongLivedService = undefined;\n\t(globalThis as any)['@astrojs/compiler'] = undefined;\n};\n\nexport const initialize: typeof types.initialize = async (options) => {\n\tlet wasmURL = options.wasmURL;\n\tif (!wasmURL) throw new Error('Must provide the \"wasmURL\" option');\n\twasmURL += '';\n\tif (!initializePromise) {\n\t\tinitializePromise = startRunningService(wasmURL).catch((err) => {\n\t\t\t// Let the caller try again if this fails.\n\t\t\tinitializePromise = void 0;\n\t\t\t// But still, throw the error back up the caller.\n\t\t\tthrow err;\n\t\t});\n\t}\n\tlongLivedService = longLivedService || (await initializePromise);\n};\n\nconst ensureServiceIsRunning = (): Service => {\n\tif (!initializePromise) throw new Error('You need to call \"initialize\" before calling this');\n\tif (!longLivedService)\n\t\tthrow new Error(\n\t\t\t'You need to wait for the promise returned from \"initialize\" to be resolved before calling this'\n\t\t);\n\treturn longLivedService;\n};\n\nconst instantiateWASM = async (\n\twasmURL: string,\n\timportObject: Record<string, any>\n): Promise<WebAssembly.WebAssemblyInstantiatedSource> => {\n\tlet response = undefined;\n\n\tif (WebAssembly.instantiateStreaming) {\n\t\tresponse = await WebAssembly.instantiateStreaming(fetch(wasmURL), importObject);\n\t} else {\n\t\tconst fetchAndInstantiateTask = async () => {\n\t\t\tconst wasmArrayBuffer = await fetch(wasmURL).then((res) => res.arrayBuffer());\n\t\t\treturn WebAssembly.instantiate(wasmArrayBuffer, importObject);\n\t\t};\n\t\tresponse = await fetchAndInstantiateTask();\n\t}\n\n\treturn response;\n};\n\nconst startRunningService = async (wasmURL: string): Promise<Service> => {\n\tconst go = new Go();\n\tconst wasm = await instantiateWASM(wasmURL, go.importObject);\n\tgo.run(wasm.instance);\n\n\tconst service: any = (globalThis as any)['@astrojs/compiler'];\n\n\treturn {\n\t\ttransform: (input, options) =>\n\t\t\tnew Promise((resolve) => resolve(service.transform(input, options || {}))),\n\t\tconvertToTSX: (input, options) =>\n\t\t\tnew Promise((resolve) => resolve(service.convertToTSX(input, options || {}))).then(\n\t\t\t\t(result: any) => ({\n\t\t\t\t\t...result,\n\t\t\t\t\tmap: JSON.parse(result.map),\n\t\t\t\t})\n\t\t\t),\n\t\tparse: (input, options) =>\n\t\t\tnew Promise((resolve) => resolve(service.parse(input, options || {}))).then(\n\t\t\t\t(result: any) => ({ ...result, ast: JSON.parse(result.ast) })\n\t\t\t),\n\t};\n};\n"
  },
  {
    "path": "packages/compiler/src/browser/utils.ts",
    "content": "import type {\n\tCommentNode,\n\tComponentNode,\n\tCustomElementNode,\n\tDoctypeNode,\n\tElementNode,\n\tExpressionNode,\n\tFragmentNode,\n\tFrontmatterNode,\n\tLiteralNode,\n\tNode,\n\tParentNode,\n\tRootNode,\n\tTagLikeNode,\n\tTextNode,\n} from '../shared/ast.js';\n\nexport type Visitor = (node: Node, parent?: ParentNode, index?: number) => void | Promise<void>;\n\nfunction guard<Type extends Node>(type: string) {\n\treturn (node: Node): node is Type => node.type === type;\n}\n\nexport const is = {\n\tparent(node: Node): node is ParentNode {\n\t\treturn Array.isArray((node as any).children);\n\t},\n\tliteral(node: Node): node is LiteralNode {\n\t\treturn typeof (node as any).value === 'string';\n\t},\n\ttag(node: Node): node is TagLikeNode {\n\t\treturn (\n\t\t\tnode.type === 'element' ||\n\t\t\tnode.type === 'custom-element' ||\n\t\t\tnode.type === 'component' ||\n\t\t\tnode.type === 'fragment'\n\t\t);\n\t},\n\twhitespace(node: Node): node is TextNode {\n\t\treturn node.type === 'text' && node.value.trim().length === 0;\n\t},\n\troot: guard<RootNode>('root'),\n\telement: guard<ElementNode>('element'),\n\tcustomElement: guard<CustomElementNode>('custom-element'),\n\tcomponent: guard<ComponentNode>('component'),\n\tfragment: guard<FragmentNode>('fragment'),\n\texpression: guard<ExpressionNode>('expression'),\n\ttext: guard<TextNode>('text'),\n\tdoctype: guard<DoctypeNode>('doctype'),\n\tcomment: guard<CommentNode>('comment'),\n\tfrontmatter: guard<FrontmatterNode>('frontmatter'),\n};\n\nclass Walker {\n\tconstructor(private callback: Visitor) {}\n\tasync visit(node: Node, parent?: ParentNode, index?: number): Promise<void> {\n\t\tawait this.callback(node, parent, index);\n\t\tif (is.parent(node)) {\n\t\t\tconst promises = [];\n\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\tconst child = node.children[i];\n\t\t\t\tpromises.push(this.callback(child, node as ParentNode, i));\n\t\t\t}\n\t\t\tawait Promise.all(promises);\n\t\t}\n\t}\n}\n\nexport function walk(node: ParentNode, callback: Visitor): void {\n\tconst walker = new Walker(callback);\n\twalker.visit(node);\n}\n\nexport function walkAsync(node: ParentNode, callback: Visitor): Promise<void> {\n\tconst walker = new Walker(callback);\n\treturn walker.visit(node);\n}\n\nfunction serializeAttributes(node: TagLikeNode): string {\n\tlet output = '';\n\tfor (const attr of node.attributes) {\n\t\toutput += ' ';\n\t\tswitch (attr.kind) {\n\t\t\tcase 'empty': {\n\t\t\t\toutput += `${attr.name}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'expression': {\n\t\t\t\toutput += `${attr.name}={${attr.value}}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'quoted': {\n\t\t\t\toutput += `${attr.name}=${attr.raw}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'template-literal': {\n\t\t\t\toutput += `${attr.name}=\\`${attr.value}\\``;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'shorthand': {\n\t\t\t\toutput += `{${attr.name}}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'spread': {\n\t\t\t\toutput += `{...${attr.value}}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn output;\n}\n\nexport interface SerializeOptions {\n\tselfClose: boolean;\n}\n/** @deprecated Please use `SerializeOptions`  */\nexport type SerializeOtions = SerializeOptions;\n\nexport function serialize(root: Node, opts: SerializeOptions = { selfClose: true }): string {\n\tlet output = '';\n\tfunction visitor(node: Node) {\n\t\tif (is.root(node)) {\n\t\t\tfor (const child of node.children) {\n\t\t\t\tvisitor(child);\n\t\t\t}\n\t\t} else if (is.frontmatter(node)) {\n\t\t\toutput += `---${node.value}---\\n\\n`;\n\t\t} else if (is.comment(node)) {\n\t\t\toutput += `<!--${node.value}-->`;\n\t\t} else if (is.expression(node)) {\n\t\t\toutput += '{';\n\t\t\tfor (const child of node.children) {\n\t\t\t\tvisitor(child);\n\t\t\t}\n\t\t\toutput += '}';\n\t\t} else if (is.literal(node)) {\n\t\t\toutput += node.value;\n\t\t} else if (is.tag(node)) {\n\t\t\toutput += `<${node.name}`;\n\t\t\toutput += serializeAttributes(node);\n\t\t\tif (node.children.length === 0 && opts.selfClose) {\n\t\t\t\toutput += ' />';\n\t\t\t} else {\n\t\t\t\toutput += '>';\n\t\t\t\tfor (const child of node.children) {\n\t\t\t\t\tvisitor(child);\n\t\t\t\t}\n\t\t\t\toutput += `</${node.name}>`;\n\t\t\t}\n\t\t}\n\t}\n\tvisitor(root);\n\treturn output;\n}\n"
  },
  {
    "path": "packages/compiler/src/browser/wasm_exec.ts",
    "content": "// @ts-nocheck\n// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n//\n// This file has been modified for use by the TinyGo compiler.\n// This file has been further modified for use by Astro.\n\nconst enosys = () => {\n  const err = new Error('not implemented');\n  err.code = 'ENOSYS';\n  return err;\n};\n\nlet outputBuf = '';\nconst fs = {\n  constants: {\n    O_WRONLY: -1,\n    O_RDWR: -1,\n    O_CREAT: -1,\n    O_TRUNC: -1,\n    O_APPEND: -1,\n    O_EXCL: -1,\n  }, // unused\n  writeSync(fd, buf) {\n    outputBuf += decoder.decode(buf);\n    const nl = outputBuf.lastIndexOf('\\n');\n    if (nl != -1) {\n      console.log(outputBuf.substr(0, nl));\n      outputBuf = outputBuf.substr(nl + 1);\n    }\n    return buf.length;\n  },\n  write(fd, buf, offset, length, position, callback) {\n    if (offset !== 0 || length !== buf.length || position !== null) {\n      callback(enosys());\n      return;\n    }\n    const n = this.writeSync(fd, buf);\n    callback(null, n);\n  },\n  chmod(path, mode, callback) {\n    callback(enosys());\n  },\n  chown(path, uid, gid, callback) {\n    callback(enosys());\n  },\n  close(fd, callback) {\n    callback(enosys());\n  },\n  fchmod(fd, mode, callback) {\n    callback(enosys());\n  },\n  fchown(fd, uid, gid, callback) {\n    callback(enosys());\n  },\n  fstat(fd, callback) {\n    callback(enosys());\n  },\n  fsync(fd, callback) {\n    callback(null);\n  },\n  ftruncate(fd, length, callback) {\n    callback(enosys());\n  },\n  lchown(path, uid, gid, callback) {\n    callback(enosys());\n  },\n  link(path, link, callback) {\n    callback(enosys());\n  },\n  lstat(path, callback) {\n    callback(enosys());\n  },\n  mkdir(path, perm, callback) {\n    callback(enosys());\n  },\n  open(path, flags, mode, callback) {\n    callback(enosys());\n  },\n  read(fd, buffer, offset, length, position, callback) {\n    callback(enosys());\n  },\n  readdir(path, callback) {\n    callback(enosys());\n  },\n  readlink(path, callback) {\n    callback(enosys());\n  },\n  rename(from, to, callback) {\n    callback(enosys());\n  },\n  rmdir(path, callback) {\n    callback(enosys());\n  },\n  stat(path, callback) {\n    callback(enosys());\n  },\n  symlink(path, link, callback) {\n    callback(enosys());\n  },\n  truncate(path, length, callback) {\n    callback(enosys());\n  },\n  unlink(path, callback) {\n    callback(enosys());\n  },\n  utimes(path, atime, mtime, callback) {\n    callback(enosys());\n  },\n};\nconst process = {\n  getuid() {\n    return -1;\n  },\n  getgid() {\n    return -1;\n  },\n  geteuid() {\n    return -1;\n  },\n  getegid() {\n    return -1;\n  },\n  getgroups() {\n    throw enosys();\n  },\n  pid: -1,\n  ppid: -1,\n  umask() {\n    throw enosys();\n  },\n  cwd() {\n    throw enosys();\n  },\n  chdir() {\n    throw enosys();\n  },\n};\n\nObject.defineProperties(globalThis, {\n  fs: {\n    value: fs,\n    enumerable: true,\n  },\n  process: {\n    value: process,\n    enumerable: true,\n  },\n});\n\nconst encoder = new TextEncoder('utf-8');\nconst decoder = new TextDecoder('utf-8');\nconst logLine = [];\n\nexport default class Go {\n  public importObject;\n  constructor() {\n    this.argv = ['js'];\n    this.env = {};\n    this.exit = (code) => {\n      if (code !== 0) {\n        console.warn('exit code:', code);\n      }\n    };\n    this._exitPromise = new Promise((resolve) => {\n      this._resolveExitPromise = resolve;\n    });\n    this._pendingEvent = null;\n    this._scheduledTimeouts = new Map();\n    this._nextCallbackTimeoutID = 1;\n\n    const setInt64 = (addr, v) => {\n      this.mem.setUint32(addr + 0, v, true);\n      this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true);\n    };\n\n    const getInt64 = (addr) => {\n      const low = this.mem.getUint32(addr + 0, true);\n      const high = this.mem.getInt32(addr + 4, true);\n      return low + high * 4294967296;\n    };\n\n    const loadValue = (addr) => {\n      const f = this.mem.getFloat64(addr, true);\n      if (f === 0) {\n        return undefined;\n      }\n      if (!isNaN(f)) {\n        return f;\n      }\n\n      const id = this.mem.getUint32(addr, true);\n      return this._values[id];\n    };\n\n    const storeValue = (addr, v) => {\n      const nanHead = 0x7ff80000;\n\n      if (typeof v === 'number' && v !== 0) {\n        if (isNaN(v)) {\n          this.mem.setUint32(addr + 4, nanHead, true);\n          this.mem.setUint32(addr, 0, true);\n          return;\n        }\n        this.mem.setFloat64(addr, v, true);\n        return;\n      }\n\n      if (v === undefined) {\n        this.mem.setFloat64(addr, 0, true);\n        return;\n      }\n\n      let id = this._ids.get(v);\n      if (id === undefined) {\n        id = this._idPool.pop();\n        if (id === undefined) {\n          id = this._values.length;\n        }\n        this._values[id] = v;\n        this._goRefCounts[id] = 0;\n        this._ids.set(v, id);\n      }\n      this._goRefCounts[id]++;\n      let typeFlag = 0;\n      switch (typeof v) {\n        case 'object':\n          if (v !== null) {\n            typeFlag = 1;\n          }\n          break;\n        case 'string':\n          typeFlag = 2;\n          break;\n        case 'symbol':\n          typeFlag = 3;\n          break;\n        case 'function':\n          typeFlag = 4;\n          break;\n      }\n      this.mem.setUint32(addr + 4, nanHead | typeFlag, true);\n      this.mem.setUint32(addr, id, true);\n    };\n\n    const loadSlice = (addr) => {\n      const array = getInt64(addr + 0);\n      const len = getInt64(addr + 8);\n      return new Uint8Array(this._inst.exports.mem.buffer, array, len);\n    };\n\n    const loadSliceOfValues = (addr) => {\n      const array = getInt64(addr + 0);\n      const len = getInt64(addr + 8);\n      const a = new Array(len);\n      for (let i = 0; i < len; i++) {\n        a[i] = loadValue(array + i * 8);\n      }\n      return a;\n    };\n\n    const loadString = (addr) => {\n      const saddr = getInt64(addr + 0);\n      const len = getInt64(addr + 8);\n      return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));\n    };\n\n    const timeOrigin = Date.now() - performance.now();\n    this.importObject = {\n      gojs: {\n        // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)\n        // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported\n        // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).\n        // This changes the SP, thus we have to update the SP used by the imported function.\n\n        // func wasmExit(code int32)\n        'runtime.wasmExit': (sp) => {\n          sp >>>= 0;\n          const code = this.mem.getInt32(sp + 8, true);\n          this.exited = true;\n          delete this._inst;\n          delete this._values;\n          delete this._goRefCounts;\n          delete this._ids;\n          delete this._idPool;\n          this.exit(code);\n        },\n\n        // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)\n        'runtime.wasmWrite': (sp) => {\n          sp >>>= 0;\n          const fd = getInt64(sp + 8);\n          const p = getInt64(sp + 16);\n          const n = this.mem.getInt32(sp + 24, true);\n          fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));\n        },\n\n        // func resetMemoryDataView()\n        'runtime.resetMemoryDataView': (sp) => {\n          sp >>>= 0;\n          this.mem = new DataView(this._inst.exports.mem.buffer);\n        },\n\n        // func nanotime1() int64\n        'runtime.nanotime1': (sp) => {\n          sp >>>= 0;\n          setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);\n        },\n\n        // func walltime() (sec int64, nsec int32)\n        'runtime.walltime': (sp) => {\n          sp >>>= 0;\n          const msec = new Date().getTime();\n          setInt64(sp + 8, msec / 1000);\n          this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);\n        },\n\n        // func scheduleTimeoutEvent(delay int64) int32\n        'runtime.scheduleTimeoutEvent': (sp) => {\n          sp >>>= 0;\n          const id = this._nextCallbackTimeoutID;\n          this._nextCallbackTimeoutID++;\n          this._scheduledTimeouts.set(\n            id,\n            setTimeout(\n              () => {\n                this._resume();\n                while (this._scheduledTimeouts.has(id)) {\n                  // for some reason Go failed to register the timeout event, log and try again\n                  // (temporary workaround for https://github.com/golang/go/issues/28975)\n                  console.warn('scheduleTimeoutEvent: missed timeout event');\n                  this._resume();\n                }\n              },\n              getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early\n            ),\n          );\n          this.mem.setInt32(sp + 16, id, true);\n        },\n\n        // func clearTimeoutEvent(id int32)\n        'runtime.clearTimeoutEvent': (sp) => {\n          sp >>>= 0;\n          const id = this.mem.getInt32(sp + 8, true);\n          clearTimeout(this._scheduledTimeouts.get(id));\n          this._scheduledTimeouts.delete(id);\n        },\n\n        // func getRandomData(r []byte)\n        'runtime.getRandomData': (sp) => {\n          sp >>>= 0;\n          globalThis.crypto.getRandomValues(loadSlice(sp + 8));\n        },\n\n        // func finalizeRef(v ref)\n        'syscall/js.finalizeRef': (sp) => {\n          sp >>>= 0;\n          const id = this.mem.getUint32(sp + 8, true);\n          this._goRefCounts[id]--;\n          if (this._goRefCounts[id] === 0) {\n            const v = this._values[id];\n            this._values[id] = null;\n            this._ids.delete(v);\n            this._idPool.push(id);\n          }\n        },\n\n        // func stringVal(value string) ref\n        'syscall/js.stringVal': (sp) => {\n          sp >>>= 0;\n          storeValue(sp + 24, loadString(sp + 8));\n        },\n\n        // func valueGet(v ref, p string) ref\n        'syscall/js.valueGet': (sp) => {\n          sp >>>= 0;\n          const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16));\n          sp = this._inst.exports.getsp() >>> 0; // see comment above\n          storeValue(sp + 32, result);\n        },\n\n        // func valueSet(v ref, p string, x ref)\n        'syscall/js.valueSet': (sp) => {\n          sp >>>= 0;\n          Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));\n        },\n\n        // func valueDelete(v ref, p string)\n        'syscall/js.valueDelete': (sp) => {\n          sp >>>= 0;\n          Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));\n        },\n\n        // func valueIndex(v ref, i int) ref\n        'syscall/js.valueIndex': (sp) => {\n          sp >>>= 0;\n          storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));\n        },\n\n        // valueSetIndex(v ref, i int, x ref)\n        'syscall/js.valueSetIndex': (sp) => {\n          sp >>>= 0;\n          Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));\n        },\n\n        // func valueCall(v ref, m string, args []ref) (ref, bool)\n        'syscall/js.valueCall': (sp) => {\n          sp >>>= 0;\n          try {\n            const v = loadValue(sp + 8);\n            const m = Reflect.get(v, loadString(sp + 16));\n            const args = loadSliceOfValues(sp + 32);\n            const result = Reflect.apply(m, v, args);\n            sp = this._inst.exports.getsp() >>> 0; // see comment above\n            storeValue(sp + 56, result);\n            this.mem.setUint8(sp + 64, 1);\n          } catch (err) {\n            sp = this._inst.exports.getsp() >>> 0; // see comment above\n            storeValue(sp + 56, err);\n            this.mem.setUint8(sp + 64, 0);\n          }\n        },\n\n        // func valueInvoke(v ref, args []ref) (ref, bool)\n        'syscall/js.valueInvoke': (sp) => {\n          sp >>>= 0;\n          try {\n            const v = loadValue(sp + 8);\n            const args = loadSliceOfValues(sp + 16);\n            const result = Reflect.apply(v, undefined, args);\n            sp = this._inst.exports.getsp() >>> 0; // see comment above\n            storeValue(sp + 40, result);\n            this.mem.setUint8(sp + 48, 1);\n          } catch (err) {\n            sp = this._inst.exports.getsp() >>> 0; // see comment above\n            storeValue(sp + 40, err);\n            this.mem.setUint8(sp + 48, 0);\n          }\n        },\n\n        // func valueNew(v ref, args []ref) (ref, bool)\n        'syscall/js.valueNew': (sp) => {\n          sp >>>= 0;\n          try {\n            const v = loadValue(sp + 8);\n            const args = loadSliceOfValues(sp + 16);\n            const result = Reflect.construct(v, args);\n            sp = this._inst.exports.getsp() >>> 0; // see comment above\n            storeValue(sp + 40, result);\n            this.mem.setUint8(sp + 48, 1);\n          } catch (err) {\n            sp = this._inst.exports.getsp() >>> 0; // see comment above\n            storeValue(sp + 40, err);\n            this.mem.setUint8(sp + 48, 0);\n          }\n        },\n\n        // func valueLength(v ref) int\n        'syscall/js.valueLength': (sp) => {\n          sp >>>= 0;\n          setInt64(sp + 16, Number.parseInt(loadValue(sp + 8).length));\n        },\n\n        // valuePrepareString(v ref) (ref, int)\n        'syscall/js.valuePrepareString': (sp) => {\n          sp >>>= 0;\n          const str = encoder.encode(String(loadValue(sp + 8)));\n          storeValue(sp + 16, str);\n          setInt64(sp + 24, str.length);\n        },\n\n        // valueLoadString(v ref, b []byte)\n        'syscall/js.valueLoadString': (sp) => {\n          sp >>>= 0;\n          const str = loadValue(sp + 8);\n          loadSlice(sp + 16).set(str);\n        },\n\n        // func valueInstanceOf(v ref, t ref) bool\n        'syscall/js.valueInstanceOf': (sp) => {\n          sp >>>= 0;\n          this.mem.setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16) ? 1 : 0);\n        },\n\n        // func copyBytesToGo(dst []byte, src ref) (int, bool)\n        'syscall/js.copyBytesToGo': (sp) => {\n          sp >>>= 0;\n          const dst = loadSlice(sp + 8);\n          const src = loadValue(sp + 32);\n          if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {\n            this.mem.setUint8(sp + 48, 0);\n            return;\n          }\n          const toCopy = src.subarray(0, dst.length);\n          dst.set(toCopy);\n          setInt64(sp + 40, toCopy.length);\n          this.mem.setUint8(sp + 48, 1);\n        },\n\n        // func copyBytesToJS(dst ref, src []byte) (int, bool)\n        'syscall/js.copyBytesToJS': (sp) => {\n          sp >>>= 0;\n          const dst = loadValue(sp + 8);\n          const src = loadSlice(sp + 16);\n          if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {\n            this.mem.setUint8(sp + 48, 0);\n            return;\n          }\n          const toCopy = src.subarray(0, dst.length);\n          dst.set(toCopy);\n          setInt64(sp + 40, toCopy.length);\n          this.mem.setUint8(sp + 48, 1);\n        },\n\n        debug: (value) => {\n          console.log(value);\n        },\n      },\n    };\n  }\n\n  async run(instance) {\n    if (!(instance instanceof WebAssembly.Instance)) {\n      throw new Error('Go.run: WebAssembly.Instance expected');\n    }\n    this._inst = instance;\n    this.mem = new DataView(this._inst.exports.mem.buffer);\n    this._values = [\n      // JS values that Go currently has references to, indexed by reference id\n      Number.NaN,\n      0,\n      null,\n      true,\n      false,\n      globalThis,\n      this,\n    ];\n    this._goRefCounts = new Array(this._values.length).fill(Number.POSITIVE_INFINITY); // number of references that Go has to a JS value, indexed by reference id\n    this._ids = new Map([\n      // mapping from JS values to reference ids\n      [0, 1],\n      [null, 2],\n      [true, 3],\n      [false, 4],\n      [globalThis, 5],\n      [this, 6],\n    ]);\n    this._idPool = []; // unused ids that have been garbage collected\n    this.exited = false; // whether the Go program has exited\n\n    // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.\n    let offset = 4096;\n\n    const strPtr = (str) => {\n      const ptr = offset;\n      const bytes = encoder.encode(`${str}\\0`);\n      new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes);\n      offset += bytes.length;\n      if (offset % 8 !== 0) {\n        offset += 8 - (offset % 8);\n      }\n      return ptr;\n    };\n\n    const argc = this.argv.length;\n\n    const argvPtrs = [];\n    this.argv.forEach((arg) => {\n      argvPtrs.push(strPtr(arg));\n    });\n    argvPtrs.push(0);\n\n    const keys = Object.keys(this.env).sort();\n    keys.forEach((key) => {\n      argvPtrs.push(strPtr(`${key}=${this.env[key]}`));\n    });\n    argvPtrs.push(0);\n\n    const argv = offset;\n    argvPtrs.forEach((ptr) => {\n      this.mem.setUint32(offset, ptr, true);\n      this.mem.setUint32(offset + 4, 0, true);\n      offset += 8;\n    });\n\n    this._inst.exports.run(argc, argv);\n    if (this.exited) {\n      this._resolveExitPromise();\n    }\n    await this._exitPromise;\n  }\n\n  private _resume() {\n    if (this.exited) {\n      throw new Error('Go program has already exited');\n    }\n    this._inst.exports.resume();\n    if (this.exited) {\n      this._resolveExitPromise();\n    }\n  }\n\n  private _makeFuncWrapper(id) {\n    const go = this;\n    return function () {\n      const event = { id: id, this: this, args: arguments };\n      go._pendingEvent = event;\n      go._resume();\n      return event.result;\n    };\n  }\n}\n"
  },
  {
    "path": "packages/compiler/src/node/index.ts",
    "content": "export type {\n\tHoistedScript,\n\tParseOptions,\n\tParseResult,\n\tPreprocessorResult,\n\tTransformOptions,\n\tTransformResult,\n} from '../shared/types.js';\nimport { promises as fs } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport type * as types from '../shared/types.js';\nimport Go from './wasm_exec.js';\n\nexport const transform: typeof types.transform = async (input, options) => {\n\treturn getService().then((service) => service.transform(input, options));\n};\n\nexport const parse: typeof types.parse = async (input, options) => {\n\treturn getService().then((service) => service.parse(input, options));\n};\n\nexport const convertToTSX: typeof types.convertToTSX = async (input, options) => {\n\treturn getService().then((service) => service.convertToTSX(input, options));\n};\n\nexport const compile = async (template: string): Promise<string> => {\n\tconst { default: mod } = await import(\n\t\t`data:text/javascript;charset=utf-8;base64,${Buffer.from(template).toString('base64')}`\n\t);\n\treturn mod;\n};\n\ninterface Service {\n\ttransform: typeof types.transform;\n\tparse: typeof types.parse;\n\tconvertToTSX: typeof types.convertToTSX;\n}\n\nlet longLivedService: Promise<Service> | undefined;\n\nexport const teardown: typeof types.teardown = () => {\n\tlongLivedService = undefined;\n\t(globalThis as any)['@astrojs/compiler'] = undefined;\n};\n\nconst getService = (): Promise<Service> => {\n\tif (!longLivedService) {\n\t\tlongLivedService = startRunningService().catch((err) => {\n\t\t\t// Let the caller try again if this fails.\n\t\t\tlongLivedService = void 0;\n\t\t\t// But still, throw the error back up the caller.\n\t\t\tthrow err;\n\t\t});\n\t}\n\treturn longLivedService;\n};\n\nconst instantiateWASM = async (\n\twasmURL: string,\n\timportObject: Record<string, any>\n): Promise<WebAssembly.WebAssemblyInstantiatedSource> => {\n\tlet response = undefined;\n\n\tconst fetchAndInstantiateTask = async () => {\n\t\tconst wasmArrayBuffer = await fs.readFile(wasmURL).then((res) => res.buffer);\n\t\treturn WebAssembly.instantiate(new Uint8Array(wasmArrayBuffer), importObject);\n\t};\n\tresponse = await fetchAndInstantiateTask();\n\n\treturn response;\n};\n\nconst startRunningService = async (): Promise<Service> => {\n\tconst go = new Go();\n\tconst wasm = await instantiateWASM(\n\t\tfileURLToPath(new URL('../astro.wasm', import.meta.url)),\n\t\tgo.importObject\n\t);\n\tgo.run(wasm.instance);\n\tconst _service: any = (globalThis as any)['@astrojs/compiler'];\n\treturn {\n\t\ttransform: (input, options) =>\n\t\t\tnew Promise((resolve) => {\n\t\t\t\ttry {\n\t\t\t\t\tresolve(_service.transform(input, options || {}));\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// Recreate the service next time on panic\n\t\t\t\t\tlongLivedService = void 0;\n\t\t\t\t\tthrow err;\n\t\t\t\t}\n\t\t\t}),\n\t\tparse: (input, options) =>\n\t\t\tnew Promise((resolve) => resolve(_service.parse(input, options || {})))\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tlongLivedService = void 0;\n\t\t\t\t\tthrow error;\n\t\t\t\t})\n\t\t\t\t.then((result: any) => ({ ...result, ast: JSON.parse(result.ast) })),\n\t\tconvertToTSX: (input, options) => {\n\t\t\treturn new Promise((resolve) => resolve(_service.convertToTSX(input, options || {})))\n\t\t\t\t.catch((error) => {\n\t\t\t\t\tlongLivedService = void 0;\n\t\t\t\t\tthrow error;\n\t\t\t\t})\n\t\t\t\t.then((result: any) => {\n\t\t\t\t\treturn { ...result, map: JSON.parse(result.map) };\n\t\t\t\t});\n\t\t},\n\t};\n};\n"
  },
  {
    "path": "packages/compiler/src/node/sync.ts",
    "content": "import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport type * as types from '../shared/types.js';\nimport Go from './wasm_exec.js';\n\ntype UnwrappedPromise<T> = T extends (...params: any) => Promise<infer Return>\n\t? (...params: Parameters<T>) => Return\n\t: T;\n\ninterface Service {\n\ttransform: UnwrappedPromise<typeof types.transform>;\n\tparse: UnwrappedPromise<typeof types.parse>;\n\tconvertToTSX: UnwrappedPromise<typeof types.convertToTSX>;\n}\n\nfunction getService(): Service {\n\tif (!longLivedService) {\n\t\tlongLivedService = startRunningService();\n\t}\n\treturn longLivedService;\n}\n\nlet longLivedService: Service | undefined;\n\nexport const transform = ((input, options) =>\n\tgetService().transform(input, options)) satisfies Service['transform'];\n\nexport const parse = ((input, options) => {\n\treturn getService().parse(input, options);\n}) satisfies Service['parse'];\n\nexport const convertToTSX = ((input, options) => {\n\treturn getService().convertToTSX(input, options);\n}) satisfies Service['convertToTSX'];\n\nexport function startRunningService(): Service {\n\tconst go = new Go();\n\tconst wasm = instantiateWASM(\n\t\tfileURLToPath(new URL('../astro.wasm', import.meta.url)),\n\t\tgo.importObject\n\t);\n\tgo.run(wasm);\n\tconst _service: any = (globalThis as any)['@astrojs/compiler'];\n\treturn {\n\t\ttransform: (input, options) => {\n\t\t\ttry {\n\t\t\t\treturn _service.transform(input, options || {});\n\t\t\t} catch (err) {\n\t\t\t\t// Recreate the service next time on panic\n\t\t\t\tlongLivedService = void 0;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t},\n\t\tparse: (input, options) => {\n\t\t\ttry {\n\t\t\t\tconst result = _service.parse(input, options || {});\n\t\t\t\treturn { ...result, ast: JSON.parse(result.ast) };\n\t\t\t} catch (err) {\n\t\t\t\tlongLivedService = void 0;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t},\n\t\tconvertToTSX: (input, options) => {\n\t\t\ttry {\n\t\t\t\tconst result = _service.convertToTSX(input, options || {});\n\t\t\t\treturn { ...result, map: JSON.parse(result.map) };\n\t\t\t} catch (err) {\n\t\t\t\tlongLivedService = void 0;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t},\n\t};\n}\n\nfunction instantiateWASM(wasmURL: string, importObject: Record<string, any>): WebAssembly.Instance {\n\tconst wasmArrayBuffer = readFileSync(wasmURL);\n\treturn new WebAssembly.Instance(new WebAssembly.Module(wasmArrayBuffer), importObject);\n}\n"
  },
  {
    "path": "packages/compiler/src/node/utils.ts",
    "content": "import type {\n\tCommentNode,\n\tComponentNode,\n\tCustomElementNode,\n\tDoctypeNode,\n\tElementNode,\n\tExpressionNode,\n\tFragmentNode,\n\tFrontmatterNode,\n\tLiteralNode,\n\tNode,\n\tParentNode,\n\tRootNode,\n\tTagLikeNode,\n\tTextNode,\n} from '../shared/ast.js';\n\nexport type Visitor = (node: Node, parent?: ParentNode, index?: number) => void | Promise<void>;\n\nfunction guard<Type extends Node>(type: string) {\n\treturn (node: Node): node is Type => node.type === type;\n}\n\nexport const is = {\n\tparent(node: Node): node is ParentNode {\n\t\treturn Array.isArray((node as any).children);\n\t},\n\tliteral(node: Node): node is LiteralNode {\n\t\treturn typeof (node as any).value === 'string';\n\t},\n\ttag(node: Node): node is TagLikeNode {\n\t\treturn (\n\t\t\tnode.type === 'element' ||\n\t\t\tnode.type === 'custom-element' ||\n\t\t\tnode.type === 'component' ||\n\t\t\tnode.type === 'fragment'\n\t\t);\n\t},\n\twhitespace(node: Node): node is TextNode {\n\t\treturn node.type === 'text' && node.value.trim().length === 0;\n\t},\n\troot: guard<RootNode>('root'),\n\telement: guard<ElementNode>('element'),\n\tcustomElement: guard<CustomElementNode>('custom-element'),\n\tcomponent: guard<ComponentNode>('component'),\n\tfragment: guard<FragmentNode>('fragment'),\n\texpression: guard<ExpressionNode>('expression'),\n\ttext: guard<TextNode>('text'),\n\tdoctype: guard<DoctypeNode>('doctype'),\n\tcomment: guard<CommentNode>('comment'),\n\tfrontmatter: guard<FrontmatterNode>('frontmatter'),\n};\n\nclass Walker {\n\tconstructor(private callback: Visitor) {}\n\tasync visit(node: Node, parent?: ParentNode, index?: number): Promise<void> {\n\t\tawait this.callback(node, parent, index);\n\t\tif (is.parent(node)) {\n\t\t\tconst promises = [];\n\t\t\tfor (let i = 0; i < node.children.length; i++) {\n\t\t\t\tconst child = node.children[i];\n\t\t\t\tpromises.push(this.callback(child, node as ParentNode, i));\n\t\t\t}\n\t\t\tawait Promise.all(promises);\n\t\t}\n\t}\n}\n\nexport function walk(node: ParentNode, callback: Visitor): void {\n\tconst walker = new Walker(callback);\n\twalker.visit(node);\n}\n\nexport function walkAsync(node: ParentNode, callback: Visitor): Promise<void> {\n\tconst walker = new Walker(callback);\n\treturn walker.visit(node);\n}\n\nfunction serializeAttributes(node: TagLikeNode): string {\n\tlet output = '';\n\tfor (const attr of node.attributes) {\n\t\toutput += ' ';\n\t\tswitch (attr.kind) {\n\t\t\tcase 'empty': {\n\t\t\t\toutput += `${attr.name}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'expression': {\n\t\t\t\toutput += `${attr.name}={${attr.value}}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'quoted': {\n\t\t\t\toutput += `${attr.name}=${attr.raw}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'template-literal': {\n\t\t\t\toutput += `${attr.name}=\\`${attr.value}\\``;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'shorthand': {\n\t\t\t\toutput += `{${attr.name}}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'spread': {\n\t\t\t\toutput += `{...${attr.name}}`;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn output;\n}\n\nexport interface SerializeOptions {\n\tselfClose: boolean;\n}\n/** @deprecated Please use `SerializeOptions`  */\nexport type SerializeOtions = SerializeOptions;\n\nexport function serialize(root: Node, opts: SerializeOptions = { selfClose: true }): string {\n\tlet output = '';\n\tfunction visitor(node: Node) {\n\t\tif (is.root(node)) {\n\t\t\tfor (const child of node.children) {\n\t\t\t\tvisitor(child);\n\t\t\t}\n\t\t} else if (is.frontmatter(node)) {\n\t\t\toutput += `---${node.value}---\\n\\n`;\n\t\t} else if (is.comment(node)) {\n\t\t\toutput += `<!--${node.value}-->`;\n\t\t} else if (is.expression(node)) {\n\t\t\toutput += '{';\n\t\t\tfor (const child of node.children) {\n\t\t\t\tvisitor(child);\n\t\t\t}\n\t\t\toutput += '}';\n\t\t} else if (is.literal(node)) {\n\t\t\toutput += node.value;\n\t\t} else if (is.tag(node)) {\n\t\t\toutput += `<${node.name}`;\n\t\t\toutput += serializeAttributes(node);\n\t\t\tif (node.children.length === 0 && opts.selfClose) {\n\t\t\t\toutput += ' />';\n\t\t\t} else {\n\t\t\t\toutput += '>';\n\t\t\t\tfor (const child of node.children) {\n\t\t\t\t\tvisitor(child);\n\t\t\t\t}\n\t\t\t\toutput += `</${node.name}>`;\n\t\t\t}\n\t\t}\n\t}\n\tvisitor(root);\n\treturn output;\n}\n"
  },
  {
    "path": "packages/compiler/src/node/wasm_exec.ts",
    "content": "// @ts-nocheck\n// Copyright 2018 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n//\n// This file has been modified for use by Astro.\n\nimport crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport { TextDecoder, TextEncoder } from 'node:util';\n\nif (!globalThis.fs) {\n\tObject.defineProperty(globalThis, 'fs', {\n\t\tvalue: fs,\n\t});\n}\n\nif (!globalThis.process) {\n\tObject.defineProperties(globalThis, 'process', {\n\t\tvalue: process,\n\t});\n}\n\nif (!globalThis.crypto) {\n\tObject.defineProperty(globalThis, 'crypto', {\n\t\tvalue: crypto.webcrypto\n\t\t\t? crypto.webcrypto\n\t\t\t: {\n\t\t\t\t\tgetRandomValues(b) {\n\t\t\t\t\t\treturn crypto.randomFillSync(b);\n\t\t\t\t\t},\n\t\t\t\t},\n\t});\n}\n\nif (!globalThis.performance) {\n\tObject.defineProperty(globalThis, 'performance', {\n\t\tvalue: {\n\t\t\tnow() {\n\t\t\t\tconst [sec, nsec] = process.hrtime();\n\t\t\t\treturn sec * 1000 + nsec / 1000000;\n\t\t\t},\n\t\t},\n\t});\n}\n// End of polyfills for common API.\n\nconst encoder = new TextEncoder('utf-8');\nconst decoder = new TextDecoder('utf-8');\nvar logLine = [];\n\nexport default class Go {\n\tpublic importObject;\n\tconstructor() {\n\t\tthis.argv = ['js'];\n\t\tthis.env = {};\n\t\tthis.exit = (code) => {\n\t\t\tif (code !== 0) {\n\t\t\t\tconsole.warn('exit code:', code);\n\t\t\t}\n\t\t};\n\t\tthis._exitPromise = new Promise((resolve) => {\n\t\t\tthis._resolveExitPromise = resolve;\n\t\t});\n\t\tthis._pendingEvent = null;\n\t\tthis._scheduledTimeouts = new Map();\n\t\tthis._nextCallbackTimeoutID = 1;\n\n\t\tconst setInt64 = (addr, v) => {\n\t\t\tthis.mem.setUint32(addr + 0, v, true);\n\t\t\tthis.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true);\n\t\t};\n\n\t\tconst getInt64 = (addr) => {\n\t\t\tconst low = this.mem.getUint32(addr + 0, true);\n\t\t\tconst high = this.mem.getInt32(addr + 4, true);\n\t\t\treturn low + high * 4294967296;\n\t\t};\n\n\t\tconst loadValue = (addr) => {\n\t\t\tconst f = this.mem.getFloat64(addr, true);\n\t\t\tif (f === 0) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tif (!isNaN(f)) {\n\t\t\t\treturn f;\n\t\t\t}\n\n\t\t\tconst id = this.mem.getUint32(addr, true);\n\t\t\treturn this._values[id];\n\t\t};\n\n\t\tconst storeValue = (addr, v) => {\n\t\t\tconst nanHead = 0x7ff80000;\n\n\t\t\tif (typeof v === 'number' && v !== 0) {\n\t\t\t\tif (isNaN(v)) {\n\t\t\t\t\tthis.mem.setUint32(addr + 4, nanHead, true);\n\t\t\t\t\tthis.mem.setUint32(addr, 0, true);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis.mem.setFloat64(addr, v, true);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (v === undefined) {\n\t\t\t\tthis.mem.setFloat64(addr, 0, true);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet id = this._ids.get(v);\n\t\t\tif (id === undefined) {\n\t\t\t\tid = this._idPool.pop();\n\t\t\t\tif (id === undefined) {\n\t\t\t\t\tid = this._values.length;\n\t\t\t\t}\n\t\t\t\tthis._values[id] = v;\n\t\t\t\tthis._goRefCounts[id] = 0;\n\t\t\t\tthis._ids.set(v, id);\n\t\t\t}\n\t\t\tthis._goRefCounts[id]++;\n\t\t\tlet typeFlag = 0;\n\t\t\tswitch (typeof v) {\n\t\t\t\tcase 'object':\n\t\t\t\t\tif (v !== null) {\n\t\t\t\t\t\ttypeFlag = 1;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'string':\n\t\t\t\t\ttypeFlag = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'symbol':\n\t\t\t\t\ttypeFlag = 3;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'function':\n\t\t\t\t\ttypeFlag = 4;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tthis.mem.setUint32(addr + 4, nanHead | typeFlag, true);\n\t\t\tthis.mem.setUint32(addr, id, true);\n\t\t};\n\n\t\tconst loadSlice = (addr) => {\n\t\t\tconst array = getInt64(addr + 0);\n\t\t\tconst len = getInt64(addr + 8);\n\t\t\treturn new Uint8Array(this._inst.exports.mem.buffer, array, len);\n\t\t};\n\n\t\tconst loadSliceOfValues = (addr) => {\n\t\t\tconst array = getInt64(addr + 0);\n\t\t\tconst len = getInt64(addr + 8);\n\t\t\tconst a = new Array(len);\n\t\t\tfor (let i = 0; i < len; i++) {\n\t\t\t\ta[i] = loadValue(array + i * 8);\n\t\t\t}\n\t\t\treturn a;\n\t\t};\n\n\t\tconst loadString = (addr) => {\n\t\t\tconst saddr = getInt64(addr + 0);\n\t\t\tconst len = getInt64(addr + 8);\n\t\t\treturn decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));\n\t\t};\n\n\t\tconst timeOrigin = Date.now() - performance.now();\n\t\tthis.importObject = {\n\t\t\tgojs: {\n\t\t\t\t// Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters)\n\t\t\t\t// may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported\n\t\t\t\t// function. A goroutine can switch to a new stack if the current stack is too small (see morestack function).\n\t\t\t\t// This changes the SP, thus we have to update the SP used by the imported function.\n\n\t\t\t\t// func wasmExit(code int32)\n\t\t\t\t'runtime.wasmExit': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst code = this.mem.getInt32(sp + 8, true);\n\t\t\t\t\tthis.exited = true;\n\t\t\t\t\tdelete this._inst;\n\t\t\t\t\tdelete this._values;\n\t\t\t\t\tdelete this._goRefCounts;\n\t\t\t\t\tdelete this._ids;\n\t\t\t\t\tdelete this._idPool;\n\t\t\t\t\tthis.exit(code);\n\t\t\t\t},\n\n\t\t\t\t// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)\n\t\t\t\t'runtime.wasmWrite': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst fd = getInt64(sp + 8);\n\t\t\t\t\tconst p = getInt64(sp + 16);\n\t\t\t\t\tconst n = this.mem.getInt32(sp + 24, true);\n\t\t\t\t\tfs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));\n\t\t\t\t},\n\n\t\t\t\t// func resetMemoryDataView()\n\t\t\t\t'runtime.resetMemoryDataView': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tthis.mem = new DataView(this._inst.exports.mem.buffer);\n\t\t\t\t},\n\n\t\t\t\t// func nanotime1() int64\n\t\t\t\t'runtime.nanotime1': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tsetInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);\n\t\t\t\t},\n\n\t\t\t\t// func walltime() (sec int64, nsec int32)\n\t\t\t\t'runtime.walltime': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst msec = new Date().getTime();\n\t\t\t\t\tsetInt64(sp + 8, msec / 1000);\n\t\t\t\t\tthis.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true);\n\t\t\t\t},\n\n\t\t\t\t// func scheduleTimeoutEvent(delay int64) int32\n\t\t\t\t'runtime.scheduleTimeoutEvent': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst id = this._nextCallbackTimeoutID;\n\t\t\t\t\tthis._nextCallbackTimeoutID++;\n\t\t\t\t\tthis._scheduledTimeouts.set(\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tsetTimeout(\n\t\t\t\t\t\t\t() => {\n\t\t\t\t\t\t\t\tthis._resume();\n\t\t\t\t\t\t\t\twhile (this._scheduledTimeouts.has(id)) {\n\t\t\t\t\t\t\t\t\t// for some reason Go failed to register the timeout event, log and try again\n\t\t\t\t\t\t\t\t\t// (temporary workaround for https://github.com/golang/go/issues/28975)\n\t\t\t\t\t\t\t\t\tconsole.warn('scheduleTimeoutEvent: missed timeout event');\n\t\t\t\t\t\t\t\t\tthis._resume();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tgetInt64(sp + 8) + 1 // setTimeout has been seen to fire up to 1 millisecond early\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\tthis.mem.setInt32(sp + 16, id, true);\n\t\t\t\t},\n\n\t\t\t\t// func clearTimeoutEvent(id int32)\n\t\t\t\t'runtime.clearTimeoutEvent': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst id = this.mem.getInt32(sp + 8, true);\n\t\t\t\t\tclearTimeout(this._scheduledTimeouts.get(id));\n\t\t\t\t\tthis._scheduledTimeouts.delete(id);\n\t\t\t\t},\n\n\t\t\t\t// func getRandomData(r []byte)\n\t\t\t\t'runtime.getRandomData': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tglobalThis.crypto.getRandomValues(loadSlice(sp + 8));\n\t\t\t\t},\n\n\t\t\t\t// func finalizeRef(v ref)\n\t\t\t\t'syscall/js.finalizeRef': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst id = this.mem.getUint32(sp + 8, true);\n\t\t\t\t\tthis._goRefCounts[id]--;\n\t\t\t\t\tif (this._goRefCounts[id] === 0) {\n\t\t\t\t\t\tconst v = this._values[id];\n\t\t\t\t\t\tthis._values[id] = null;\n\t\t\t\t\t\tthis._ids.delete(v);\n\t\t\t\t\t\tthis._idPool.push(id);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// func stringVal(value string) ref\n\t\t\t\t'syscall/js.stringVal': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tstoreValue(sp + 24, loadString(sp + 8));\n\t\t\t\t},\n\n\t\t\t\t// func valueGet(v ref, p string) ref\n\t\t\t\t'syscall/js.valueGet': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst result = Reflect.get(loadValue(sp + 8), loadString(sp + 16));\n\t\t\t\t\tsp = this._inst.exports.getsp() >>> 0; // see comment above\n\t\t\t\t\tstoreValue(sp + 32, result);\n\t\t\t\t},\n\n\t\t\t\t// func valueSet(v ref, p string, x ref)\n\t\t\t\t'syscall/js.valueSet': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tReflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));\n\t\t\t\t},\n\n\t\t\t\t// func valueDelete(v ref, p string)\n\t\t\t\t'syscall/js.valueDelete': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tReflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16));\n\t\t\t\t},\n\n\t\t\t\t// func valueIndex(v ref, i int) ref\n\t\t\t\t'syscall/js.valueIndex': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tstoreValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));\n\t\t\t\t},\n\n\t\t\t\t// valueSetIndex(v ref, i int, x ref)\n\t\t\t\t'syscall/js.valueSetIndex': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tReflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));\n\t\t\t\t},\n\n\t\t\t\t// func valueCall(v ref, m string, args []ref) (ref, bool)\n\t\t\t\t'syscall/js.valueCall': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst v = loadValue(sp + 8);\n\t\t\t\t\t\tconst m = Reflect.get(v, loadString(sp + 16));\n\t\t\t\t\t\tconst args = loadSliceOfValues(sp + 32);\n\t\t\t\t\t\tconst result = Reflect.apply(m, v, args);\n\t\t\t\t\t\tsp = this._inst.exports.getsp() >>> 0; // see comment above\n\t\t\t\t\t\tstoreValue(sp + 56, result);\n\t\t\t\t\t\tthis.mem.setUint8(sp + 64, 1);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsp = this._inst.exports.getsp() >>> 0; // see comment above\n\t\t\t\t\t\tstoreValue(sp + 56, err);\n\t\t\t\t\t\tthis.mem.setUint8(sp + 64, 0);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// func valueInvoke(v ref, args []ref) (ref, bool)\n\t\t\t\t'syscall/js.valueInvoke': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst v = loadValue(sp + 8);\n\t\t\t\t\t\tconst args = loadSliceOfValues(sp + 16);\n\t\t\t\t\t\tconst result = Reflect.apply(v, undefined, args);\n\t\t\t\t\t\tsp = this._inst.exports.getsp() >>> 0; // see comment above\n\t\t\t\t\t\tstoreValue(sp + 40, result);\n\t\t\t\t\t\tthis.mem.setUint8(sp + 48, 1);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsp = this._inst.exports.getsp() >>> 0; // see comment above\n\t\t\t\t\t\tstoreValue(sp + 40, err);\n\t\t\t\t\t\tthis.mem.setUint8(sp + 48, 0);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// func valueNew(v ref, args []ref) (ref, bool)\n\t\t\t\t'syscall/js.valueNew': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst v = loadValue(sp + 8);\n\t\t\t\t\t\tconst args = loadSliceOfValues(sp + 16);\n\t\t\t\t\t\tconst result = Reflect.construct(v, args);\n\t\t\t\t\t\tsp = this._inst.exports.getsp() >>> 0; // see comment above\n\t\t\t\t\t\tstoreValue(sp + 40, result);\n\t\t\t\t\t\tthis.mem.setUint8(sp + 48, 1);\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tsp = this._inst.exports.getsp() >>> 0; // see comment above\n\t\t\t\t\t\tstoreValue(sp + 40, err);\n\t\t\t\t\t\tthis.mem.setUint8(sp + 48, 0);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\t// func valueLength(v ref) int\n\t\t\t\t'syscall/js.valueLength': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tsetInt64(sp + 16, Number.parseInt(loadValue(sp + 8).length));\n\t\t\t\t},\n\n\t\t\t\t// valuePrepareString(v ref) (ref, int)\n\t\t\t\t'syscall/js.valuePrepareString': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst str = encoder.encode(String(loadValue(sp + 8)));\n\t\t\t\t\tstoreValue(sp + 16, str);\n\t\t\t\t\tsetInt64(sp + 24, str.length);\n\t\t\t\t},\n\n\t\t\t\t// valueLoadString(v ref, b []byte)\n\t\t\t\t'syscall/js.valueLoadString': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst str = loadValue(sp + 8);\n\t\t\t\t\tloadSlice(sp + 16).set(str);\n\t\t\t\t},\n\n\t\t\t\t// func valueInstanceOf(v ref, t ref) bool\n\t\t\t\t'syscall/js.valueInstanceOf': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tthis.mem.setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16) ? 1 : 0);\n\t\t\t\t},\n\n\t\t\t\t// func copyBytesToGo(dst []byte, src ref) (int, bool)\n\t\t\t\t'syscall/js.copyBytesToGo': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst dst = loadSlice(sp + 8);\n\t\t\t\t\tconst src = loadValue(sp + 32);\n\t\t\t\t\tif (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {\n\t\t\t\t\t\tthis.mem.setUint8(sp + 48, 0);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst toCopy = src.subarray(0, dst.length);\n\t\t\t\t\tdst.set(toCopy);\n\t\t\t\t\tsetInt64(sp + 40, toCopy.length);\n\t\t\t\t\tthis.mem.setUint8(sp + 48, 1);\n\t\t\t\t},\n\n\t\t\t\t// func copyBytesToJS(dst ref, src []byte) (int, bool)\n\t\t\t\t'syscall/js.copyBytesToJS': (sp) => {\n\t\t\t\t\tsp >>>= 0;\n\t\t\t\t\tconst dst = loadValue(sp + 8);\n\t\t\t\t\tconst src = loadSlice(sp + 16);\n\t\t\t\t\tif (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {\n\t\t\t\t\t\tthis.mem.setUint8(sp + 48, 0);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst toCopy = src.subarray(0, dst.length);\n\t\t\t\t\tdst.set(toCopy);\n\t\t\t\t\tsetInt64(sp + 40, toCopy.length);\n\t\t\t\t\tthis.mem.setUint8(sp + 48, 1);\n\t\t\t\t},\n\n\t\t\t\tdebug: (value) => {\n\t\t\t\t\tconsole.log(value);\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync run(instance) {\n\t\tif (!(instance instanceof WebAssembly.Instance)) {\n\t\t\tthrow new Error('Go.run: WebAssembly.Instance expected');\n\t\t}\n\t\tthis._inst = instance;\n\t\tthis.mem = new DataView(this._inst.exports.mem.buffer);\n\t\tthis._values = [\n\t\t\t// JS values that Go currently has references to, indexed by reference id\n\t\t\tNumber.NaN,\n\t\t\t0,\n\t\t\tnull,\n\t\t\ttrue,\n\t\t\tfalse,\n\t\t\tglobalThis,\n\t\t\tthis,\n\t\t];\n\t\tthis._goRefCounts = new Array(this._values.length).fill(Number.POSITIVE_INFINITY); // number of references that Go has to a JS value, indexed by reference id\n\t\tthis._ids = new Map([\n\t\t\t// mapping from JS values to reference ids\n\t\t\t[0, 1],\n\t\t\t[null, 2],\n\t\t\t[true, 3],\n\t\t\t[false, 4],\n\t\t\t[globalThis, 5],\n\t\t\t[this, 6],\n\t\t]);\n\t\tthis._idPool = []; // unused ids that have been garbage collected\n\t\tthis.exited = false; // whether the Go program has exited\n\n\t\t// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.\n\t\tlet offset = 4096;\n\n\t\tconst strPtr = (str) => {\n\t\t\tconst ptr = offset;\n\t\t\tconst bytes = encoder.encode(`${str}\\0`);\n\t\t\tnew Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes);\n\t\t\toffset += bytes.length;\n\t\t\tif (offset % 8 !== 0) {\n\t\t\t\toffset += 8 - (offset % 8);\n\t\t\t}\n\t\t\treturn ptr;\n\t\t};\n\n\t\tconst argc = this.argv.length;\n\n\t\tconst argvPtrs = [];\n\t\tthis.argv.forEach((arg) => {\n\t\t\targvPtrs.push(strPtr(arg));\n\t\t});\n\t\targvPtrs.push(0);\n\n\t\tconst keys = Object.keys(this.env).sort();\n\t\tkeys.forEach((key) => {\n\t\t\targvPtrs.push(strPtr(`${key}=${this.env[key]}`));\n\t\t});\n\t\targvPtrs.push(0);\n\n\t\tconst argv = offset;\n\t\targvPtrs.forEach((ptr) => {\n\t\t\tthis.mem.setUint32(offset, ptr, true);\n\t\t\tthis.mem.setUint32(offset + 4, 0, true);\n\t\t\toffset += 8;\n\t\t});\n\n\t\tthis._inst.exports.run(argc, argv);\n\t\tif (this.exited) {\n\t\t\tthis._resolveExitPromise();\n\t\t}\n\t\tawait this._exitPromise;\n\t}\n\n\tprivate _resume() {\n\t\tif (this.exited) {\n\t\t\tthrow new Error('Go program has already exited');\n\t\t}\n\t\tthis._inst.exports.resume();\n\t\tif (this.exited) {\n\t\t\tthis._resolveExitPromise();\n\t\t}\n\t}\n\n\tprivate _makeFuncWrapper(id) {\n\t\tconst go = this;\n\t\treturn function () {\n\t\t\tconst event = { id: id, this: this, args: arguments };\n\t\t\tgo._pendingEvent = event;\n\t\t\tgo._resume();\n\t\t\treturn event.result;\n\t\t};\n\t}\n}\n"
  },
  {
    "path": "packages/compiler/src/shared/ast.ts",
    "content": "export type ParentNode =\n\t| RootNode\n\t| ElementNode\n\t| ComponentNode\n\t| CustomElementNode\n\t| FragmentNode\n\t| ExpressionNode;\nexport type LiteralNode = TextNode | DoctypeNode | CommentNode | FrontmatterNode;\n\nexport type Node =\n\t| RootNode\n\t| ElementNode\n\t| ComponentNode\n\t| CustomElementNode\n\t| FragmentNode\n\t| ExpressionNode\n\t| TextNode\n\t| FrontmatterNode\n\t| DoctypeNode\n\t| CommentNode;\n\nexport interface Position {\n\tstart: Point;\n\tend?: Point;\n}\nexport interface Point {\n\t/** 1-based line number */\n\tline: number;\n\t/** 1-based column number, per-line */\n\tcolumn: number;\n\t/** 0-based byte offset */\n\toffset: number;\n}\nexport interface BaseNode {\n\ttype: string;\n\tposition?: Position;\n}\n\nexport interface ParentLikeNode extends BaseNode {\n\ttype: 'element' | 'component' | 'custom-element' | 'fragment' | 'expression' | 'root';\n\tchildren: Node[];\n}\n\nexport interface ValueNode extends BaseNode {\n\tvalue: string;\n}\n\nexport interface RootNode extends ParentLikeNode {\n\ttype: 'root';\n}\n\nexport interface AttributeNode extends BaseNode {\n\ttype: 'attribute';\n\tkind: 'quoted' | 'empty' | 'expression' | 'spread' | 'shorthand' | 'template-literal';\n\tname: string;\n\tvalue: string;\n\traw?: string;\n}\n\nexport interface TextNode extends ValueNode {\n\ttype: 'text';\n}\n\nexport interface ElementNode extends ParentLikeNode {\n\ttype: 'element';\n\tname: string;\n\tattributes: AttributeNode[];\n}\n\nexport interface FragmentNode extends ParentLikeNode {\n\ttype: 'fragment';\n\tname: string;\n\tattributes: AttributeNode[];\n}\n\nexport interface ComponentNode extends ParentLikeNode {\n\ttype: 'component';\n\tname: string;\n\tattributes: AttributeNode[];\n}\n\nexport interface CustomElementNode extends ParentLikeNode {\n\ttype: 'custom-element';\n\tname: string;\n\tattributes: AttributeNode[];\n}\n\nexport type TagLikeNode = ElementNode | FragmentNode | ComponentNode | CustomElementNode;\n\nexport interface DoctypeNode extends ValueNode {\n\ttype: 'doctype';\n}\n\nexport interface CommentNode extends ValueNode {\n\ttype: 'comment';\n}\n\nexport interface FrontmatterNode extends ValueNode {\n\ttype: 'frontmatter';\n}\n\nexport interface ExpressionNode extends ParentLikeNode {\n\ttype: 'expression';\n}\n"
  },
  {
    "path": "packages/compiler/src/shared/diagnostics.ts",
    "content": "export enum DiagnosticCode {\n\tERROR = 1000,\n\tERROR_UNTERMINATED_JS_COMMENT = 1001,\n\tERROR_FRAGMENT_SHORTHAND_ATTRS = 1002,\n\tERROR_UNMATCHED_IMPORT = 1003,\n\tERROR_UNSUPPORTED_SLOT_ATTRIBUTE = 1004,\n\tWARNING = 2000,\n\tWARNING_UNTERMINATED_HTML_COMMENT = 2001,\n\tWARNING_UNCLOSED_HTML_TAG = 2002,\n\tWARNING_DEPRECATED_DIRECTIVE = 2003,\n\tWARNING_IGNORED_DIRECTIVE = 2004,\n\tWARNING_UNSUPPORTED_EXPRESSION = 2005,\n\tWARNING_SET_WITH_CHILDREN = 2006,\n\tINFO = 3000,\n\tHINT = 4000,\n}\n"
  },
  {
    "path": "packages/compiler/src/shared/types.ts",
    "content": "import type { RootNode } from './ast.js';\nimport type { DiagnosticCode } from './diagnostics.js';\nexport type * from './ast.js';\n\nexport interface PreprocessorResult {\n\tcode: string;\n\tmap?: string;\n}\n\nexport interface PreprocessorError {\n\terror: string;\n}\n\nexport interface ParseOptions {\n\tposition?: boolean;\n}\n\nexport enum DiagnosticSeverity {\n\tError = 1,\n\tWarning = 2,\n\tInformation = 3,\n\tHint = 4,\n}\n\nexport interface DiagnosticMessage {\n\tseverity: DiagnosticSeverity;\n\tcode: DiagnosticCode;\n\tlocation: DiagnosticLocation;\n\thint?: string;\n\ttext: string;\n}\n\nexport interface DiagnosticLocation {\n\tfile: string;\n\t// 1-based\n\tline: number;\n\t// 1-based\n\tcolumn: number;\n\tlength: number;\n}\n\nexport interface TransformOptions {\n\tinternalURL?: string;\n\tfilename?: string;\n\tnormalizedFilename?: string;\n\tsourcemap?: boolean | 'inline' | 'external' | 'both';\n\tastroGlobalArgs?: string;\n\tcompact?: boolean;\n\tresultScopedSlot?: boolean;\n\tscopedStyleStrategy?: 'where' | 'class' | 'attribute';\n\t/**\n\t * @deprecated \"as\" has been removed and no longer has any effect!\n\t */\n\tas?: 'document' | 'fragment';\n\ttransitionsAnimationURL?: string;\n\tresolvePath?: (specifier: string) => Promise<string> | string;\n\tpreprocessStyle?: (\n\t\tcontent: string,\n\t\tattrs: Record<string, string>\n\t) => null | Promise<PreprocessorResult | PreprocessorError>;\n\tannotateSourceFile?: boolean;\n}\n\nexport type ConvertToTSXOptions = Pick<\n\tTransformOptions,\n\t'filename' | 'normalizedFilename' | 'sourcemap'\n> & {\n\t/** If set to true, script tags content will be included in the generated TSX\n\t * Scripts will be wrapped in an arrow function to be compatible with JSX's spec\n\t */\n\tincludeScripts?: boolean;\n\t/** If set to true, style tags content will be included in the generated TSX\n\t * Styles will be wrapped in a template literal to be compatible with JSX's spec\n\t */\n\tincludeStyles?: boolean;\n};\n\nexport type HoistedScript = { type: string } & (\n\t| {\n\t\t\ttype: 'external';\n\t\t\tsrc: string;\n\t  }\n\t| {\n\t\t\ttype: 'inline';\n\t\t\tcode: string;\n\t\t\tmap: string;\n\t  }\n);\n\nexport interface HydratedComponent {\n\texportName: string;\n\tlocalName: string;\n\tspecifier: string;\n\tresolvedPath: string;\n}\n\nexport interface TransformResult {\n\tcode: string;\n\tmap: string;\n\tscope: string;\n\tstyleError: string[];\n\tdiagnostics: DiagnosticMessage[];\n\tcss: string[];\n\tscripts: HoistedScript[];\n\thydratedComponents: HydratedComponent[];\n\tclientOnlyComponents: HydratedComponent[];\n\tserverComponents: HydratedComponent[];\n\tcontainsHead: boolean;\n\tpropagation: boolean;\n}\n\nexport interface SourceMap {\n\tfile: string;\n\tmappings: string;\n\tnames: string[];\n\tsources: string[];\n\tsourcesContent: string[];\n\tversion: number;\n}\n\n/**\n * Represents a location in a TSX file.\n * Both the `start` and `end` properties are 0-based, and are based off utf-16 code units. (i.e. JavaScript's `String.prototype.length`)\n */\nexport interface TSXLocation {\n\tstart: number;\n\tend: number;\n}\n\nexport interface TSXExtractedTag {\n\tposition: TSXLocation;\n\tcontent: string;\n}\n\nexport interface TSXExtractedScript extends TSXExtractedTag {\n\ttype: 'processed-module' | 'module' | 'inline' | 'event-attribute' | 'json' | 'raw' | 'unknown';\n}\n\nexport interface TSXExtractedStyle extends TSXExtractedTag {\n\ttype: 'tag' | 'style-attribute';\n\tlang:\n\t\t| 'css'\n\t\t| 'scss'\n\t\t| 'sass'\n\t\t| 'less'\n\t\t| 'stylus'\n\t\t| 'styl'\n\t\t| 'postcss'\n\t\t| 'pcss'\n\t\t| 'unknown'\n\t\t| (string & {});\n}\n\nexport interface TSXResult {\n\tcode: string;\n\tmap: SourceMap;\n\tdiagnostics: DiagnosticMessage[];\n\tmetaRanges: {\n\t\tfrontmatter: TSXLocation;\n\t\tbody: TSXLocation;\n\t\tscripts?: TSXExtractedScript[];\n\t\tstyles?: TSXExtractedStyle[];\n\t};\n}\n\nexport interface ParseResult {\n\tast: RootNode;\n\tdiagnostics: DiagnosticMessage[];\n}\n\n// This function transforms a single JavaScript file. It can be used to minify\n// JavaScript, convert TypeScript/JSX to JavaScript, or convert newer JavaScript\n// to older JavaScript. It returns a promise that is either resolved with a\n// \"TransformResult\" object or rejected with a \"TransformFailure\" object.\n//\n// Works in node: yes\n// Works in browser: yes\nexport declare function transform(\n\tinput: string,\n\toptions?: TransformOptions\n): Promise<TransformResult>;\n\nexport declare function parse(input: string, options?: ParseOptions): Promise<ParseResult>;\n\nexport declare function convertToTSX(\n\tinput: string,\n\toptions?: ConvertToTSXOptions\n): Promise<TSXResult>;\n\n// This configures the browser-based version of astro. It is necessary to\n// call this first and wait for the returned promise to be resolved before\n// making other API calls when using astro in the browser.\n//\n// Works in node: yes\n// Works in browser: yes (\"options\" is required)\nexport declare function initialize(options: InitializeOptions): Promise<void>;\n\n/**\n * When calling the core compiler APIs, e.g. `transform`, `parse`, etc, they\n * would automatically instantiate a WASM instance to process the input. When\n * done, you can call this to manually teardown the WASM instance.\n *\n * If the APIs are called again, they will automatically instantiate a new WASM\n * instance. In browsers, you have to call `initialize()` again before using the APIs.\n *\n * Note: Calling teardown is optional and exists mostly as an optimization only.\n */\nexport declare function teardown(): void;\n\nexport interface InitializeOptions {\n\t// The URL of the \"astro.wasm\" file. This must be provided when running\n\t// astro in the browser.\n\twasmURL?: string;\n}\n"
  },
  {
    "path": "packages/compiler/sync.d.ts",
    "content": "export * from './dist/node/sync.js';\n"
  },
  {
    "path": "packages/compiler/test/bad-styles/sass.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<style lang=\"scss\">\n\tarticle:global(:is(h1, h2, h3, h4, h5, h6):hover {\n\t\tcolor: purple;\n\t}\n</style>\n<style lang=\"scss\">\n\tarticle:is(h1, h2, h3, h4, h5, h6)):hover {\n\t\tcolor: purple;\n\t}\n</style>\n`;\n\ntest('it works', async () => {\n\tconst result = await transform(FIXTURE, {\n\t\tfilename: '/users/astro/apps/pacman/src/pages/index.astro',\n\t\tasync preprocessStyle() {\n\t\t\treturn {\n\t\t\t\terror: new Error('Unable to convert').message,\n\t\t\t};\n\t\t},\n\t});\n\tassert.equal(result.styleError.length, 2);\n\tassert.equal(result.styleError[0], 'Unable to convert');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/bad-styles/unclosed-style.ts",
    "content": "import { type ParseResult, parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { ElementNode } from '../../types.js';\n\ntest('can compile unfinished style', async () => {\n\tlet error = 0;\n\tlet result: ParseResult = {} as ParseResult;\n\n\ttry {\n\t\tresult = await parse('<style>');\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\n\tconst style = result.ast.children[0] as ElementNode;\n\tassert.equal(error, 0, 'Expected to compile with unfinished style.');\n\tassert.ok(result.ast, 'Expected to compile with unfinished style.');\n\tassert.equal(style.name, 'style', 'Expected to compile with unfinished style.');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/body-after-head-component.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\nconst isProd = true;\n---\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    {isProd && <TestHead />}\n    <title>document</title>\n    {isProd && <slot />}\n  </head>\n  <body style=\"color: red;\">\n    <main>\n       <h1>Welcome to <span class=\"text-gradient\">Astro</span></h1>\n    </main>\n  </body>\n</html>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('has body in output', () => {\n\tassert.match(\n\t\tresult.code,\n\t\t'<body style=\"color: red;\">',\n\t\t'Expected output to contain body element!'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/body-expression.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nconst slugs = ['one', 'two', 'three'];\n---\n\n<html>\n  <head></head>\n  <body>\n    {slugs.map((slug) => (\n      <a href={\\`/post/\\${slug}\\`}>{slug}</a>\n    ))}\n  </body>\n</html>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('can compiler body expression', () => {\n\tassert.ok(result.code, 'Expected to compiler body expression!');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/comment.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\n/***/\n---\n\n<div />\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('Can handle multi-* comments', () => {\n\tassert.ok(result.code, 'Expected to compile');\n\tassert.equal(result.diagnostics.length, 0, 'Expected no diagnostics');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/component-metadata/index.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport One from '../components/one.jsx';\nimport * as Two from '../components/two.jsx';\nimport { Three } from '../components/three.tsx';\nimport * as four from '../components/four.jsx';\n\nimport * as Five from '../components/five.jsx';\nimport { Six } from '../components/six.jsx';\nimport Seven from '../components/seven.jsx';\nimport * as eight from '../components/eight.jsx';\n---\n\n<One client:load />\n<Two.someName client:load />\n<Three client:load />\n<four.nested.deep.Component client:load />\n\n<!-- client only tests -->\n<Five.someName client:only />\n<Six client:only />\n<Seven client:only />\n<eight.nested.deep.Component client:only />\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: '/users/astro/apps/pacman/src/pages/index.astro',\n\t});\n});\n\ntest('Hydrated component', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components.length, 4);\n});\n\ntest('Hydrated components: default export', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[0].exportName, 'default');\n\tassert.equal(components[0].specifier, '../components/one.jsx');\n\tassert.equal(components[0].resolvedPath, '/users/astro/apps/pacman/src/components/one.jsx');\n});\n\ntest('Hydrated components: star export', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[1].exportName, 'someName');\n\tassert.equal(components[1].specifier, '../components/two.jsx');\n\tassert.equal(components[1].resolvedPath, '/users/astro/apps/pacman/src/components/two.jsx');\n});\n\ntest('Hydrated components: named export', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[2].exportName, 'Three');\n\tassert.equal(components[2].specifier, '../components/three.tsx');\n\tassert.equal(components[2].resolvedPath, '/users/astro/apps/pacman/src/components/three.tsx');\n});\n\ntest('Hydrated components: deep nested export', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[3].exportName, 'nested.deep.Component');\n\tassert.equal(components[3].specifier, '../components/four.jsx');\n\tassert.equal(components[3].resolvedPath, '/users/astro/apps/pacman/src/components/four.jsx');\n});\n\ntest('ClientOnly component', () => {\n\tconst components = result.clientOnlyComponents;\n\tassert.equal(components.length, 4);\n});\n\ntest('ClientOnly components: star export', () => {\n\tconst components = result.clientOnlyComponents;\n\tassert.equal(components[0].exportName, 'someName');\n\tassert.equal(components[0].specifier, '../components/five.jsx');\n\tassert.equal(components[0].resolvedPath, '/users/astro/apps/pacman/src/components/five.jsx');\n});\n\ntest('ClientOnly components: named export', () => {\n\tconst components = result.clientOnlyComponents;\n\tassert.equal(components[1].exportName, 'Six');\n\tassert.equal(components[1].specifier, '../components/six.jsx');\n\tassert.equal(components[1].resolvedPath, '/users/astro/apps/pacman/src/components/six.jsx');\n});\n\ntest('ClientOnly components: default export', () => {\n\tconst components = result.clientOnlyComponents;\n\tassert.equal(components[2].exportName, 'default');\n\tassert.equal(components[2].specifier, '../components/seven.jsx');\n\tassert.equal(components[2].resolvedPath, '/users/astro/apps/pacman/src/components/seven.jsx');\n});\n\ntest('ClientOnly components: deep nested export', () => {\n\tconst components = result.clientOnlyComponents;\n\tassert.equal(components[3].exportName, 'nested.deep.Component');\n\tassert.equal(components[3].specifier, '../components/eight.jsx');\n\tassert.equal(components[3].resolvedPath, '/users/astro/apps/pacman/src/components/eight.jsx');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/component-name.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = '<div>Hello world!</div>';\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: '/src/components/Cool.astro',\n\t});\n});\n\ntest('exports named component', () => {\n\tassert.match(result.code, 'export default $$Cool', 'Expected output to contain named export');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/export.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('TypeScript props on newline', async () => {\n\tconst FIXTURE = `---\nexport type Props = BaseLayoutProps &\n  Pick<LocaleSelectProps, 'locale' | 'someOtherProp'>;\n---\n\n<div></div>\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'BaseLayoutProps &\\n  Pick<',\n\t\t'Expected output to contain full Props export'\n\t);\n});\n\ntest('exported type', async () => {\n\tconst FIXTURE = `---\n// this is fine\nexport type NumberType = number;\n// astro hangs because of this typedef.\n// comment it out and astro will work fine.\nexport type FuncType = (x: number) => number;\n---\n\n{new Date()}\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'export type NumberType = number;\\nexport type FuncType = (x: number) => number',\n\t\t'Expected output to contain full Props export'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/expression-then-node.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport Show from './Show.astro';\n\nexport interface Props<T> {\n\teach: Iterable<T>;\n}\n\nconst { each } = Astro.props;\n---\n\n{\n\t(async function* () {\n\t\tfor await (const value of each) {\n\t\t\tlet html = await Astro.slots.render('default', [value]);\n\t\t\tyield <Fragment set:html={html} />;\n\t\t\tyield '\\n';\n\t\t}\n\t})()\n}\n\n<Show when={!each.length}>\n\t<slot name=\"fallback\" />\n</Show>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('expression followed by node', () => {\n\tassert.match(\n\t\tresult.code,\n\t\t`yield '\n';\n\t\t}`,\n\t\t'Expected output to properly handle expression!'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/expressions.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('Can handle < inside JSX expression', async () => {\n\tconst input = `<Layout>\n   {\n      new Array(totalPages).fill(0).map((_, index) => {\n        const active = currentPage === index;\n        if (\n          totalPages > 25 &&\n          ( index < currentPage - offset ||\n            index > currentPage + offset)\n        ) {\n          return 'HAAAA';\n        }\n      })\n    }\n</Layout>\n`;\n\tconst output = await transform(input);\n\tassert.ok(output.code, 'Expected to compile');\n\tassert.match(\n\t\toutput.code,\n\t\t`new Array(totalPages).fill(0).map((_, index) => {\n        const active = currentPage === index;\n        if (\n          totalPages > 25 &&\n          ( index < currentPage - offset ||\n            index > currentPage + offset)\n        ) {\n          return 'HAAAA';\n        }\n      })`,\n\t\t'Expected expression to be compiled properly'\n\t);\n\tassert.equal(output.diagnostics.length, 0, 'Expected no diagnostics');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/fragment.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport ThemeToggleButton from './ThemeToggleButton.tsx';\n---\n\n<title>Uhhh</title>\n\n<body><div>Hello!</div></body>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('can compile fragment', () => {\n\tassert.not.match(result.code, '<head>', 'Expected output not to contain <head>');\n\tassert.match(\n\t\tresult.code,\n\t\t'<body><div>Hello!</div></body>',\n\t\t'Expected output to contain <body><div>Hello!</div></body>'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/get-static-paths.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('getStaticPaths with braces on newline', async () => {\n\tconst FIXTURE = `---\nimport A from './A.astro';\nexport async function getStaticPaths()\n{\n  return [\n    { params: { id: '1' } },\n    { params: { id: '2' } },\n    { params: { id: '3' } }\n  ];\n}\n---\n\n<div></div>\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'export async function getStaticPaths()\\n{',\n\t\t'Expected output to contain getStaticPaths output'\n\t);\n});\n\ntest('getStaticPaths with braces on newline and destructured params', async () => {\n\tconst FIXTURE = `---\nimport A from './A.astro';\nexport async function getStaticPaths({ paginate })\n{\n  return [\n    { params: { id: '1' } },\n    { params: { id: '2' } },\n    { params: { id: '3' } }\n  ];\n}\n---\n\n<div></div>\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'export async function getStaticPaths({ paginate })\\n{',\n\t\t'Expected output to contain getStaticPaths output'\n\t);\n});\n\ntest('getStaticPaths as const without braces', async () => {\n\tconst FIXTURE = `---\nimport A from './A.astro';\nexport const getStaticPaths = () => ([\n  { params: { id: '1' } },\n  { params: { id: '2' } },\n  { params: { id: '3' } }\n])\n---\n\n<div></div>\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'export const getStaticPaths = () => ([',\n\t\t'Expected output to contain getStaticPaths output'\n\t);\n});\n\ntest('getStaticPaths as const with braces on newline', async () => {\n\tconst FIXTURE = `---\nimport A from './A.astro';\nexport const getStaticPaths = () =>\n{\n  return [\n    { params: { id: '1' } },\n    { params: { id: '2' } },\n    { params: { id: '3' } }\n  ];\n}\n---\n\n<div></div>\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'export const getStaticPaths = () =>\\n{',\n\t\t'Expected output to contain getStaticPaths output'\n\t);\n});\n\ntest('getStaticPaths with whitespace', async () => {\n\tconst FIXTURE = `---\nexport const getStaticPaths = async () => {\n\tconst content = await Astro.glob('../content/*.mdx');\n\n\treturn content\n    .filter((page) => !page.frontmatter.draft) // skip drafts\n    .map(({ default: MdxContent, frontmatter, url, file }) => {\n        return {\n          params: { slug: frontmatter.slug || \"index\" },\n          props: {\n            MdxContent,\n\t\t\t\t\t\tfile,\n            frontmatter,\n\t\t\t\t\t\turl\n          }\n        }\n     })\n}\n\nconst { MdxContent, frontmatter, url, file } = Astro.props;\n---\n<div></div>\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'\\nconst $$stdin = ',\n\t\t'Expected getStaticPaths hoisting to maintain newlines'\n\t);\n});\n\ntest('getStaticPaths with types', async () => {\n\tconst FIXTURE = `---\nexport async function getStaticPaths({\n  paginate,\n}: {\n  paginate: PaginateFunction;\n}) {\n  const allPages = (\n    await getCollection(\n      \"blog\"\n    )\n  );\n  return paginate(allPages, { pageSize: 10 });\n}\n---\n\n<div></div>\n`;\n\tconst result = await transform(FIXTURE);\n\tassert.match(\n\t\tresult.code,\n\t\t'{\\n  paginate: PaginateFunction;\\n}) {',\n\t\t'Expected output to contain getStaticPaths output'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/head-injection.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = '<html><head><title>Ah</title></head></html>';\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('head injection', () => {\n\tassert.match(\n\t\tresult.code,\n\t\t'$$renderHead($$result)',\n\t\t'Expected output to contain $$renderHead($$result) injection point'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/lt-gt-text.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\n// Component Imports\nimport MainHead from '../components/MainHead.astro';\nimport Nav from '../components/Nav.astro';\nimport Footer from '../components/Footer.astro';\nimport PortfolioPreview from '../components/PortfolioPreview.astro';\n\n// Data Fetching: List all Markdown posts in the repo.\nconst projects = await Astro.glob('./project/**/*.md');\nconst featuredProject = projects[0];\n\n// Full Astro Component Syntax:\n// https://docs.astro.build/core-concepts/astro-components/\n---\n\n<html lang=\"en\">\n\t<head>\n\t\t<MainHead\n\t\t\ttitle=\"Jeanine White: Personal Site\"\n\t\t\tdescription=\"Jeanine White: Developer, Speaker, and Writer...\"\n\t\t/>\n\n\t</head>\n\t<body>\n\t    <Nav />\n\t\t<small>< header ></small>\n\t    <Footer />\n\t</body>\n</html>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('< and > as raw text', () => {\n\tassert.ok(result.code, 'Expected to compile');\n\tassert.equal(result.diagnostics.length, 0, 'Expected no diagnostics');\n\tassert.match(result.code, '< header >', 'Expected output to contain < header >');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/null-chars.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<div xmlns:happy=\"https://example.com/schemas/happy\">\n  <img src=\"jolly.avif\" happy:smile=\"sweet\"/>\n</div>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename:\n\t\t\t'/Users/matthew/dev/astro/packages/astro/test/fixtures/astro-attrs/src/pages/namespaced.astro',\n\t\tsourcemap: 'both',\n\t});\n});\n\ntest('Includes null characters', () => {\n\tassert.not.match(result.code, '\\x00', 'Corrupted output');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/props-interface.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\n// eslint-disable-next-line no-undef\nexport interface Props extends astroHTML.JSX.HTMLAttributes {}\n\nconst props = { ...Astro.props } as Props;\n---\n\n<body class:list={props['class:list']}>\n  <slot></slot>\n</body>`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('retains newlines around comment', () => {\n\tassert.ok(result.code, 'Expected to compile');\n\tassert.match(result.code, /\\/\\/ eslint-disable-next-line no-undef\\n/g);\n\tassert.equal(result.diagnostics.length, 0, 'Expected no diagnostics');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/script-before-html.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<script>\n  // anything ...\n</script>\n\n<!DOCTYPE html>\n<html lang=\"de\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width\" />\n    <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n    <meta name=\"generator\" content={Astro.generator} />\n    <title>Astro strips html lang tag</title>\n  </head>\n  <body>\n    <main>\n      <slot />\n    </main>\n  </body>\n</html>\n\n<style lang=\"scss\" is:global>\nhtml {\n  scroll-behavior: smooth;\n}\n</style>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('includes html element', () => {\n\tassert.ok(\n\t\tresult.code.includes('<html lang=\"de\">'),\n\t\t'Expected compile result to include html element!'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/script-fragment.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `<script src={Astro.resolve(\"../scripts/no_hoist_nonmodule.js\")}></script>`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('script fragment', () => {\n\tassert.ok(result.code, 'Can compile script fragment');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/top-level-expressions.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nconst { items, emptyItems } = Astro.props;\n\nconst internal = [];\n---\n\n<!-- False -->\n{false && (\n  <span id=\"frag-false\" />\n)}\n\n<!-- Null -->\n{null && (\n  <span id=\"frag-null\" />\n)}\n\n<!-- True -->\n{true && (\n  <span id=\"frag-true\" />\n)}\n\n<!-- Undefined -->\n{false && (<span id=\"frag-undefined\" />)}\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('top-level expressions', () => {\n\tassert.ok(result.code, 'Can compile top-level expressions');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/trailing-newline.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `{\n  node.shouldRenderChildren() ? (\n    // IMPORTANT - DO NOT SELF CLOSE THIS TAG. ASTRO FREAKS OUT.\n    <Fragment set:html={children}></Fragment>\n  ) : node.shouldRenderSelf() ? (\n    // @ts-ignore\n    content.map((element) => {\n      return <Astro.self content={element} components={components} />;\n    })\n  ) : node.shouldRenderTag() ? (\n    <Tag {...props}>\n      {node.hasChildren() ? (\n        <Astro.self content={children} components={components} />\n      ) : null}\n    </Tag>\n  ) : null\n}\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('does not add trailing newline to rendered output', () => {\n\tassert.match(\n\t\tresult.code,\n\t\t`}\\`;\\n}, '<stdin>', undefined);`,\n\t\t'Does not include a trailing newline in the render function'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/trailing-space.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\nimport { Markdown } from 'astro/components';\nimport Layout from '../layouts/content.astro';\n---\n\n<style>\n  #root {\n    color: green;\n  }\n</style>\n\n<Layout>\n  <div id=\"root\">\n    <Markdown is:raw>\n      ## Interesting Topic\n    </Markdown>\n  </div>\n</Layout>`; // NOTE: the lack of trailing space is important to this test!\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('trailing space', () => {\n\tassert.ok(result.code, 'Expected to compiler');\n\tassert.not.match(result.code, 'html', 'Expected output to not contain <html>');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/basic/trailing-spaces-ii.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\n---\n\n<span class=\"spoiler\">\n    <slot />\n</span>\n\n<style>\nspan { color: red; }\n</style>\n<script>\nconsole.log(\"hello\")\n</script>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('trailing space', () => {\n\tassert.ok(result.code, 'Expected to compiler');\n\tassert.match(\n\t\tresult.code,\n\t\t`<span class=\"spoiler astro-bqati2k5\">\n    \\${$$renderSlot($$result,$$slots[\"default\"])}\n</span>\n\n\n\\${$$renderScript($$result,\"<stdin>?astro&type=script&index=0&lang.ts\")}\\``\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/client-directive/special-characters.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport CaretCounter from '../components/^--with-carets/Counter';\nimport RocketCounter from '../components/and-rockets-🚀/Counter';\nimport PercentCounter from '../components/now-100%-better/Counter';\nimport SpaceCounter from '../components/with some spaces/Counter';\nimport RoundBracketCounter from '../components/with-(round-brackets)/Counter';\nimport SquareBracketCounter from '../components/with-[square-brackets]/Counter';\nimport RemoteComponent from 'https://test.com/components/with-[wacky-brackets}()10%-cooler/Counter';\n---\n<html>\n<body>\n  <h1>Special chars in component import paths from an .astro file</h1>\n  <CaretCounter id=\"caret\" client:visible />\n  <RocketCounter id=\"rocket\" client:visible />\n  <PercentCounter id=\"percent\" client:visible />\n  <SpaceCounter id=\"space\" client:visible />\n  <RoundBracketCounter id=\"round-bracket\" client:visible />\n  <SquareBracketCounter id=\"square-bracket\" client:visible />\n  <RemoteComponent id=\"remote-component\" client:visible />\n</body>\n</html>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, { filename: '/users/astro/apps/pacman/src/pages/index.astro' });\n});\n\ntest('does not panic', () => {\n\tassert.ok(result.code);\n});\n\ntest('hydrated components with carets', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[0].exportName, 'default');\n\tassert.equal(components[0].specifier, '../components/^--with-carets/Counter');\n\tassert.equal(\n\t\tcomponents[0].resolvedPath,\n\t\t'/users/astro/apps/pacman/src/components/^--with-carets/Counter'\n\t);\n});\n\ntest('hydrated components with rockets', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[1].exportName, 'default');\n\tassert.equal(components[1].specifier, '../components/and-rockets-🚀/Counter');\n\tassert.equal(\n\t\tcomponents[1].resolvedPath,\n\t\t'/users/astro/apps/pacman/src/components/and-rockets-🚀/Counter'\n\t);\n});\n\ntest('hydrated components with percent', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[2].exportName, 'default');\n\tassert.equal(components[2].specifier, '../components/now-100%-better/Counter');\n\tassert.equal(\n\t\tcomponents[2].resolvedPath,\n\t\t'/users/astro/apps/pacman/src/components/now-100%-better/Counter'\n\t);\n});\n\ntest('hydrated components with spaces', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[3].exportName, 'default');\n\tassert.equal(components[3].specifier, '../components/with some spaces/Counter');\n\tassert.equal(\n\t\tcomponents[3].resolvedPath,\n\t\t'/users/astro/apps/pacman/src/components/with some spaces/Counter'\n\t);\n});\n\ntest('hydrated components with round brackets', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[4].exportName, 'default');\n\tassert.equal(components[4].specifier, '../components/with-(round-brackets)/Counter');\n\tassert.equal(\n\t\tcomponents[4].resolvedPath,\n\t\t'/users/astro/apps/pacman/src/components/with-(round-brackets)/Counter'\n\t);\n});\n\ntest('hydrated components with square brackets', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[5].exportName, 'default');\n\tassert.equal(components[5].specifier, '../components/with-[square-brackets]/Counter');\n\tassert.equal(\n\t\tcomponents[5].resolvedPath,\n\t\t'/users/astro/apps/pacman/src/components/with-[square-brackets]/Counter'\n\t);\n});\n\ntest('hydrated components with kitchen-sink', () => {\n\tconst components = result.hydratedComponents;\n\tassert.equal(components[6].exportName, 'default');\n\tassert.equal(\n\t\tcomponents[6].specifier,\n\t\t'https://test.com/components/with-[wacky-brackets}()10%-cooler/Counter'\n\t);\n\tassert.equal(\n\t\tcomponents[6].resolvedPath,\n\t\t'https://test.com/components/with-[wacky-brackets}()10%-cooler/Counter'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/client-directive/warn.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<script client:load></script>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('reports a warning for using a client directive', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 2);\n\tassert.equal(result.diagnostics[0].severity, 2);\n\tassert.match(result.diagnostics[0].text, 'does not need the client:load directive');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/compact/minify.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nasync function minify(input: string) {\n\tconst code = (await transform(input, { compact: true })).code;\n\treturn code.replace('${$$maybeRenderHead($$result)}', '');\n}\n\ntest('basic', async () => {\n\tassert.match(\n\t\tawait minify('    <div>Hello {value}!</div>      '),\n\t\t'$$render`<div>Hello ${value}!</div>`'\n\t);\n\tassert.match(\n\t\tawait minify('    <div> Hello {value}! </div>      '),\n\t\t'$$render`<div> Hello ${value}! </div>`'\n\t);\n});\n\ntest('preservation', async () => {\n\tassert.match(await minify('<pre>  !  </pre>'), '$$render`<pre>  !  </pre>`');\n\tassert.match(await minify('<div is:raw>  !  </div>'), '$$render`<div>  !  </div>`');\n\tassert.match(await minify('<Markdown is:raw>  !  </Markdown>'), '$$render`  !  `');\n});\n\ntest('collapsing', async () => {\n\tassert.match(await minify('<span> inline </span>'), '$$render`<span> inline </span>`');\n\tassert.match(\n\t\tawait minify('<span>\\n inline \\t{\\t expression \\t}</span>'),\n\t\t'$$render`<span>\\ninline ${expression}</span>`'\n\t);\n\tassert.match(\n\t\tawait minify('<span> inline { expression }</span>'),\n\t\t'$$render`<span> inline ${expression}</span>`'\n\t);\n});\n\ntest('space normalization between attributes', async () => {\n\tassert.match(await minify('<p title=\"bar\">foo</p>'), '<p title=\"bar\">foo</p>');\n\tassert.match(await minify('<img src=\"test\"/>'), '<img src=\"test\">');\n\tassert.match(await minify('<p title = \"bar\">foo</p>'), '<p title=\"bar\">foo</p>');\n\tassert.match(await minify('<p title\\n\\n\\t  =\\n     \"bar\">foo</p>'), '<p title=\"bar\">foo</p>');\n\tassert.match(await minify('<img src=\"test\" \\n\\t />'), '<img src=\"test\">');\n\tassert.match(\n\t\tawait minify('<input title=\"bar\"       id=\"boo\"    value=\"hello world\">'),\n\t\t'<input title=\"bar\" id=\"boo\" value=\"hello world\">'\n\t);\n});\n\ntest('space normalization around text', async () => {\n\tassert.match(await minify('   <p>blah</p>\\n\\n\\n   '), '<p>blah</p>');\n\tassert.match(await minify('<p>foo <img> bar</p>'), '<p>foo <img> bar</p>');\n\tassert.match(await minify('<p>foo<img>bar</p>'), '<p>foo<img>bar</p>');\n\tassert.match(await minify('<p>foo <img>bar</p>'), '<p>foo <img>bar</p>');\n\tassert.match(await minify('<p>foo<img> bar</p>'), '<p>foo<img> bar</p>');\n\tassert.match(await minify('<p>foo <wbr> bar</p>'), '<p>foo <wbr> bar</p>');\n\tassert.match(await minify('<p>foo<wbr>bar</p>'), '<p>foo<wbr>bar</p>');\n\tassert.match(await minify('<p>foo <wbr>bar</p>'), '<p>foo <wbr>bar</p>');\n\tassert.match(await minify('<p>foo<wbr> bar</p>'), '<p>foo<wbr> bar</p>');\n\tassert.match(await minify('<p>foo <wbr baz moo=\"\"> bar</p>'), '<p>foo <wbr baz moo=\"\"> bar</p>');\n\tassert.match(await minify('<p>foo<wbr baz moo=\"\">bar</p>'), '<p>foo<wbr baz moo=\"\">bar</p>');\n\tassert.match(await minify('<p>foo <wbr baz moo=\"\">bar</p>'), '<p>foo <wbr baz moo=\"\">bar</p>');\n\tassert.match(await minify('<p>foo<wbr baz moo=\"\"> bar</p>'), '<p>foo<wbr baz moo=\"\"> bar</p>');\n\tassert.match(\n\t\tawait minify('<p>  <a href=\"#\">  <code>foo</code></a> bar</p>'),\n\t\t'<p> <a href=\"#\"> <code>foo</code></a> bar</p>'\n\t);\n\tassert.match(\n\t\tawait minify('<p><a href=\"#\"><code>foo  </code></a> bar</p>'),\n\t\t'<p><a href=\"#\"><code>foo </code></a> bar</p>'\n\t);\n\tassert.match(\n\t\tawait minify('<p>  <a href=\"#\">  <code>   foo</code></a> bar   </p>'),\n\t\t'<p> <a href=\"#\"> <code> foo</code></a> bar </p>'\n\t);\n\tassert.match(\n\t\tawait minify('<div> Empty <!-- or --> not </div>'),\n\t\t'<div> Empty <!-- or --> not </div>'\n\t);\n\tassert.match(\n\t\tawait minify('<div> a <input><!-- b --> c </div>'),\n\t\t'<div> a <input><!-- b --> c </div>'\n\t);\n\tawait Promise.all(\n\t\t[\n\t\t\t'a',\n\t\t\t'abbr',\n\t\t\t'acronym',\n\t\t\t'b',\n\t\t\t'big',\n\t\t\t'del',\n\t\t\t'em',\n\t\t\t'font',\n\t\t\t'i',\n\t\t\t'ins',\n\t\t\t'kbd',\n\t\t\t'mark',\n\t\t\t's',\n\t\t\t'samp',\n\t\t\t'small',\n\t\t\t'span',\n\t\t\t'strike',\n\t\t\t'strong',\n\t\t\t'sub',\n\t\t\t'sup',\n\t\t\t'time',\n\t\t\t'tt',\n\t\t\t'u',\n\t\t\t'var',\n\t\t].map(async (el) => {\n\t\t\tconst [open, close] = [`<${el}>`, `</${el}>`];\n\t\t\tassert.match(await minify(`foo ${open}baz${close} bar`), `foo ${open}baz${close} bar`);\n\t\t\tassert.match(await minify(`foo${open}baz${close}bar`), `foo${open}baz${close}bar`);\n\t\t\tassert.match(await minify(`foo ${open}baz${close}bar`), `foo ${open}baz${close}bar`);\n\t\t\tassert.match(await minify(`foo${open}baz${close} bar`), `foo${open}baz${close} bar`);\n\t\t\tassert.match(await minify(`foo ${open} baz ${close} bar`), `foo ${open} baz ${close} bar`);\n\t\t\tassert.match(await minify(`foo${open} baz ${close}bar`), `foo${open} baz ${close}bar`);\n\t\t\tassert.match(await minify(`foo ${open} baz ${close}bar`), `foo ${open} baz ${close}bar`);\n\t\t\tassert.match(await minify(`foo${open} baz ${close} bar`), `foo${open} baz ${close} bar`);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo ${open}baz${close} bar</div>`),\n\t\t\t\t`<div>foo ${open}baz${close} bar</div>`\n\t\t\t);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo${open}baz${close}bar</div>`),\n\t\t\t\t`<div>foo${open}baz${close}bar</div>`\n\t\t\t);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo ${open}baz${close}bar</div>`),\n\t\t\t\t`<div>foo ${open}baz${close}bar</div>`\n\t\t\t);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo${open}baz${close} bar</div>`),\n\t\t\t\t`<div>foo${open}baz${close} bar</div>`\n\t\t\t);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo ${open} baz ${close} bar</div>`),\n\t\t\t\t`<div>foo ${open} baz ${close} bar</div>`\n\t\t\t);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo${open} baz ${close}bar</div>`),\n\t\t\t\t`<div>foo${open} baz ${close}bar</div>`\n\t\t\t);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo ${open} baz ${close}bar</div>`),\n\t\t\t\t`<div>foo ${open} baz ${close}bar</div>`\n\t\t\t);\n\t\t\tassert.match(\n\t\t\t\tawait minify(`<div>foo${open} baz ${close} bar</div>`),\n\t\t\t\t`<div>foo${open} baz ${close} bar</div>`\n\t\t\t);\n\t\t})\n\t);\n\t// Don't trim whitespace around element, but do trim within\n\tawait Promise.all(\n\t\t['bdi', 'bdo', 'button', 'cite', 'code', 'dfn', 'math', 'q', 'rt', 'rtc', 'ruby', 'svg'].map(\n\t\t\tasync (el) => {\n\t\t\t\tconst [open, close] = [`<${el}>`, `</${el}>`];\n\t\t\t\tassert.match(await minify(`foo ${open}baz${close} bar`), `foo ${open}baz${close} bar`);\n\t\t\t\tassert.match(await minify(`foo${open}baz${close}bar`), `foo${open}baz${close}bar`);\n\t\t\t\tassert.match(await minify(`foo ${open}baz${close}bar`), `foo ${open}baz${close}bar`);\n\t\t\t\tassert.match(await minify(`foo${open}baz${close} bar`), `foo${open}baz${close} bar`);\n\t\t\t\tassert.match(await minify(`foo ${open} baz ${close} bar`), `foo ${open} baz ${close} bar`);\n\t\t\t\tassert.match(await minify(`foo${open} baz ${close}bar`), `foo${open} baz ${close}bar`);\n\t\t\t\tassert.match(await minify(`foo ${open} baz ${close}bar`), `foo ${open} baz ${close}bar`);\n\t\t\t\tassert.match(await minify(`foo${open} baz ${close} bar`), `foo${open} baz ${close} bar`);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo ${open}baz${close} bar</div>`),\n\t\t\t\t\t`<div>foo ${open}baz${close} bar</div>`\n\t\t\t\t);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo${open}baz${close}bar</div>`),\n\t\t\t\t\t`<div>foo${open}baz${close}bar</div>`\n\t\t\t\t);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo ${open}baz${close}bar</div>`),\n\t\t\t\t\t`<div>foo ${open}baz${close}bar</div>`\n\t\t\t\t);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo${open}baz${close} bar</div>`),\n\t\t\t\t\t`<div>foo${open}baz${close} bar</div>`\n\t\t\t\t);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo ${open} baz ${close} bar</div>`),\n\t\t\t\t\t`<div>foo ${open} baz ${close} bar</div>`\n\t\t\t\t);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo${open} baz ${close}bar</div>`),\n\t\t\t\t\t`<div>foo${open} baz ${close}bar</div>`\n\t\t\t\t);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo ${open} baz ${close}bar</div>`),\n\t\t\t\t\t`<div>foo ${open} baz ${close}bar</div>`\n\t\t\t\t);\n\t\t\t\tassert.match(\n\t\t\t\t\tawait minify(`<div>foo${open} baz ${close} bar</div>`),\n\t\t\t\t\t`<div>foo${open} baz ${close} bar</div>`\n\t\t\t\t);\n\t\t\t}\n\t\t)\n\t);\n\tawait Promise.all(\n\t\t[\n\t\t\t['<span> foo </span>', '<span> foo </span>'],\n\t\t\t[' <span> foo </span> ', '<span> foo </span>'],\n\t\t\t['<nobr>a</nobr>', '<nobr>a</nobr>'],\n\t\t\t['<nobr>a </nobr>', '<nobr>a </nobr>'],\n\t\t\t['<nobr> a</nobr>', '<nobr> a</nobr>'],\n\t\t\t['<nobr> a </nobr>', '<nobr> a </nobr>'],\n\t\t\t['a<nobr>b</nobr>c', 'a<nobr>b</nobr>c'],\n\t\t\t['a<nobr>b </nobr>c', 'a<nobr>b </nobr>c'],\n\t\t\t['a<nobr> b</nobr>c', 'a<nobr> b</nobr>c'],\n\t\t\t['a<nobr> b </nobr>c', 'a<nobr> b </nobr>c'],\n\t\t\t['a<nobr>b</nobr> c', 'a<nobr>b</nobr> c'],\n\t\t\t['a<nobr>b </nobr> c', 'a<nobr>b </nobr> c'],\n\t\t\t['a<nobr> b</nobr> c', 'a<nobr> b</nobr> c'],\n\t\t\t['a<nobr> b </nobr> c', 'a<nobr> b </nobr> c'],\n\t\t\t['a <nobr>b</nobr>c', 'a <nobr>b</nobr>c'],\n\t\t\t['a <nobr>b </nobr>c', 'a <nobr>b </nobr>c'],\n\t\t\t['a <nobr> b</nobr>c', 'a <nobr> b</nobr>c'],\n\t\t\t['a <nobr> b </nobr>c', 'a <nobr> b </nobr>c'],\n\t\t\t['a <nobr>b</nobr> c', 'a <nobr>b</nobr> c'],\n\t\t\t['a <nobr>b </nobr> c', 'a <nobr>b </nobr> c'],\n\t\t\t['a <nobr> b</nobr> c', 'a <nobr> b</nobr> c'],\n\t\t\t['a <nobr> b </nobr> c', 'a <nobr> b </nobr> c'],\n\t\t].map(async ([input, output]) => {\n\t\t\tassert.match(await minify(input), output);\n\t\t})\n\t);\n});\n\ntest('surrounded by newlines (astro#7401)', async () => {\n\tconst input = '<span>foo</span>\\n\\t\\tbar\\n\\t\\t<span>baz</span>';\n\tconst output = '<span>foo</span>\\nbar\\n<span>baz</span>';\n\tconst result = await minify(input);\n\n\tassert.match(result, output);\n});\n\ntest('separated by newlines (#815)', async () => {\n\tconst input = '<p>\\n\\ta\\n\\t<span>b</span>\\n\\tc\\n</p>';\n\tconst output = '<p>\\na\\n<span>b</span>\\nc\\n</p>';\n\tconst result = await minify(input);\n\n\tassert.match(result, output);\n});\n"
  },
  {
    "path": "packages/compiler/test/css-order/astro-styles.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<style>\n  body { color: green; }\n</style>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: 'test.astro',\n\t});\n});\n\ntest('Astro style imports are included in the compiled JS', () => {\n\tconst idx = result.code.indexOf('test.astro?astro&type=style&index=0&lang.css');\n\tassert.not.equal(idx, -1);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/css-order/imported-styles.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport '../styles/global.css';\n---\n<style>\n  body { color: green; }\n</style>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: 'test.astro',\n\t});\n});\n\ntest('Astro style imports placed after frontmatter imports', () => {\n\tconst idx1 = result.code.indexOf('../styles/global.css');\n\tconst idx2 = result.code.indexOf('test.astro?astro&type=style&index=0&lang.css');\n\tassert.ok(idx2 > idx1);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/errors/client-only-unfound.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\nimport * as components from '../components';\nconst { MyComponent } = components;\n---\n<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <MyComponent client:only />\n  </body>\n</html>`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: '/src/components/Cool.astro',\n\t});\n});\n\ntest('got an error because client:only component not found import', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(\n\t\tresult.diagnostics[0].text,\n\t\t'Unable to find matching import statement for client:only component'\n\t);\n\tassert.is(\n\t\tFIXTURE.split('\\n')[result.diagnostics[0].location.line - 1],\n\t\t'    <MyComponent client:only />'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/errors/define-vars.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('define:vars warning', async () => {\n\tconst result = await transform(\n\t\t`<Fragment><slot /></Fragment>\n<style define:vars={{ color: 'red' }}></style>`,\n\t\t{ filename: '/src/components/Foo.astro' }\n\t);\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(result.diagnostics[0].code, 2007);\n});\n\ntest('define:vars no warning', async () => {\n\tconst result = await transform(\n\t\t`<div><slot /></div>\n<style define:vars={{ color: 'red' }}></style>`,\n\t\t{ filename: '/src/components/Foo.astro' }\n\t);\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 0);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/errors/fragment-shorthand.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    < data-test=\"hello\"><div></div></>\n  </body>\n</html>`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: '/src/components/fragment.astro',\n\t});\n});\n\ntest('got a tokenizer error', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(\n\t\tresult.diagnostics[0].text,\n\t\t'Unable to assign attributes when using <> Fragment shorthand syntax!'\n\t);\n\tconst loc = result.diagnostics[0].location;\n\tassert.is(FIXTURE.split('\\n')[loc.line - 1], `    < data-test=\"hello\"><div></div></>`);\n\tassert.is(\n\t\tFIXTURE.split('\\n')[loc.line - 1].slice(loc.column - 1, loc.column - 1 + loc.length),\n\t\t`< data-test=\"hello\">`\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/errors/html-comment.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <div>\n      <!--\n    </div>\n  </body>\n</html>`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: '/src/components/EOF.astro',\n\t});\n});\n\ntest('html comment error', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(result.diagnostics[0].text, 'Unterminated comment');\n\tassert.is(FIXTURE.split('\\n')[result.diagnostics[0].location.line - 1], '      <!--');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/errors/invalid-spread.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('...spread has warning', async () => {\n\tconst result = await transform('<Head ...seo />', { filename: '/src/components/Foo.astro' });\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(result.diagnostics[0].code, 2008);\n});\n\ntest('{...spread} does not have warning', async () => {\n\tconst result = await transform('<Head {...seo} />', { filename: '/src/components/Foo.astro' });\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 0);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/errors/jsx-comment.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <div>\n      {/*\n    </div>\n  </body>\n</html>`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: '/src/components/EOF.astro',\n\t});\n});\n\ntest('jsx comment error', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(result.diagnostics[0].text, 'Unterminated comment');\n\tassert.is(FIXTURE.split('\\n')[result.diagnostics[0].location.line - 1], '      {/*');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/errors/missing-frontmatter-fence.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\n// Missing opening frontmatter fence - only has closing ---\nconst FIXTURE = `import BaseLayout from '@/layouts/BaseLayout.astro';\nimport { getCollection } from 'astro:content';\nconst posts = await getCollection('blog');\n---\n<BaseLayout title=\"Crash Test\">\n  <h1>{posts.length}</h1>\n</BaseLayout>`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: '/src/pages/checkthis.astro',\n\t});\n});\n\ntest('missing opening frontmatter fence reports error instead of panic', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(result.diagnostics[0].code, 1006);\n\tassert.is(\n\t\tresult.diagnostics[0].text,\n\t\t'The closing frontmatter fence (---) is missing an opening fence'\n\t);\n\tassert.is(\n\t\tresult.diagnostics[0].hint,\n\t\t'Add --- at the beginning of your file before any import statements or code'\n\t);\n\t// Verify the error location points to the closing --- fence\n\tconst loc = result.diagnostics[0].location;\n\t// The line number should point to the line containing ---\n\tassert.is(FIXTURE.split('\\n')[loc.line - 1], '---');\n\t// The column and length should extract exactly the --- characters\n\tassert.is(\n\t\tFIXTURE.split('\\n')[loc.line - 1].slice(loc.column - 1, loc.column - 1 + loc.length),\n\t\t'---'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/head-metadata/with-head.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<html>\n  <head>\n    <title>Testing</title>\n  </head>\n  <body>\n    <h1>Testing</h1>\n  </body>\n</html>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: 'test.astro',\n\t});\n});\n\ntest('containsHead is true', () => {\n\tassert.equal(result.containsHead, true);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/head-metadata/without-head.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<slot />\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tfilename: 'test.astro',\n\t});\n});\n\ntest('containsHead is false', () => {\n\tassert.equal(result.containsHead, false);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/complex-frontmatter.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\nconst input = `---\n// TODO: Due to this issue: https://github.com/withastro/astro/issues/1438, this route can't be in the same folder\n// as the paginated article list is or they'll conflict, so this means our articles URL are \\`/article\\/\\${slug}\\` instead\n// of \\`/articles/\\${slug}\\` (with a s), once that issue is fixed, we'll be able to put it back in the right place\n\nconst foobar = true;\n\nimport { Article, postProcessArticle } from \"$data/articles\";\nimport type { GetStaticPaths, MDXInstance } from \"$data/shared\";\nimport ArticleLayout from \"$layouts/ArticleLayout.astro\";\nimport { getSlugFromFile } from \"$utils\";\n\nexport const getStaticPaths: GetStaticPaths = async () => {\n  const articles = await Astro.glob<Article>(\"/content/articles/**/*.mdx\");\n  return articles.map((article) => {\n    const augmentedFrontmatter = postProcessArticle(article.frontmatter, article.file);\n\n    return {\n      params: { slug: getSlugFromFile(article.file) },\n      props: { article: { ...article, frontmatter: augmentedFrontmatter } },\n    };\n  });\n};\n\ninterface Props {\n  article: MDXInstance<Article>;\n}\n\nconst { article } = Astro.props;\n---\n\n<ArticleLayout article={article} />`;\n\ntest('tracks getStaticPaths', async () => {\n\tconst loc = await testJSSourcemap(input, 'getStaticPaths');\n\tassert.equal(loc, { source: 'index.astro', line: 13, column: 14, name: null });\n});\n\ntest('tracks foobar', async () => {\n\tconst loc = await testJSSourcemap(input, 'foobar');\n\tassert.equal(loc, { source: 'index.astro', line: 6, column: 7, name: null });\n});\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/deprecated.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\ntest('script is:inline', async () => {\n\tconst input = `---\n    /** @deprecated */\nconst deprecated = \"Astro\"\ndeprecated;\nconst hello = \"Astro\"\n---\n`;\n\tconst output = await testJSSourcemap(input, 'deprecated;');\n\n\tassert.equal(output, {\n\t\tline: 4,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/error.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\ntest('svelte error', async () => {\n\tconst input = `---\nimport SvelteOptionalProps from \"./SvelteOptionalProps.svelte\"\n---\n\n<SvelteOptionalProps></SvelteOptionalProps>`;\n\tconst output = await testJSSourcemap(input, '<SvelteOptionalProps>');\n\n\tassert.equal(output, {\n\t\tline: 5,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest('vue error', async () => {\n\tconst input = `---\nimport SvelteError from \"./SvelteError.svelte\"\nimport VueError from \"./VueError.vue\"\n---\n\n<SvelteError></SvelteError>\n<VueError></VueError>`;\n\tconst svelte = await testJSSourcemap(input, '<SvelteError>');\n\n\tassert.equal(svelte, {\n\t\tline: 6,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n\n\tconst vue = await testJSSourcemap(input, '<VueError>');\n\n\tassert.equal(vue, {\n\t\tline: 7,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/frontmatter.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\ntest('frontmatter', async () => {\n\tconst input = `---\nnonexistent\n---\n`;\n\tconst output = await testJSSourcemap(input, 'nonexistent');\n\n\tassert.equal(output, {\n\t\tline: 2,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/hover.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\nconst fixture = `---\n    const MyVariable = \"Astro\"\n\n    /** Documentation */\n    const MyDocumentedVariable = \"Astro\"\n\n    /** @author Astro */\n    const MyJSDocVariable = \"Astro\"\n---\n`;\n\ntest('hover I', async () => {\n\tconst input = fixture;\n\tconst output = await testJSSourcemap(input, 'MyVariable');\n\n\tassert.equal(output, {\n\t\tline: 2,\n\t\tcolumn: 11,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest('hover II', async () => {\n\tconst input = fixture;\n\tconst output = await testJSSourcemap(input, 'MyDocumentedVariable');\n\n\tassert.equal(output, {\n\t\tline: 5,\n\t\tcolumn: 11,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest('hover III', async () => {\n\tconst input = fixture;\n\tconst output = await testJSSourcemap(input, 'MyJSDocVariable');\n\n\tassert.equal(output, {\n\t\tline: 8,\n\t\tcolumn: 11,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/module.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\ntest('script is:inline', async () => {\n\tconst input = `---\n  // valid\n  import { foo } from './script.js';\n    import ComponentAstro from './astro.astro';\n    import ComponentSvelte from './svelte.svelte';\n    import ComponentVue from './vue.vue';\n  // invalid\n  import { baz } from './script';\n  foo;baz;ComponentAstro;ComponentSvelte;ComponentVue;\n---\n`;\n\tconst output = await testJSSourcemap(input, `'./script'`);\n\n\tassert.equal(output, {\n\t\tline: 8,\n\t\tcolumn: 23,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/script.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\ntest('script is:inline', async () => {\n\tconst input = `<script is:inline>\n  const MyNumber = 3;\n  console.log(MyNumber.toStrang());\n</script>\n`;\n\tconst output = await testJSSourcemap(input, '\\n');\n\n\tassert.equal(output, {\n\t\tline: 1,\n\t\tcolumn: 18,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/template.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testJSSourcemap } from '../utils.js';\n\ntest('template expression basic', async () => {\n\tconst input = '<div>{nonexistent}</div>';\n\n\tconst output = await testJSSourcemap(input, 'nonexistent');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 6,\n\t\tname: null,\n\t});\n});\n\ntest('template expression has dot', async () => {\n\tconst input = '<div>{console.log(hey)}</div>';\n\tconst output = await testJSSourcemap(input, 'log');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 14,\n\t\tname: null,\n\t});\n});\n\ntest('template expression with addition', async () => {\n\tconst input = `{\"hello\" + hey}`;\n\tconst output = await testJSSourcemap(input, 'hey');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 11,\n\t\tname: null,\n\t});\n});\n\ntest('html attribute', async () => {\n\tconst input = `<svg color=\"#000\"></svg>`;\n\tconst output = await testJSSourcemap(input, 'color');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 5,\n\t});\n});\n\ntest('complex template expression', async () => {\n\tconst input = `{[].map(ITEM => {\nv = \"what\";\nreturn <div>{ITEMS}</div>\n})}`;\n\tconst item = await testJSSourcemap(input, 'ITEM');\n\tconst items = await testJSSourcemap(input, 'ITEMS');\n\tassert.equal(item, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 8,\n\t});\n\tassert.equal(items, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 3,\n\t\tcolumn: 14,\n\t});\n});\n\ntest('attributes', async () => {\n\tconst input = `<div className=\"hello\" />`;\n\tconst className = await testJSSourcemap(input, 'className');\n\tassert.equal(className, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 5,\n\t});\n});\n\ntest('special attributes', async () => {\n\tconst input = `<div @on.click=\"fn\" />`;\n\tconst onClick = await testJSSourcemap(input, '@on.click');\n\tassert.equal(onClick, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 5,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/js-sourcemaps/windows-linereturns.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\ntest('Windows line returns', async () => {\n\tconst result = await transform(\n\t\t`<div class=\"px-10\">\\r\\n{\\r\\n() => {\\r\\nif (style == Style.Ordered) {\\r\\nreturn items.map((item: string, index: number) => (\\r\\n// index + 1 is needed to start with 1 not 0\\r\\n<p>\\r\\n{index + 1}\\r\\n<Fragment set:html={item} />\\r\\n</p>\\r\\n));\\r\\n} else {\\r\\nreturn items.map((item: string) => (\\r\\n<Fragment set:html={item} />\\r\\n));\\r\\n}\\r\\n}\\r\\n}\\r\\n</div>`,\n\t\t{ sourcemap: 'both', filename: 'index.astro', resolvePath: (i: string) => i }\n\t);\n\tassert.ok(result.code, 'Expected to compile');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/ast.ts",
    "content": "import { type ParseResult, parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { ElementNode } from '../../types.js';\n\nconst FIXTURE = `\n---\nlet value = 'world';\n---\n\n<h1 name=\"value\" empty {shorthand} expression={true} literal=\\`tags\\`>Hello {value}</h1>\n<div></div>\n`;\n\nlet result: ParseResult;\ntest.before(async () => {\n\tresult = await parse(FIXTURE);\n});\n\ntest('ast', () => {\n\tassert.type(result, 'object', `Expected \"parse\" to return an object!`);\n\tassert.equal(result.ast.type, 'root', `Expected \"ast\" root node to be of type \"root\"`);\n});\n\ntest('frontmatter', () => {\n\tconst [frontmatter] = result.ast.children;\n\tassert.equal(\n\t\tfrontmatter.type,\n\t\t'frontmatter',\n\t\t`Expected first child node to be of type \"frontmatter\"`\n\t);\n});\n\ntest('element', () => {\n\tconst [, element] = result.ast.children;\n\tassert.equal(element.type, 'element', `Expected first child node to be of type \"element\"`);\n});\n\ntest('element with no attributes', () => {\n\tconst [, , , element] = result.ast.children as ElementNode[];\n\tassert.equal(element.attributes, [], `Expected the \"attributes\" property to be an empty array`);\n});\n\ntest('element with no children', () => {\n\tconst [, , , element] = result.ast.children as ElementNode[];\n\tassert.equal(element.children, [], `Expected the \"children\" property to be an empty array`);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/client-component-unfound.ts",
    "content": "import { parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `{\n\theaders && (\n\t\t<nav class=\"mobile-toc\">\n\t\t\t<TableOfContents\n\t\t\t\tclient:media=\"(max-width: 72em)\"\n\t\t\t\theaders={headers}\n\t\t\t\tlabels={{ onThisPage: t('rightSidebar.onThisPage'), overview: t('rightSidebar.overview') }}\n\t\t\t\tisMobile={true}\n\t\t\t/>\n\t\t</nav>\n\t)\n}\n`;\n\ntest('unfound client component', async () => {\n\tconst result = await parse(FIXTURE);\n\tassert.ok(result.ast, 'Expected an AST to be generated');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/escaping.ts",
    "content": "import { parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst STYLE = 'div { & span { color: red; }}';\nconst FIXTURE = `<style>${STYLE}</style>`;\n\ntest('ampersand', async () => {\n\tconst result = await parse(FIXTURE);\n\tassert.ok(result.ast, 'Expected an AST to be generated');\n\tconst [\n\t\t{\n\t\t\tchildren: [{ value: output }],\n\t\t},\n\t] = result.ast.children as any;\n\tassert.equal(output, STYLE, 'Expected AST style to equal input');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/fragment.ts",
    "content": "import { type ParseResult, parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { FragmentNode } from '../../types.js';\n\nconst FIXTURE = '<>Hello</><Fragment>World</Fragment>';\n\nlet result: ParseResult;\ntest.before(async () => {\n\tresult = await parse(FIXTURE);\n});\n\ntest('fragment shorthand', () => {\n\tconst [first] = result.ast.children as FragmentNode[];\n\tassert.equal(first.type, 'fragment', 'Expected first child to be of type \"fragment\"');\n\tassert.equal(first.name, '', 'Expected first child to have name of \"\"');\n});\n\ntest('fragment literal', () => {\n\tconst [, second] = result.ast.children as FragmentNode[];\n\tassert.equal(second.type, 'fragment', 'Expected second child to be of type \"fragment\"');\n\tassert.equal(second.name, 'Fragment', 'Expected second child to have name of \"\"');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/literal.ts",
    "content": "import { parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { ElementNode } from '../../types.js';\n\ntest('preserve style tag position I', async () => {\n\tconst input = `<html><body><h1>Hello world!</h1></body></html>\n<style></style>`;\n\tconst { ast } = await parse(input);\n\n\tconst lastChildren = ast.children.at(-1) as ElementNode;\n\n\tassert.equal(lastChildren.type, 'element', 'Expected last child node to be of type \"element\"');\n\tassert.equal(lastChildren.name, 'style', 'Expected last child node to be of type \"style\"');\n});\n\ntest('preserve style tag position II', async () => {\n\tconst input = `<html></html>\n<style></style>`;\n\tconst { ast } = await parse(input);\n\n\tconst lastChildren = ast.children.at(-1) as ElementNode;\n\n\tassert.equal(lastChildren.type, 'element', 'Expected last child node to be of type \"element\"');\n\tassert.equal(lastChildren.name, 'style', 'Expected last child node to be of type \"style\"');\n});\n\ntest('preserve style tag position III', async () => {\n\tconst input = `<html lang=\"en\"><head><BaseHead /></head></html>\n<style>@use \"../styles/global.scss\";</style>`;\n\tconst { ast } = await parse(input);\n\n\tconst lastChildren = ast.children.at(-1) as ElementNode;\n\n\tassert.equal(lastChildren.type, 'element', 'Expected last child node to be of type \"element\"');\n\tassert.equal(lastChildren.name, 'style', 'Expected last child node to be of type \"style\"');\n\tassert.equal(\n\t\tlastChildren.children[0].type,\n\t\t'text',\n\t\t'Expected last child node to be of type \"text\"'\n\t);\n});\n\ntest('preserve style tag position IV', async () => {\n\tconst input = `<html lang=\"en\"><head><BaseHead /></head><body><Header /></body></html>\n<style>@use \"../styles/global.scss\";</style>`;\n\tconst { ast } = await parse(input);\n\n\tconst lastChildren = ast.children.at(-1) as ElementNode;\n\n\tassert.equal(lastChildren.type, 'element', 'Expected last child node to be of type \"element\"');\n\tassert.equal(lastChildren.name, 'style', 'Expected last child node to be of type \"style\"');\n\tassert.equal(\n\t\tlastChildren.children[0].type,\n\t\t'text',\n\t\t'Expected last child node to be of type \"text\"'\n\t);\n});\n\ntest('preserve style tag position V', async () => {\n\tconst input = `<html lang=\"en\"><head><BaseHead /></head><body><Header /></body><style>@use \"../styles/global.scss\";</style></html>`;\n\tconst { ast } = await parse(input);\n\n\tconst firstChild = ast.children.at(0) as ElementNode;\n\tconst lastChild = firstChild.children.at(-1) as ElementNode;\n\n\tassert.equal(lastChild.type, 'element', 'Expected last child node to be of type \"element\"');\n\tassert.equal(lastChild.name, 'style', 'Expected last child node to be of type \"style\"');\n\tassert.equal(lastChild.children[0].type, 'text', 'Expected last child node to be of type \"text\"');\n});\n"
  },
  {
    "path": "packages/compiler/test/parse/multibyte-characters.ts",
    "content": "import { parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = '{foo}，';\n\ntest('does not crash', async () => {\n\tconst result = await parse(FIXTURE);\n\tassert.ok(result.ast, 'does not crash');\n});\n\ntest('properly maps the position', async () => {\n\tconst {\n\t\tast: { children },\n\t} = await parse(FIXTURE);\n\n\tconst text = children[1];\n\tassert.equal(text.position?.start.offset, 5, 'properly maps the text start position');\n\tassert.equal(text.position?.end?.offset, 8, 'properly maps the text end position');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/orphan-head.ts",
    "content": "import { type ParseResult, parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Document</title>\n</head>\n  <body>\n    <h1>\n      Hello world!</h1>\n  </body>\n</html>\n`;\n\nlet result: ParseResult;\ntest.before(async () => {\n\tresult = await parse(FIXTURE);\n});\n\ntest('orphan head', () => {\n\tassert.ok(result, 'able to parse');\n\n\tconst [doctype, html, ...others] = result.ast.children;\n\tassert.equal(others.length, 1, 'Expected only three child nodes!');\n\tassert.equal(doctype.type, 'doctype', `Expected first child node to be of type \"doctype\"`);\n\tassert.equal(html.type, 'element', `Expected first child node to be of type \"element\"`);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/orphan-slot.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport { Code, Markdown } from 'astro/components';\n\nconst {isRequired, description, example} = Astro.props;\n---\n\n<slot />\n{isRequired && <p class=\"mt-16 badge badge-info\">Required</p>}\n{description?.trim() && <Markdown content={description} />}\n{example && <Code code={example} lang='yaml' />}\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('orphan slot', () => {\n\tassert.ok(result.code, 'able to parse');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/position.ts",
    "content": "import { parse } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { ElementNode, FrontmatterNode } from '../../types.js';\n\ntest('include start and end positions', async () => {\n\tconst input = `---\n// Hello world!\n---\n\n<iframe>Hello</iframe><div></div>`;\n\tconst { ast } = await parse(input);\n\n\tconst iframe = ast.children[1] as ElementNode;\n\tassert.is(iframe.name, 'iframe');\n\tassert.ok(iframe.position?.start, 'Expected serialized output to contain a start position');\n\tassert.ok(iframe.position.end, 'Expected serialized output to contain an end position');\n});\n\ntest('include start and end positions for comments', async () => {\n\tconst input = `---\n// Hello world!\n---\n\n<!-- prettier:ignore -->\n<iframe>Hello</iframe><div></div>`;\n\tconst { ast } = await parse(input);\n\n\tconst comment = ast.children[1] as ElementNode;\n\tassert.is(comment.type, 'comment');\n\tassert.ok(comment.position?.start, 'Expected serialized output to contain a start position');\n\tassert.ok(comment.position.end, 'Expected serialized output to contain an end position');\n});\n\ntest('include start and end positions for text', async () => {\n\tconst input = `---\n// Hello world!\n---\n\nHello world!`;\n\tconst { ast } = await parse(input);\n\n\tconst text = ast.children[1] as ElementNode;\n\tassert.is(text.type, 'text');\n\tassert.ok(text.position?.start, 'Expected serialized output to contain a start position');\n\tassert.ok(text.position?.end, 'Expected serialized output to contain an end position');\n});\n\ntest('include start and end positions for self-closing tags', async () => {\n\tconst input = '<input/>';\n\tconst { ast } = await parse(input);\n\n\tconst element = ast.children[0] as ElementNode;\n\tassert.is(element.type, 'element');\n\tassert.is(element.name, 'input');\n\tassert.ok(element.position?.start, 'Expected serialized output to contain a start position');\n\tassert.ok(element.position.end, 'Expected serialized output to contain an end position');\n});\n\ntest('include correct start and end position for self-closing tag', async () => {\n\tconst input = `\n<!-- prettier-ignore -->\n<li />`;\n\tconst { ast } = await parse(input);\n\n\tconst li = ast.children[1] as ElementNode;\n\tassert.is(li.name, 'li');\n\tassert.ok(li.position?.start, 'Expected serialized output to contain a start position');\n\tassert.ok(li.position.end, 'Expected serialized output to contain an end position');\n\n\tassert.equal(\n\t\tli.position.start,\n\t\t{ line: 3, column: 1, offset: 26 },\n\t\t'Expected serialized output to contain a start position'\n\t);\n\tassert.equal(\n\t\tli.position.end,\n\t\t{ line: 3, column: 6, offset: 31 },\n\t\t'Expected serialized output to contain an end position'\n\t);\n});\n\ntest('include correct start and end position for normal closing tag', async () => {\n\tconst input = `\n<!-- prettier-ignore -->\n<li></li>`;\n\tconst { ast } = await parse(input);\n\n\tconst li = ast.children[1] as ElementNode;\n\tassert.is(li.name, 'li');\n\tassert.ok(li.position?.start, 'Expected serialized output to contain a start position');\n\tassert.ok(li.position.end, 'Expected serialized output to contain an end position');\n\n\tassert.equal(\n\t\tli.position.start,\n\t\t{ line: 3, column: 1, offset: 26 },\n\t\t'Expected serialized output to contain a start position'\n\t);\n\tassert.equal(\n\t\tli.position.end,\n\t\t{ line: 3, column: 10, offset: 35 },\n\t\t'Expected serialized output to contain an end position'\n\t);\n});\n\ntest('include start and end position if frontmatter is only thing in file (#802)', async () => {\n\tconst input = `---\n---`;\n\tconst { ast } = await parse(input);\n\n\tconst frontmatter = ast.children[0] as FrontmatterNode;\n\tassert.is(frontmatter.type, 'frontmatter');\n\tassert.ok(frontmatter.position?.start, 'Expected serialized output to contain a start position');\n\tassert.ok(frontmatter.position.end, 'Expected serialized output to contain an end position');\n\n\tassert.equal(\n\t\tfrontmatter.position.start,\n\t\t{ line: 1, column: 1, offset: 0 },\n\t\t'Expected serialized output to contain a start position'\n\t);\n\tassert.equal(\n\t\tfrontmatter.position.end,\n\t\t{ line: 2, column: 4, offset: 7 },\n\t\t'Expected serialized output to contain an end position'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/parse/serialize.ts",
    "content": "import { parse } from '@astrojs/compiler';\nimport { serialize } from '@astrojs/compiler/utils';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `---\nlet value = 'world';\nlet content = \"Testing 123\";\n---\n\n<style>\n  :root {\n    color: red;\n  }\n</style>\n\n<div>Hello {value}</div>\n\n<h1 name=\"value\" set:html={content} empty {shorthand} expression={true} literal=\\`tags\\` {...spread}>Hello {value}</h1>\n\n<Fragment set:html={content} />\n\n<Markdown is:raw>\n  # Hello world!\n</Markdown>\n`;\n\nlet result: string;\ntest.before(async () => {\n\tconst { ast } = await parse(FIXTURE);\n\ttry {\n\t\tresult = serialize(ast);\n\t} catch (e) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.log(e);\n\t}\n});\n\ntest('serialize', () => {\n\tassert.type(result, 'string', `Expected \"serialize\" to return an object!`);\n\tassert.equal(result, FIXTURE, 'Expected serialized output to equal input');\n});\n\ntest('self-close elements', async () => {\n\tconst input = '<div />';\n\tconst { ast } = await parse(input);\n\tconst output = serialize(ast, { selfClose: false });\n\tconst selfClosedOutput = serialize(ast);\n\tassert.equal(output, '<div></div>', 'Expected serialized output to equal <div></div>');\n\tassert.equal(selfClosedOutput, input, `Expected serialized output to equal ${input}`);\n});\n\ntest('raw attributes', async () => {\n\tconst input = `<div name=\"value\" single='quote' un=quote />`;\n\tconst { ast } = await parse(input);\n\tconst output = serialize(ast);\n\tassert.equal(output, input, `Expected serialized output to equal ${input}`);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/resolve-path/preserve.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport Foo from './Foo.jsx'\nimport Bar from './Bar.jsx'\nimport { name } './foo.module.css'\n---\n<Foo />\n<Foo client:load />\n<Foo client:only=\"react\" />\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tresolvePath: async (s) => s,\n\t});\n});\n\ntest('preserve path', () => {\n\tassert.match(result.code, /\"client:load\":true.*\"client:component-path\":\\(\"\\.\\/Foo\\.jsx\"\\)/);\n\tassert.match(result.code, /\"client:only\":\"react\".*\"client:component-path\":\\(\"\\.\\/Foo\\.jsx\"\\)/);\n});\n\ntest('no metadata', () => {\n\tassert.not.match(result.code, /\\$\\$metadata/);\n\tassert.not.match(result.code, /\\$\\$createMetadata/);\n\tassert.not.match(result.code, /createMetadata as \\$\\$createMetadata/);\n\tassert.not.match(result.code, /import \\* as \\$\\$module\\d/);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/scope/same-source.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\n---\n\n<style>\ndiv {\n  background-color: blue;\n  width: 50px;\n  height: 50px;\n}\n</style>\n\n<div />\n`.trim();\n\nfunction grabAstroScope(code: string) {\n\tconst match = /astro-[0-9A-Za-z]+/.exec(code);\n\tif (match) {\n\t\treturn match[0];\n\t}\n\treturn null;\n}\n\ntest('Similar components have different scoped class names', async () => {\n\tlet result = await transform(FIXTURE, {\n\t\tnormalizedFilename: '/src/pages/index.astro',\n\t});\n\tconst scopeA = grabAstroScope(result.code);\n\tassert.ok(scopeA);\n\n\tresult = await transform(FIXTURE, {\n\t\tnormalizedFilename: '/src/pages/two.astro',\n\t});\n\n\tconst scopeB = grabAstroScope(result.code);\n\tassert.ok(scopeB);\n\n\tassert.ok(scopeA !== scopeB, 'The scopes should not match for different files');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/scripts/isinline-hint.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('reports a hint for adding attributes to a script tag without is:inline', async () => {\n\tconst result = await transform(`<script type=\"module\"></script>`);\n\tassert.equal(result.diagnostics[0].severity, 4);\n\tassert.match(result.diagnostics[0].text, /\\#script-processing/);\n});\n\ntest('does not report a diagnostic for the src attribute', async () => {\n\tconst result = await transform(`<script src=\"/external.js\"></script>`);\n\tconsole.log(result.diagnostics);\n\tassert.equal(result.diagnostics.length, 0);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/scripts/order.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('outputs scripts in expected order', async () => {\n\tconst result = await transform(\n\t\t`\n    <script>console.log(1)</script>\n    <script>console.log(2)</script>`\n\t);\n\n\tconst scripts = result.scripts;\n\n\t// for typescript\n\tif (scripts[0].type === 'external') throw new Error('Script is external');\n\tif (scripts[1].type === 'external') throw new Error('Script is external');\n\n\tassert.match(scripts[0].code, 'console.log(1)');\n\tassert.match(scripts[1].code, 'console.log(2)');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/server-islands/meta.ts",
    "content": "import { fileURLToPath } from 'node:url';\nimport { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport Avatar from './Avatar.astro';\nimport {Other} from './Other.astro';\n---\n\n<Avatar server:defer />\n<Other server:defer />\n`;\n\nlet result: Awaited<ReturnType<typeof transform>>;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tresolvePath: async (s: string) => {\n\t\t\tconst out = new URL(s, import.meta.url);\n\t\t\treturn fileURLToPath(out);\n\t\t},\n\t});\n});\n\ntest('component metadata added', () => {\n\tassert.equal(result.serverComponents.length, 2);\n});\n\ntest('component should contain head propagation', () => {\n\tassert.equal(result.propagation, true);\n});\n\ntest('path resolved to the filename', () => {\n\tconst m = result.serverComponents[0];\n\tassert.ok(m.specifier !== m.resolvedPath);\n});\n\ntest('localName is the name used in the template', () => {\n\tassert.equal(result.serverComponents[0].localName, 'Avatar');\n\tassert.equal(result.serverComponents[1].localName, 'Other');\n});\n\ntest('exportName is the export name of the imported module', () => {\n\tassert.equal(result.serverComponents[0].exportName, 'default');\n\tassert.equal(result.serverComponents[1].exportName, 'Other');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/slot-result/result.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nimport Parent from './Parent.astro';\n---\n<Parent>\n  <div></div>\n</Parent>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tresolvePath: async (s) => s,\n\t\tresultScopedSlot: true,\n\t});\n});\n\ntest('resultScopedSlot: includes the result object in the call to the slot', () => {\n\tassert.match(result.code, /\\(\\$\\$result\\) =>/);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/static-extraction/css.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\n---\n<style>\n    .thing { color: green; }\n    .url-space { background: url('/white space.png'); }\n    .escape:not(#\\\\#) { color: red; }\n</style>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('extracts styles', () => {\n\tassert.equal(\n\t\tresult.css.length,\n\t\t1,\n\t\t`Incorrect CSS returned. Expected a length of 1 and got ${result.css.length}`\n\t);\n});\n\ntest('escape url with space', () => {\n\tassert.match(result.css[0], 'background:url(/white\\\\ space.png)');\n});\n\ntest('escape css syntax', () => {\n\tassert.match(result.css[0], ':not(#\\\\#)');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/static-extraction/hoist-expression.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nconst url = 'foo';\n---\n<script type=\"module\" hoist src={url}></script>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE);\n});\n\ntest('logs warning with hoisted expression', () => {\n\tassert.ok(result.code);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/stress/index.ts",
    "content": "import { transform } from '@astrojs/compiler';\n\nasync function run() {\n\tawait transform(\n\t\t`---\nimport CartItems from './CartItems.astro';\n---\n\n<script>\n  document.addEventListener('alpine:init', () => {\n    Alpine.data('initCartDrawer', () => ({\n      open: false,\n      cart: {},\n      getData(data) {\n          if (data.cart) {\n              this.cart = data.cart\n              this.setCartItems();\n          }\n      },\n      cartItems: [],\n      setCartItems() {\n          this.cartItems = this.cart && this.cart.items.sort(function(a,b) { return a.item_id - b.item_id }) || []\n      },\n      deleteItemFromCart(itemId) {\n        var formKey = document.querySelector('input[name=form_key]').value;\n        fetch(BASE_URL+\"checkout/sidebar/removeItem/\", {\n            \"headers\": {\n                \"content-type\": \"application/x-www-form-urlencoded; charset=UTF-8\",\n            },\n            \"body\": \"form_key=\"+ formKey + \"&item_id=\"+itemId,\n            \"method\": \"POST\",\n            \"mode\": \"cors\",\n            \"credentials\": \"include\"\n        }).then(function (response) {\n            if (response.redirected) {\n                window.location.href = response.url;\n            } else if (response.ok) {\n                return response.json();\n            } else {\n                typeof window.dispatchMessages !== \"undefined\" && window.dispatchMessages(\n                    [{\n                        type: \"warning\",\n                        text: \"Could not remove item from quote.\"\n                    }], 5000\n                );\n            }\n        }).then(function (response) {\n            typeof window.dispatchMessages !== \"undefined\" && window.dispatchMessages(\n                [{\n                    type: response.success ? \"success\" : \"error\",\n                    text: response.success\n                        ? \"You removed the item.\"\n                        : response.error_message\n                }], 5000\n            );\n            var reloadCustomerDataEvent = new CustomEvent(\"reload-customer-section-data\");\n            window.dispatchEvent(reloadCustomerDataEvent);\n        });\n      }\n    }))\n  })\n</script>\n\n<section id=\"cart-drawer\"\n         x-data=\"initCartDrawer\"\n         @private-content-loaded.window=\"getData(event.detail.data)\"\n         @toggle-cart.window=\"open=true;\"\n         @keydown.window.escape=\"open=false\"\n>\n  <template x-if=\"cart && cart.summary_count\">\n    <div role=\"dialog\"\n             aria-labelledby=\"cart-drawer-title\"\n             aria-modal=\"true\"\n             @click.outside=\"open = false\"\n             class=\"fixed inset-y-0 right-0 z-30 flex max-w-full\">\n      <div class=\"backdrop\"\n        x-show=\"open\"\n        x-transition:enter=\"ease-in-out duration-500\"\n        x-transition:enter-start=\"opacity-0\"\n        x-transition:enter-end=\"opacity-100\"\n        x-transition:leave=\"ease-in-out duration-500\"\n        x-transition:leave-start=\"opacity-100\"\n        x-transition:leave-end=\"opacity-0\"\n        @click=\"open = false\"\n        aria-label=\"Close panel\">\n      </div>\n      <div class=\"relative w-screen max-w-md shadow-2xl\"\n        x-show=\"open\"\n        x-transition:enter=\"transform transition ease-in-out duration-500 sm:duration-700\"\n        x-transition:enter-start=\"translate-x-full\"\n        x-transition:enter-end=\"translate-x-0\"\n        x-transition:leave=\"transform transition ease-in-out duration-500 sm:duration-700\"\n        x-transition:leave-start=\"translate-x-0\"\n        x-transition:leave-end=\"translate-x-full\"\n      >\n        <div\n          x-show=\"open\"\n          x-transition:enter=\"ease-in-out duration-500\"\n          x-transition:enter-start=\"opacity-0\"\n          x-transition:enter-end=\"opacity-100\"\n          x-transition:leave=\"ease-in-out duration-500\"\n          x-transition:leave-start=\"opacity-100\"\n          x-transition:leave-end=\"opacity-0\" class=\"absolute top-0 right-0 flex p-2 mt-2\"\n        >\n          <button @click=\"open = false;\" aria-label=\"Close panel\"\n                  class=\"p-2 text-gray-300 transition duration-150 ease-in-out hover:text-black\">\n            <svg class=\"w-6 h-6\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n              <path stroke-linecap=\"round\" stroke-linejoin=\"round\"\n                    stroke-width=\"2\" d=\"M6 18L18 6M6 6l12 12\">\n              </path>\n            </svg>\n          </button>\n        </div>\n        <div class=\"flex flex-col h-full py-6 space-y-6 bg-white shadow-xl\">\n          <header class=\"px-4 sm:px-6\">\n              <h2 id=\"cart-drawer-title\" class=\"text-lg font-medium leading-7 text-gray-900\">My Cart</h2>\n          </header>\n        <div class=\"relative grid gap-6 px-4 py-6 overflow-y-auto bg-white border-b\n            sm:gap-8 sm:px-6 border-container\">\n          <template x-for=\"item in cartItems\">\n\n\n            <!-- <CartItems/> -->\n<div class=\"flex items-start p-3 -m-3 space-x-4 transition duration-150\n    ease-in-out rounded-lg hover:bg-gray-100\">\n  <a :href=\"item.product_url\" class=\"w-1/4\">\n    <img\n        :src=\"item.product_image.src\"\n        :width=\"item.product_image.width\"\n        :height=\"item.product_image.height\"\n        loading=\"lazy\"\n    />\n  </a>\n  <div class=\"w-3/4 space-y-2\">\n    <div>\n      <p class=\"text-xl\">\n          <span x-html=\"item.qty\"></span> x <span x-html=\"item.product_name\"></span>\n      </p>\n      <p class=\"text-sm\"><span x-html=\"item.product_sku\"/></p>\n    </div>\n    <template x-for=\"option in item.options\">\n        <div class=\"pt-2\">\n            <p class=\"font-semibold\" x-text=\"option.label + ':'\"></p>\n            <p class=\"text-secondary\" x-html=\"option.value\"></p>\n        </div>\n    </template>\n    <p><span x-html=\"item.product_price\"></span></p>\n    <div class=\"pt-4\">\n      <a :href=\"item.configure_url\"\n          x-show=\"item.product_type !== 'grouped'\"\n          class=\"inline-flex p-2 mr-2 btn btn-primary\">\n          <svg fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\"\n                size=\"16\" class=\"w-5 h-5\">\n              <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\"\n                    d=\"M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536\n                    3.536L6.5 21.036H3v-3.572L16.732 3.732z\">\n              </path>\n          </svg>\n      </a>\n    </div>\n  </div>\n</div>\n\n\n\n          </template>\n        </div>\n        <div class=\"relative grid gap-6 px-4 py-6 bg-white sm:gap-8 sm:px-6\">\n          <div class=\"w-full p-3 -m-3 space-x-4 transition duration-150 ease-in-out rounded-lg\n              hover:bg-gray-100\">\n              <p>Subtotal: <span x-html=\"cart.subtotal\"></span></p>\n          </div>\n          <div class=\"w-full p-3 -m-3 space-x-4 transition duration-150 ease-in-out rounded-lg hover:bg-gray-100\">\n            <a @click.prevent.stop=\"$dispatch('toggle-authentication',\n                {url: 'checkout'});\"\n                href=\"checkout\"\n                class=\"inline-flex btn btn-primary\">\n                Checkout\n            </a>\n            <span>or</span>\n            <a href=\"checkout/cart\"\n                class=\"underline\">\n                View and Edit Cart\n            </a>\n          </div>\n        </div>\n      </div>\n    </div>\n  </template>\n</section>`,\n\t\t{\n\t\t\tsourcemap: true,\n\t\t}\n\t);\n}\n\nconst MAX_CONCURRENT_RENDERS = 25;\nconst MAX_RENDERS = 1e4;\n\nasync function test() {\n\tawait run();\n\tconst promises = [];\n\tconst tests = [];\n\n\tfor (let i = 0; i < MAX_RENDERS; i++) {\n\t\ttests.push(() => {\n\t\t\tif (i % 1000 === 0) {\n\t\t\t\tconsole.log(`Test ${i}`);\n\t\t\t}\n\t\t\treturn run();\n\t\t});\n\t}\n\n\t// Throttle the paths to avoid overloading the CPU with too many tasks.\n\tfor (const ts of throttle(MAX_CONCURRENT_RENDERS, tests)) {\n\t\tfor (const t of ts) {\n\t\t\tpromises.push(t());\n\t\t}\n\t\t// This blocks generating more paths until these 10 complete.\n\t\tawait Promise.all(promises);\n\t\t// This empties the array without allocating a new one.\n\t\tpromises.length = 0;\n\t}\n}\n\n// Throttle the rendering a paths to prevents creating too many Promises on the microtask queue.\nfunction* throttle(max: number, tests: any) {\n\tconst tmp = [];\n\tlet i = 0;\n\tfor (const t of tests) {\n\t\ttmp.push(t);\n\t\tif (i === max) {\n\t\t\tyield tmp;\n\t\t\t// Empties the array, to avoid allocating a new one.\n\t\t\ttmp.length = 0;\n\t\t\ti = 0;\n\t\t} else {\n\t\t\ti++;\n\t\t}\n\t}\n\n\t// If tmp has items in it, that means there were less than {max} paths remaining\n\t// at the end, so we need to yield these too.\n\tif (tmp.length) {\n\t\tyield tmp;\n\t}\n}\n\ntest();\n"
  },
  {
    "path": "packages/compiler/test/styles/define-vars.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { preprocessStyle } from '../utils.js';\n\ntest('does not include define:vars in generated markup', async () => {\n\tconst input = `\n---\nlet color = 'red';\n---\n\n<style lang=\"scss\" define:vars={{ color }}>\n  div {\n    color: var(--color);\n  }\n</style>\n\n<div>Hello world!</div>\n\n<div>Ahhh</div>\n`;\n\tconst result = await transform(input, {\n\t\tpreprocessStyle,\n\t});\n\tassert.ok(!result.code.includes('STYLES'));\n\tassert.equal(result.css.length, 1);\n});\n\ntest('handles style object and define:vars', async () => {\n\tconst input = `\n---\nlet color = 'red';\n---\n\n<div style={{ color: 'var(--color)' }}>Hello world!</div>\n\n<style define:vars={{ color }}></style>\n`;\n\tconst result = await transform(input);\n\tassert.match(result.code, `$$addAttribute([{ color: 'var(--color)' },$$definedVars], \"style\")`);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/styles/emit-scope.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n---\nlet value = 'world';\n---\n\n<style>div { color: red; }</style>\n\n<div>Hello world!</div>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tsourcemap: true,\n\t});\n});\n\ntest('emits a scope', () => {\n\tassert.ok(result.scope, 'Expected to return a scope');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/styles/empty-style.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { preprocessStyle } from '../utils.js';\n\nconst FIXTURE = `\n---\nlet value = 'world';\n---\n\n<style lang=\"scss\"></style>\n\n<div>Hello world!</div>\n\n<div>Ahhh</div>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tsourcemap: true,\n\t\tpreprocessStyle,\n\t});\n});\n\ntest('can compile empty style', () => {\n\tassert.ok(result.code, 'Expected to compile with empty style.');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/styles/hash.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE_A = `\n<style>\n  h1 { color: red; }\n</style>\n\n<h1>Hello world!</h1>\n`;\nconst FIXTURE_B = `\n<style>\n  h1 { color: blue; }\n</style>\n\n<h1>Hello world!</h1>\n`;\nconst FIXTURE_C = `\n<style>\n  h1 { color: red; }\n</style>\n\n<script>console.log(\"Hello world\")</script>\n`;\nconst FIXTURE_D = `\n<style>\n  h1 { color: red; }\n</style>\n\n<script>console.log(\"Hello world!\")</script>\n`;\n\nconst scopes: string[] = [];\ntest.before(async () => {\n\tconst [{ scope: a }, { scope: b }, { scope: c }, { scope: d }] = await Promise.all(\n\t\t[FIXTURE_A, FIXTURE_B, FIXTURE_C, FIXTURE_D].map((source) => transform(source))\n\t);\n\tscopes.push(a, b, c, d);\n});\n\ntest('hash changes when content outside of style change', () => {\n\tconst [, b, c] = scopes;\n\tassert.not.equal(b, c, 'Expected scopes to not be equal');\n});\n\ntest('hash changes when scripts change', () => {\n\tconst [, , c, d] = scopes;\n\tassert.not.equal(c, d, 'Expected scopes to not be equal');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/styles/sass.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { preprocessStyle } from '../utils.js';\n\nconst FIXTURE = `\n---\nlet value = 'world';\n---\n\n<style lang=\"scss\" define:vars={{ a: 0 }}>\n$color: red;\n\ndiv {\n  color: $color;\n}\n</style>\n\n<div>Hello world!</div>\n\n<div>Ahhh</div>\n\n<style lang=\"scss\">\n$color: green;\ndiv {\n  color: $color;\n}\n</style>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tsourcemap: true,\n\t\tpreprocessStyle,\n\t});\n});\n\ntest('transforms scss one', () => {\n\tassert.match(result.css[0], 'color:red', 'Expected \"color:red\" to be present.');\n});\n\ntest('transforms scss two', () => {\n\tassert.match(\n\t\tresult.css[result.css.length - 1],\n\t\t'color:green',\n\t\t'Expected \"color:green\" to be present.'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/table/components.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { parse } from 'acorn';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('allows components in table', async () => {\n\tconst input = `\n---\nconst  MyTableRow = \"tr\";\n---\n\n<table>\n    <MyTableRow>\n        <td>Witch</td>\n    </MyTableRow>\n    <MyTableRow>\n        <td>Moon</td>\n    </MyTableRow>\n</table>\n`;\n\n\tlet error = 0;\n\ttry {\n\t\tconst { code } = await transform(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tparse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\tassert.equal(error, 0, 'compiler should generate valid code');\n});\n"
  },
  {
    "path": "packages/compiler/test/table/expressions.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { parse } from 'acorn';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('allows expressions in table', async () => {\n\tconst input = `\n---\n---\n\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width\" />\n\t\t<meta name=\"generator\" content={Astro.generator} />\n\t\t<title>Astro</title>\n\t</head>\n\t<body>\n    <table>\n      <tbody>\n        {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n      </tbody>\n    </table>\n\t</body>\n</html>\n`;\n\n\tlet error = 0;\n\ttry {\n\t\tconst { code } = await transform(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tparse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n\t\tassert.match(code, '<tr>${num}</tr>');\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\tassert.equal(error, 0, 'compiler should generate valid code');\n});\n\ntest('allows many expressions in table', async () => {\n\tconst input = `\n---\n---\n\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.svg\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width\" />\n\t\t<meta name=\"generator\" content={Astro.generator} />\n\t\t<title>Astro</title>\n\t</head>\n\t<body>\n    <table>\n      <tbody>\n        {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n         {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n         {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n         {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n         {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n         {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n      </tbody>\n    </table>\n\t</body>\n</html>\n`;\n\n\tlet error = 0;\n\ttry {\n\t\tconst { code } = await transform(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tparse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n\t\tassert.match(code, '<tr>${num}</tr>');\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\tassert.equal(error, 0, 'compiler should generate valid code');\n});\n"
  },
  {
    "path": "packages/compiler/test/table/in-expression.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { parse } from 'acorn';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('does not panic on table in expression', async () => {\n\tconst input = `\n<section>\n    {course.reviews && course.reviews.length &&\n        <>\n            <div class=\"py-3\">\n                <hr>\n            </div>\n            <h2 class=\"text-lg font-bold\">รีวิวจากผู้เรียน (ทั้งหมด {course.reviews.length} รีวิว คะแนนเฉลี่ย {course.reviews.reduce((p, c, _, { length }) => p + c.star / length, 0).toFixed(1)})</h2>\n            <table class=\"rounded shadow dark:shadow-none dark:border dark:border-gray-700\">\n                <tbody>\n                {course.reviews.map(review => (\n                    <tr class=\"even:bg-gray-50 dark:even:bg-gray-700\">\n                    <td class=\"p-2 align-top\"><Icon class=\"w-8 h-8 flex-shrink-0\" name=\"mdi:account-circle\"></Icon></td>\n                    <td class=\"p-2 w-full\">\n                        <h3 class=\"whitespace-nowrap font-bold\">{review.name}</h3>\n                        {review.comment && <p class=\"text-sm text-secondary\">{review.comment}</p>}\n                    </td>\n                    <td class=\"p-2 align-top\">{'⭐'.repeat(review.star)}</td>\n                    </tr>\n                ))}\n                </tbody>\n            </table>\n        </>\n    }\n</section>\n`;\n\n\tlet error = 0;\n\ttry {\n\t\tconst { code } = await transform(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tparse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\tassert.equal(error, 0, 'compiler should generate valid code');\n});\n\ntest('does not generate invalid markup on table in expression', async () => {\n\tconst input = `\n<ul>\n    {Astro.props.page.data.map(page =>\n        <li>\n            <table>\n            <tr><td>{page.frontmatter.title}</td></tr>\n            <tr><td>\n                <Debug {...Object.keys(page)} />\n            </td></tr>\n            </table>\n        </li>\n  )}\n</ul>\n`;\n\n\tlet error = 0;\n\ttry {\n\t\tconst { code } = await transform(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tparse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\tassert.equal(error, 0, 'compiler should generate valid code');\n});\n\ntest('does not generate invalid markup on multiple tables', async () => {\n\tconst input = `\n<section>\n  {[\"a\", \"b\", \"c\"].map(char=> {\n    <table>\n      <tbody>\n        {[1, 2, 3].map((num) => (\n          <tr>{num}</tr>\n         ))}\n      </tbody>\n    </table>\n})}\n</section>\n<section></section>\n`;\n\n\tlet error = 0;\n\ttry {\n\t\tconst { code } = await transform(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tparse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\tassert.equal(error, 0, 'compiler should generate valid code');\n});\n"
  },
  {
    "path": "packages/compiler/test/teardown/parse.ts",
    "content": "import { parse, teardown } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = '<div>hello</div>';\n\ntest('parse still works after teardown', async () => {\n\tconst ast1 = await parse(FIXTURE);\n\tassert.ok(ast1);\n\tteardown();\n\t// Make sure `parse` creates a new WASM instance after teardown removed the previous one\n\tconst ast2 = await parse(FIXTURE);\n\tassert.ok(ast2);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/transition/data-astro.ts",
    "content": "import { transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<div data-astro-reload>\n  <a href=\"/\" data-astro-reload>/</a>\n  <form data-astro-reload=\"x\">.</form>\n  <area data-astro-reload/>\n  <svg xmlns=\"http://www.w3.org/2000/svg\"><a data-astro-reload>.</a></svg>\n  <script is:inline data-astro-rerun src=\"some.js\" type=\"module\" />\n  <script is:inline data-astro-rerun>\"Bar\"</script>\n</div>`;\n\ntest('Issues warnings for data-astro-* attributes', async () => {\n\tconst result = await transform(FIXTURE);\n\tassert.equal(result.diagnostics.length, 2);\n\tassert.equal(result.diagnostics[0].code, 2000);\n\tassert.equal(result.diagnostics[1].code, 2010);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/transition/meta.ts",
    "content": "import { type TransformResult, transform } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst FIXTURE = `\n<div transition:animate=\"slide\"></div>\n`;\n\nlet result: TransformResult;\ntest.before(async () => {\n\tresult = await transform(FIXTURE, {\n\t\tresolvePath: async (s) => s,\n\t});\n});\n\ntest('tagged with propagation metadata', () => {\n\tassert.equal(result.propagation, true);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/basic.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\ntest('basic', async () => {\n\tconst input = `\n---\nlet value = 'world';\n---\n\n<h1 name=\"value\" empty {shorthand} expression={true} literal=\\`tags\\`>Hello {value}</h1>\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\nlet value = 'world';\n\n<Fragment>\n<h1 name=\"value\" empty shorthand={shorthand} expression={true} literal={\\`tags\\`}>Hello {value}</h1>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('named export', async () => {\n\tconst input = `\n---\nlet value = 'world';\n---\n\n<h1 name=\"value\" empty {shorthand} expression={true} literal=\\`tags\\`>Hello {value}</h1>\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\nlet value = 'world';\n\n<Fragment>\n<h1 name=\"value\" empty shorthand={shorthand} expression={true} literal={\\`tags\\`}>Hello {value}</h1>\n<div></div>\n\n</Fragment>\nexport default function Test__AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, {\n\t\tfilename: '/Users/nmoo/test.astro',\n\t\tsourcemap: 'external',\n\t});\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('moves @attributes to spread', async () => {\n\tconst input = `<div @click={() => {}} name=\"value\"></div>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<div name=\"value\" {...{\"@click\":(() => {})}}></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('add trailing semicolon to frontmatter', async () => {\n\tconst input = `\n---\nconsole.log(\"hello\")\n---\n\n{hello}\n`;\n\tconst output = `${TSXPrefix}\nconsole.log(\"hello\")\n\n{};<Fragment>\n{hello}\n\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('add trailing semicolon to frontmatter II', async () => {\n\tconst input = `\n---\nconst { hello } = Astro.props\n---\n\n<div class={hello}></div>\n`;\n\tconst output = `${TSXPrefix}\nconst { hello } = Astro.props\n\n{};<Fragment>\n<div class={hello}></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('moves attributes with dots in them to spread', async () => {\n\tconst input = `<div x-on:keyup.shift.enter=\"alert('Astro')\" name=\"value\"></div>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<div name=\"value\" {...{\"x-on:keyup.shift.enter\":\"alert('Astro')\"}}></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('moves attributes that starts with : to spread', async () => {\n\tconst input = `<div :class=\"hey\" name=\"value\"></div>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<div name=\"value\" {...{\":class\":\"hey\"}}></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest(\"Don't move attributes to spread unnecessarily\", async () => {\n\tconst input = `<div 丽dfds_fsfdsfs aria-blarg name=\"value\"></div>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<div 丽dfds_fsfdsfs aria-blarg name=\"value\"></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserves unclosed tags', async () => {\n\tconst input = '<components.';\n\tconst output = `${TSXPrefix}<Fragment>\n<components.\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('template literal attribute', async () => {\n\tconst input = '<div class=`${hello}`></div>';\n\tconst output = `${TSXPrefix}<Fragment>\n<div class={\\`\\${hello}\\`}></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('unclosed tags', async () => {\n\tconst input = `---\nconst myMarkdown = await import('../content/post.md');\n---\n\n<myMarkdown.`;\n\tconst output = `${TSXPrefix}\nconst myMarkdown = await import('../content/post.md');\n\n<Fragment>\n<myMarkdown.\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('unclosed tags II', async () => {\n\tconst input = `---\nconst myMarkdown = await import('../content/post.md');\n---\n\n<myMarkdown.\n`;\n\tconst output = `${TSXPrefix}\nconst myMarkdown = await import('../content/post.md');\n\n<Fragment>\n<myMarkdown.\n\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('spread object', async () => {\n\tconst input = `<DocSearch {...{ lang, labels: { modal, placeholder } }} client:only=\"preact\" />`;\n\tconst output = `${TSXPrefix}<Fragment>\n<DocSearch {...{ lang, labels: { modal, placeholder } }} client:only=\"preact\" />\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('spread object II', async () => {\n\tconst input = `<MainLayout {...Astro.props}>\n</MainLayout>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<MainLayout {...Astro.props}>\n</MainLayout>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('fragment with no name', async () => {\n\tconst input = '<>+0123456789</>';\n\tconst output = `${TSXPrefix}<Fragment>\n<>+0123456789</>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserves spaces in tag', async () => {\n\tconst input = '<Button ></Button>';\n\tconst output = `${TSXPrefix}<Fragment>\n<Button ></Button>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserves spaces after attributes in tag', async () => {\n\tconst input = '<Button a=\"b\" ></Button>';\n\tconst output = `${TSXPrefix}<Fragment>\n<Button a=\"b\" ></Button>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserves spaces in tag', async () => {\n\tconst input = '<Button      >';\n\tconst output = `${TSXPrefix}<Fragment>\n<Button ></Button>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserves line returns in tag by transforming to space', async () => {\n\tconst input = `<Button\n\t>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<Button ></Button>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('fragment with leading linebreak', async () => {\n\tconst input = `\n<>Test123</>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<>Test123</>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/comment-whitespace.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\ntest('preverve whitespace around jsx comments', async () => {\n\tconst input = `{/* @ts-expect-error */}\n<Component prop=\"value\"></Component>\n\n{\n// @ts-expect-error\n}\n<Component prop=\"value\"></Component>\n\n{\n/* @ts-expect-error */\n<Component prop=\"value\"></Component>\n}\n\n{\n// @ts-expect-error\n<Component prop=\"value\"></Component>\n}`;\n\tconst output = `${TSXPrefix}<Fragment>\n{/* @ts-expect-error */}\n<Component prop=\"value\"></Component>\n\n{\n// @ts-expect-error\n}\n<Component prop=\"value\"></Component>\n\n{\n/* @ts-expect-error */\n<Fragment><Component prop=\"value\"></Component></Fragment>\n}\n\n{\n// @ts-expect-error\n<Fragment><Component prop=\"value\"></Component></Fragment>\n}\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/complex-generics.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\nconst input = `---\n// TODO: Due to this issue: https://github.com/withastro/astro/issues/1438, this route can't be in the same folder\n// as the paginated article list is or they'll conflict, so this means our articles URL are \\`/article\\/\\${slug}\\` instead\n// of \\`/articles/\\${slug}\\` (with a s), once that issue is fixed, we'll be able to put it back in the right place\nimport { Article, postProcessArticle } from \"$data/articles\";\nimport type { GetStaticPaths, MDXInstance } from \"$data/shared\";\nimport ArticleLayout from \"$layouts/ArticleLayout.astro\";\nimport { getSlugFromFile } from \"$utils\";\n\nexport const getStaticPaths: GetStaticPaths = async () => {\n  const articles = await Astro.glob<Article>(\"/content/articles/**/*.mdx\");\n  return articles.map((article) => {\n    const augmentedFrontmatter = postProcessArticle(article.frontmatter, article.file);\n\n    return {\n      params: { slug: getSlugFromFile(article.file) },\n      props: { article: { ...article, frontmatter: augmentedFrontmatter } },\n    };\n  });\n};\n\nexport interface Props {\n  article: MDXInstance<Article>;\n}\n\nconst { article } = Astro.props;\n---\n\n<ArticleLayout article={article} />`;\n\ntest('does not panic on complex generics', async () => {\n\tlet error = 0;\n\ttry {\n\t\tawait convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\tassert.equal(error, 0, 'compiler should not have panicked');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/escape.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\ntest('escapes braces in comment', async () => {\n\tconst input = '<!-- {<div>Not JSX!<div/>}-->';\n\tconst output = `${TSXPrefix}<Fragment>\n{/** \\\\\\\\{<div>Not JSX!<div/>\\\\\\\\}*/}\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('always inserts space before comment', async () => {\n\tconst input = '<!--/<div>Error?<div/>-->';\n\tconst output = `${TSXPrefix}<Fragment>\n{/** /<div>Error?<div/>*/}\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('simple escapes star slashes (*/)', async () => {\n\tconst input = '<!--*/<div>Evil comment<div/>-->';\n\tconst output = `${TSXPrefix}<Fragment>\n{/** *\\\\/<div>Evil comment<div/>*/}\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('multiple escapes star slashes (*/)', async () => {\n\tconst input = '<!--***/*/**/*/*/*/<div>Even more evil comment<div/>-->';\n\tconst output = `${TSXPrefix}<Fragment>\n{/** ***\\\\/*\\\\/**\\\\/*\\\\/*\\\\/*\\\\/<div>Even more evil comment<div/>*/}\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('does not escape tag opening unnecessarily', async () => {\n\tconst input = `<div></div>\n<div`;\n\tconst output = `${TSXPrefix}<Fragment>\n<div></div>\n<div\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('does not escape tag opening unnecessarily II', async () => {\n\tconst input = `<div>\n<div\n</div>\n`;\n\tconst output = `${TSXPrefix}<Fragment>\n<div>\n<div div {...{\"<\":true}}>\n</div></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('does not escape tag opening unnecessarily III', async () => {\n\tconst input = '<div>{[].map((something) => <div><Blocknote</div><div><Image</div>)}</div>';\n\tconst output = `${TSXPrefix}<Fragment>\n<div>{[].map((something) => <Fragment><div><Blocknote< div><div><Image< div>)</Image<></div></Blocknote<></div></Fragment>}</div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/line-terminator.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('handles non-standard line terminators', async () => {\n\tconst inputs = [' ', 'something something', 'something  ', '   '];\n\tlet err = 0;\n\tfor (const input of inputs) {\n\t\ttry {\n\t\t\tawait convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\t} catch (e) {\n\t\t\terr = 1;\n\t\t}\n\t}\n\tassert.equal(err, 0, 'did not error');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/literal-style-tag.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\ntest('preserve style tag position I', async () => {\n\tconst input = `<html><body><h1>Hello world!</h1></body></html>\n<style></style>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<html><body><h1>Hello world!</h1></body></html>\n<style></style>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserve style tag position II', async () => {\n\tconst input = `<html></html>\n<style></style>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<html></html>\n<style></style>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserve style tag position III', async () => {\n\tconst input = `<html lang=\"en\"><head><BaseHead /></head></html>\n<style>@use \"../styles/global.scss\";</style>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<html lang=\"en\"><head><BaseHead /></head></html>\n<style>{\\`@use \"../styles/global.scss\";\\`}</style>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserve style tag position IV', async () => {\n\tconst input = `<html lang=\"en\"><head><BaseHead /></head><body><Header /></body></html>\n<style>@use \"../styles/global.scss\";</style>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<html lang=\"en\"><head><BaseHead /></head><body><Header /></body></html>\n<style>{\\`@use \"../styles/global.scss\";\\`}</style>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserve style tag position V', async () => {\n\tconst input = `<html lang=\"en\"><head><BaseHead /></head><body><Header /></body><style>@use \"../styles/global.scss\";</style></html>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<html lang=\"en\"><head><BaseHead /></head><body><Header /></body><style>{\\`@use \"../styles/global.scss\";\\`}</style></html>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/meta.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('return ranges', async () => {\n\tconst input = `---\\nconsole.log(\"Hello!\")\\n---\\n\\n<div></div>`;\n\tconst { metaRanges } = await convertToTSX(input, { sourcemap: 'external' });\n\n\tassert.equal(metaRanges, {\n\t\tfrontmatter: {\n\t\t\tstart: 30,\n\t\t\tend: 54,\n\t\t},\n\t\tbody: {\n\t\t\tstart: 68,\n\t\t\tend: 80,\n\t\t},\n\t\tscripts: null,\n\t\tstyles: null,\n\t});\n});\n\ntest('return ranges - no frontmatter', async () => {\n\tconst input = '<div></div>';\n\tconst { metaRanges } = await convertToTSX(input, { sourcemap: 'external' });\n\n\tassert.equal(metaRanges, {\n\t\tfrontmatter: {\n\t\t\tstart: 30,\n\t\t\tend: 30,\n\t\t},\n\t\tbody: {\n\t\t\tstart: 41,\n\t\t\tend: 53,\n\t\t},\n\t\tscripts: null,\n\t\tstyles: null,\n\t});\n});\n\ntest('return proper ranges with multibyte characters', async () => {\n\tconst input = '---\\n🦄\\n---\\n\\n<div></div>';\n\tconst { metaRanges } = await convertToTSX(input, { sourcemap: 'external' });\n\n\tassert.equal(metaRanges, {\n\t\tfrontmatter: {\n\t\t\tstart: 30,\n\t\t\tend: 35,\n\t\t},\n\t\tbody: {\n\t\t\tstart: 49,\n\t\t\tend: 61,\n\t\t},\n\t\tscripts: null,\n\t\tstyles: null,\n\t});\n});\n\ntest('extract scripts', async () => {\n\tconst input = `<script type=\"module\">console.log({ test: \\`literal\\` })</script><script type=\"text/partytown\">console.log({ test: \\`literal\\` })</script><script type=\"application/ld+json\">{\"a\":\"b\"}</script><script is:inline>console.log(\"hello\")</script><div onload=\"console.log('hey')\"></div><script>console.log({ test: \\`literal\\` })</script><script is:raw>something;</script>`;\n\n\tconst { metaRanges } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.equal(\n\t\tmetaRanges.scripts,\n\t\t[\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 22,\n\t\t\t\t\tend: 54,\n\t\t\t\t},\n\t\t\t\ttype: 'module',\n\t\t\t\tcontent: 'console.log({ test: `literal` })',\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 93,\n\t\t\t\t\tend: 125,\n\t\t\t\t},\n\t\t\t\ttype: 'inline',\n\t\t\t\tcontent: 'console.log({ test: `literal` })',\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 169,\n\t\t\t\t\tend: 178,\n\t\t\t\t},\n\t\t\t\ttype: 'json',\n\t\t\t\tcontent: '{\"a\":\"b\"}',\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 205,\n\t\t\t\t\tend: 225,\n\t\t\t\t},\n\t\t\t\ttype: 'inline',\n\t\t\t\tcontent: 'console.log(\"hello\")',\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 247,\n\t\t\t\t\tend: 266,\n\t\t\t\t},\n\t\t\t\ttype: 'event-attribute',\n\t\t\t\tcontent: \"console.log('hey')\",\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 281,\n\t\t\t\t\tend: 313,\n\t\t\t\t},\n\t\t\t\ttype: 'processed-module',\n\t\t\t\tcontent: 'console.log({ test: `literal` })',\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 337,\n\t\t\t\t\tend: 347,\n\t\t\t\t},\n\t\t\t\ttype: 'raw',\n\t\t\t\tcontent: 'something;',\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t],\n\t\t'expected metaRanges.scripts to match snapshot'\n\t);\n});\n\ntest('extract styles', async () => {\n\tconst input = `<style>body { color: red; }</style><div style=\"color: blue;\"></div><style lang=\"scss\">body { color: red; }</style><style lang=\"pcss\">body { color: red; }</style>`;\n\n\tconst { metaRanges } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.equal(\n\t\tmetaRanges.styles,\n\t\t[\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 7,\n\t\t\t\t\tend: 27,\n\t\t\t\t},\n\t\t\t\ttype: 'tag',\n\t\t\t\tcontent: 'body { color: red; }',\n\t\t\t\tlang: 'css',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 47,\n\t\t\t\t\tend: 60,\n\t\t\t\t},\n\t\t\t\ttype: 'style-attribute',\n\t\t\t\tcontent: 'color: blue;',\n\t\t\t\tlang: 'css',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 86,\n\t\t\t\t\tend: 106,\n\t\t\t\t},\n\t\t\t\ttype: 'tag',\n\t\t\t\tcontent: 'body { color: red; }',\n\t\t\t\tlang: 'scss',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 133,\n\t\t\t\t\tend: 153,\n\t\t\t\t},\n\t\t\t\ttype: 'tag',\n\t\t\t\tcontent: 'body { color: red; }',\n\t\t\t\tlang: 'pcss',\n\t\t\t},\n\t\t],\n\t\t'expected metaRanges.styles to match snapshot'\n\t);\n});\n\ntest('extract scripts and styles with multibyte characters', async () => {\n\tconst scripts = \"<script>console.log('🦄')</script><script>console.log('Hey');</script>\";\n\tconst styles =\n\t\t\"<style>body { background: url('🦄.png'); }</style><style>body { background: url('Hey'); }</style>\";\n\n\tconst input = `${scripts}${styles}`;\n\tconst { metaRanges } = await convertToTSX(input, { sourcemap: 'external' });\n\n\tassert.equal(\n\t\tmetaRanges.scripts,\n\t\t[\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 8,\n\t\t\t\t\tend: 25,\n\t\t\t\t},\n\t\t\t\ttype: 'processed-module',\n\t\t\t\tcontent: \"console.log('🦄')\",\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 42,\n\t\t\t\t\tend: 61,\n\t\t\t\t},\n\t\t\t\ttype: 'processed-module',\n\t\t\t\tcontent: \"console.log('Hey');\",\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t],\n\t\t'expected metaRanges.scripts to match snapshot'\n\t);\n\tassert.equal(\n\t\tmetaRanges.styles,\n\t\t[\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 77,\n\t\t\t\t\tend: 112,\n\t\t\t\t},\n\t\t\t\ttype: 'tag',\n\t\t\t\tcontent: \"body { background: url('🦄.png'); }\",\n\t\t\t\tlang: 'css',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 127,\n\t\t\t\t\tend: 159,\n\t\t\t\t},\n\t\t\t\ttype: 'tag',\n\t\t\t\tcontent: \"body { background: url('Hey'); }\",\n\t\t\t\tlang: 'css',\n\t\t\t},\n\t\t],\n\t\t'expected metaRanges.styles to match snapshot'\n\t);\n});\n\ntest('extract scripts with multibyte characters II', async () => {\n\t// Emojis with various byte lengths (in order, 4, 3, 8, 28) and newlines, a complicated case, if you will\n\tconst input = `🀄✂🇸🇪👩🏻‍❤️‍👩🏽<script>\n\tconsole.log(\"🀄✂🇸🇪👩🏻‍❤️‍👩🏽\");\n</script>🀄✂🇸🇪👩🏻‍❤️‍👩🏽<div onload=\"console.log('🀄✂🇸🇪👩🏻‍❤️‍👩🏽')\"></div>`;\n\n\tconst { metaRanges } = await convertToTSX(input, { sourcemap: 'external' });\n\n\tassert.equal(\n\t\tmetaRanges.scripts,\n\t\t[\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 27,\n\t\t\t\t\tend: 65,\n\t\t\t\t},\n\t\t\t\ttype: 'processed-module',\n\t\t\t\tcontent: '\\n\\tconsole.log(\"🀄✂🇸🇪👩🏻‍❤️‍👩🏽\");\\n',\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tposition: {\n\t\t\t\t\tstart: 106,\n\t\t\t\t\tend: 141,\n\t\t\t\t},\n\t\t\t\ttype: 'event-attribute',\n\t\t\t\tcontent: \"console.log('🀄✂🇸🇪👩🏻‍❤️‍👩🏽')\",\n\t\t\t\tlang: '',\n\t\t\t},\n\t\t],\n\t\t'expected metaRanges.scripts to match snapshot'\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/nested-generics.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('handles plain aliases', async () => {\n\tconst input = `---\ninterface LocalImageProps {}\ntype Props = LocalImageProps;\n---`;\n\tconst output = await convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\tassert.ok(output.code.includes('(_props: Props)'), 'Includes aliased Props as correct props');\n});\n\ntest('handles aliases with nested generics', async () => {\n\tconst input = `---\ninterface LocalImageProps {\n  src: Promise<{ default: string }>;\n}\n\ntype Props = LocalImageProps;\n---`;\n\tconst output = await convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\tassert.ok(output.code.includes('(_props: Props)'), 'Includes aliased Props as correct props');\n});\n\ntest('gracefully handles Image props', async () => {\n\tconst input = `---\ninterface LocalImageProps\n\textends Omit<HTMLAttributes, 'src' | 'width' | 'height'>,\n\t\tOmit<TransformOptions, 'src'>,\n\t\tPick<astroHTML.JSX.ImgHTMLAttributes, 'loading' | 'decoding'> {\n\tsrc: ImageMetadata | Promise<{ default: ImageMetadata }>;\n\t/** Defines an alternative text description of the image. Set to an empty string (alt=\"\") if the image is not a key part of the content (it's decoration or a tracking pixel). */\n\talt: string;\n\tsizes: HTMLImageElement['sizes'];\n\twidths: number[];\n\tformats?: OutputFormat[];\n}\ninterface RemoteImageProps\n\textends Omit<HTMLAttributes, 'src' | 'width' | 'height'>,\n\t\tTransformOptions,\n\t\tPick<ImgHTMLAttributes, 'loading' | 'decoding'> {\n\tsrc: string;\n\t/** Defines an alternative text description of the image. Set to an empty string (alt=\"\") if the image is not a key part of the content (it's decoration or a tracking pixel). */\n\talt: string;\n\tsizes: HTMLImageElement['sizes'];\n\twidths: number[];\n\taspectRatio: TransformOptions['aspectRatio'];\n\tformats?: OutputFormat[];\n\tbackground: TransformOptions['background'];\n}\nexport type Props = LocalImageProps | RemoteImageProps;\n---`;\n\tconst output = await convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\tassert.ok(output.code.includes('(_props: Props)'), 'Includes aliased Props as correct props');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/non-latin.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\n// https://mathiasbynens.be/notes/javascript-identifiers\nconst value = `\n// Let's goooooo 🚀🚀🚀\n\n// How convenient!\nvar π = Math.PI;\n\n// Sometimes, you just have to use the Bad Parts of JavaScript:\nvar ಠ_ಠ = eval;\n\n// Code, Y U NO WORK?!\nvar ლ_ಠ益ಠ_ლ = 42;\n\n// How about a JavaScript library for functional programming?\nvar λ = function() {};\n\n// Obfuscate boring variable names for great justice\nvar \\u006C\\u006F\\u006C\\u0077\\u0061\\u0074 = 'heh';\n\n// …or just make up random ones\nvar Ꙭൽↈⴱ = 'huh';\n\n// Did you know about the [.] syntax?\nvar ᱹ = 1;\nconsole.assert([1, 2, 3][ᱹ] === 2);\n\n// While perfectly valid, this doesn’t work in most browsers:\nvar foo\\u200Cbar = 42;\n\n// This is *not* a bitwise left shift (\\`<<\\`):\nvar 〱〱 = 2;\n// This is, though:\n〱〱 << 〱〱; // 8\n\n// Give yourself a discount:\nvar price_9̶9̶_89 = 'cheap';\n\n// Fun with Roman numerals\nvar Ⅳ = 4;\nvar Ⅴ = 5;\nⅣ + Ⅴ; // 9\n\n// Cthulhu was here\nvar Hͫ̆̒̐ͣ̊̄ͯ͗͏̵̗̻̰̠̬͝ͅE̴̷̬͎̱̘͇͍̾ͦ͊͒͊̓̓̐_̫̠̱̩̭̤͈̑̎̋ͮͩ̒͑̾͋͘Ç̳͕̯̭̱̲̣̠̜͋̍O̴̦̗̯̹̼ͭ̐ͨ̊̈͘͠M̶̝̠̭̭̤̻͓͑̓̊ͣͤ̎͟͠E̢̞̮̹͍̞̳̣ͣͪ͐̈T̡̯̳̭̜̠͕͌̈́̽̿ͤ̿̅̑Ḧ̱̱̺̰̳̹̘̰́̏ͪ̂̽͂̀͠ = 'Zalgo';`;\n\ntest('non-latin characters', async () => {\n\tconst input = `\n---\n${value}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\n${value}\n\n<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/props-and-getStaticPaths.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\nfunction getPrefix({\n\tprops = `ASTRO__MergeUnion<ASTRO__Get<ASTRO__InferredGetStaticPath, 'props'>>`,\n\tcomponent = '__AstroComponent_',\n\tparams = `ASTRO__Get<ASTRO__InferredGetStaticPath, 'params'>`,\n}: {\n\tprops?: string;\n\tcomponent?: string;\n\tparams?: string;\n} = {}) {\n\treturn `/**\n * Astro global available in all contexts in .astro files\n *\n * [Astro documentation](https://docs.astro.build/reference/api-reference/#astro-global)\n*/\ndeclare const Astro: Readonly<import('astro').AstroGlobal<${props}, typeof ${component}${params ? `, ${params}` : ''}>>`;\n}\n\nfunction getSuffix() {\n\treturn `type ASTRO__ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;\ntype ASTRO__Flattened<T> = T extends Array<infer U> ? ASTRO__Flattened<U> : T;\ntype ASTRO__InferredGetStaticPath = ASTRO__Flattened<ASTRO__ArrayElement<Awaited<ReturnType<typeof getStaticPaths>>>>;\ntype ASTRO__MergeUnion<T, K extends PropertyKey = T extends unknown ? keyof T : never> = T extends unknown ? T & { [P in Exclude<K, keyof T>]?: never } extends infer O ? { [P in keyof O]: O[P] } : never : never;\ntype ASTRO__Get<T, K> = T extends undefined ? undefined : K extends keyof T ? T[K] : never;`;\n}\n\ntest('explicit props definition', async () => {\n\tconst input = `---\ninterface Props {};\nexport function getStaticPaths() {\n  return {};\n}\n---\n\n<div></div>`;\n\tconst output = `${TSXPrefix}\\ninterface Props {};\nexport function getStaticPaths() {\n  return {};\n}\n\n{};<Fragment>\n<div></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${getSuffix()}\n${getPrefix({ props: 'Props' })}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('inferred props', async () => {\n\tconst input = `---\nexport function getStaticPaths() {\n  return {};\n}\n---\n\n<div></div>`;\n\tconst output = `${TSXPrefix}\\nexport function getStaticPaths() {\n  return {};\n}\n\n{};<Fragment>\n<div></div>\n</Fragment>\nexport default function __AstroComponent_(_props: ASTRO__MergeUnion<ASTRO__Get<ASTRO__InferredGetStaticPath, 'props'>>): any {}\n${getSuffix()}\n${getPrefix()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/props.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\nconst PREFIX = (component = '__AstroComponent_') => `/**\n * Astro global available in all contexts in .astro files\n *\n * [Astro documentation](https://docs.astro.build/reference/api-reference/#astro-global)\n*/\ndeclare const Astro: Readonly<import('astro').AstroGlobal<Props, typeof ${component}>>`;\n\ntest('no props', async () => {\n\tconst input = '<div></div>';\n\tconst output = `${TSXPrefix}<Fragment>\n<div></div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('nested Props', async () => {\n\tconst input = `---\nfunction DoTheThing(Props) {}\n---`;\n\tconst output = `${TSXPrefix}\nfunction DoTheThing(Props) {}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props interface', async () => {\n\tconst input = `\n---\ninterface Props {}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props {}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props import', async () => {\n\tconst input = `\n---\nimport { Props } from './somewhere';\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\nimport { Props } from './somewhere';\n\n<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props alias', async () => {\n\tconst input = `\n---\nimport { MyComponent as Props } from './somewhere';\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\nimport { MyComponent as Props } from './somewhere';\n\n<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props type import', async () => {\n\tconst input = `\n---\nimport type { Props } from './somewhere';\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\nimport type { Props } from './somewhere';\n\n<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props type', async () => {\n\tconst input = `\n---\ntype Props = {}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ntype Props = {}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function Test__AstroComponent_(_props: Props): any {}\n${PREFIX('Test__AstroComponent_')}`;\n\tconst { code } = await convertToTSX(input, {\n\t\tfilename: '/Users/nmoo/test.astro',\n\t\tsourcemap: 'external',\n\t});\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props generic (simple)', async () => {\n\tconst input = `\n---\ninterface Props<T> {}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props<T> {}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_<T>(_props: Props<T>): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props generic (complex)', async () => {\n\tconst input = `\n---\ninterface Props<T extends Other<{ [key: string]: any }>> {}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props<T extends Other<{ [key: string]: any }>> {}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_<T extends Other<{ [key: string]: any }>>(_props: Props<T>): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props generic (very complex)', async () => {\n\tconst input = `\n---\ninterface Props<T extends { [key: string]: any }, P extends string ? { [key: string]: any }: never> {}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props<T extends { [key: string]: any }, P extends string ? { [key: string]: any }: never> {}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_<T extends { [key: string]: any }, P extends string ? { [key: string]: any }: never>(_props: Props<T, P>): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props generic (very complex II)', async () => {\n\tconst input = `\n---\ninterface Props<T extends Something<false> ? A : B, P extends string ? { [key: string]: any }: never> {}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props<T extends Something<false> ? A : B, P extends string ? { [key: string]: any }: never> {}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_<T extends Something<false> ? A : B, P extends string ? { [key: string]: any }: never>(_props: Props<T, P>): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('polymorphic props', async () => {\n\tconst input = `\n---\ninterface Props<Tag extends keyof JSX.IntrinsicElements> extends HTMLAttributes<Tag> {\n  as?: Tag;\n}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props<Tag extends keyof JSX.IntrinsicElements> extends HTMLAttributes<Tag> {\n  as?: Tag;\n}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_<Tag extends keyof JSX.IntrinsicElements>(_props: Props<Tag>): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('unrelated prop import', async () => {\n\tconst input = `\n---\nimport SvelteOptionalProps from './SvelteOptionalProps.svelte';\n---\n\n<SvelteOptionalProps />\n`;\n\tconst output = `${TSXPrefix}\nimport SvelteOptionalProps from './SvelteOptionalProps.svelte';\n\n<Fragment>\n<SvelteOptionalProps />\n\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('unrelated sibling prop', async () => {\n\tconst input = `---\nimport type { Props as ComponentBProps } from './ComponentB.astro'\n---\n\n<div />\n`;\n\tconst output = `${TSXPrefix}\nimport type { Props as ComponentBProps } from './ComponentB.astro'\n\n{};<Fragment>\n<div />\n\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props interface with as property', async () => {\n\tconst input = `---\ninterface Props {\n  as?: string;\n  href?: string;\n}\n---\n\n<div></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props {\n  as?: string;\n  href?: string;\n}\n\n{};<Fragment>\n<div></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props with destructured as property', async () => {\n\tconst input = `---\ninterface Props {\n  as?: string;\n  className?: string;\n}\n\nconst { as, className } = Astro.props;\n---\n\n<div class={className}>{as}</div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props {\n  as?: string;\n  className?: string;\n}\n\nconst { as, className } = Astro.props;\n\n<Fragment>\n<div class={className}>{as}</div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props with renamed as property in destructuring', async () => {\n\tconst input = `---\ninterface Props {\n  as?: string;\n}\n\nconst { as: element } = Astro.props;\n---\n\n<div>{element}</div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props {\n  as?: string;\n}\n\nconst { as: element } = Astro.props;\n\n<Fragment>\n<div>{element}</div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props interface with as and other properties', async () => {\n\tconst input = `---\ninterface Props extends HTMLAttributes<'div'> {\n  as?: keyof HTMLElementTagNameMap;\n  variant?: 'primary' | 'secondary';\n  size?: 'sm' | 'md' | 'lg';\n}\n\nconst { as = 'div', variant = 'primary', size = 'md', ...rest } = Astro.props;\n---\n\n<div data-variant={variant} data-size={size}></div>\n`;\n\tconst output = `${TSXPrefix}\ninterface Props extends HTMLAttributes<'div'> {\n  as?: keyof HTMLElementTagNameMap;\n  variant?: 'primary' | 'secondary';\n  size?: 'sm' | 'md' | 'lg';\n}\n\nconst { as = 'div', variant = 'primary', size = 'md', ...rest } = Astro.props;\n\n<Fragment>\n<div data-variant={variant} data-size={size}></div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('props type alias with as property', async () => {\n\tconst input = `---\ntype Props = {\n  as?: string;\n  children?: any;\n}\n\nconst props = Astro.props as Props;\n---\n\n<div>{props.children}</div>\n`;\n\tconst output = `${TSXPrefix}\ntype Props = {\n  as?: string;\n  children?: any;\n}\n\nconst props = Astro.props as Props;\n\n<Fragment>\n<div>{props.children}</div>\n\n</Fragment>\nexport default function __AstroComponent_(_props: Props): any {}\n${PREFIX()}`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/raw.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\ntest('style is raw', async () => {\n\tconst input = '<style>div { color: red; }</style>';\n\tconst output = `${TSXPrefix}<Fragment>\n<style>{\\`div { color: red; }\\`}</style>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('is:raw is raw', async () => {\n\tconst input = '<div is:raw>A{B}C</div>';\n\tconst output = `${TSXPrefix}<Fragment>\n<div is:raw>{\\`A{B}C\\`}</div>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/script.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\ntest('script function', async () => {\n\tconst input = `<script type=\"module\">console.log({ test: \\`literal\\` })</script>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<script type=\"module\">\n{() => {console.log({ test: \\`literal\\` })}}\n</script>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('partytown function', async () => {\n\tconst input = `<script type=\"text/partytown\">console.log({ test: \\`literal\\` })</script>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<script type=\"text/partytown\">\n{() => {console.log({ test: \\`literal\\` })}}\n</script>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('ld+json wrapping', async () => {\n\tconst input = `<script type=\"application/ld+json\">{\"a\":\"b\"}</script>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<script type=\"application/ld+json\">{\\`{\"a\":\"b\"}\\`}</script>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('escape unknown types', async () => {\n\tconst input = `<script type=\"text/somethigndf\" is:inline>console.log(\"something\");</script>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<script type=\"text/somethigndf\" is:inline>{\\`console.log(\"something\");\\`}</script>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest(\"don't include scripts if disabled\", async () => {\n\tconst input = `\n<script>hello;</script>\n<script type=\"module\">hello;</script>\n<script type=\"text/partytown\">hello;</script>\n<script type=\"application/ld+json\">hello;</script>\n<script type=\"text/somethigndf\" is:inline>hello;</script>`;\n\tconst output = `${TSXPrefix}<Fragment>\n<script></script>\n<script type=\"module\"></script>\n<script type=\"text/partytown\"></script>\n<script type=\"application/ld+json\"></script>\n<script type=\"text/somethigndf\" is:inline></script>\n</Fragment>\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external', includeScripts: false });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx/top-level-returns.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { TSXPrefix } from '../utils.js';\n\ntest('transforms top-level returns to throw statements', async () => {\n\tconst input = `---\nif (something) {\n\treturn Astro.redirect();\n}\n\nfunction thatDoesSomething() {\n\treturn \"Hey\";\n}\n\nclass Component {\n\trender() {\n\t\treturn \"wow\"!\n\t}\n}\n---`;\n\tconst output = `${TSXPrefix}\nif (something) {\n\tthrow  Astro.redirect();\n}\n\nfunction thatDoesSomething() {\n\treturn \"Hey\";\n}\n\nclass Component {\n\trender() {\n\t\treturn \"wow\"!\n\t}\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserves returns inside arrow functions', async () => {\n\tconst input = `---\nconst foo = () => {\n\treturn \"value\";\n}\n\nif (condition) {\n\treturn Astro.redirect(\"/login\");\n}\n---`;\n\tconst output = `${TSXPrefix}\nconst foo = () => {\n\treturn \"value\";\n}\n\nif (condition) {\n\tthrow  Astro.redirect(\"/login\");\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('preserves returns inside object methods', async () => {\n\tconst input = `---\nconst something = {\n\tsomeFunction: () => {\n\t\treturn \"Hello World\";\n\t},\n\tsomeOtherFunction() {\n\t\treturn \"Hello World\";\n\t},\n};\n\nif (true) {\n\treturn Astro.redirect();\n}\n---`;\n\tconst output = `${TSXPrefix}\nconst something = {\n\tsomeFunction: () => {\n\t\treturn \"Hello World\";\n\t},\n\tsomeOtherFunction() {\n\t\treturn \"Hello World\";\n\t},\n};\n\nif (true) {\n\tthrow  Astro.redirect();\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('handles multiple top-level returns', async () => {\n\tconst input = `---\nif (condition1) {\n\treturn Astro.redirect(\"/a\");\n}\n\nif (condition2) {\n\treturn Astro.redirect(\"/b\");\n}\n---`;\n\tconst output = `${TSXPrefix}\nif (condition1) {\n\tthrow  Astro.redirect(\"/a\");\n}\n\nif (condition2) {\n\tthrow  Astro.redirect(\"/b\");\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('no transformation when no top-level returns', async () => {\n\tconst input = `---\nfunction foo() {\n\treturn \"bar\";\n}\n\nconst arrow = () => {\n\treturn \"baz\";\n}\n---`;\n\tconst output = `${TSXPrefix}\nfunction foo() {\n\treturn \"bar\";\n}\n\nconst arrow = () => {\n\treturn \"baz\";\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('handles TypeScript syntax without losing returns', async () => {\n\tconst input = `---\ntype Response = { status: number };\nconst handler = (input: string): Response => {\n\treturn { status: 200 };\n};\n\nconst value = (foo as string);\n\nif (value) {\n\treturn Astro.redirect('/ok');\n}\n---`;\n\tconst output = `${TSXPrefix}\ntype Response = { status: number };\nconst handler = (input: string): Response => {\n\treturn { status: 200 };\n};\n\nconst value = (foo as string);\n\nif (value) {\n\tthrow  Astro.redirect('/ok');\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('does not transform returns in nested class or object methods', async () => {\n\tconst input = `---\nclass Foo {\n\tmethod() {\n\t\treturn 'foo';\n\t}\n\tarrow = () => {\n\t\treturn 'bar';\n\t}\n}\n\nconst obj = {\n\tmethod() {\n\t\treturn 'baz';\n\t},\n};\n\nif (true) {\n\treturn Astro.redirect('/nested');\n}\n---`;\n\tconst output = `${TSXPrefix}\nclass Foo {\n\tmethod() {\n\t\treturn 'foo';\n\t}\n\tarrow = () => {\n\t\treturn 'bar';\n\t}\n}\n\nconst obj = {\n\tmethod() {\n\t\treturn 'baz';\n\t},\n};\n\nif (true) {\n\tthrow  Astro.redirect('/nested');\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('handles computed methods and generic arrows', async () => {\n\tconst input = `---\nclass Foo {\n\t['get']() {\n\t\treturn 'ok';\n\t}\n\n\tstatic ['load']() {\n\t\treturn 'static';\n\t}\n}\n\nconst obj = {\n\t['get']() {\n\t\treturn 'obj';\n\t},\n};\n\nconst generic = <T,>(value: T) => {\n\treturn value;\n};\n\nif (true) {\n\treturn Astro.redirect('/computed');\n}\n---`;\n\tconst output = `${TSXPrefix}\nclass Foo {\n\t['get']() {\n\t\treturn 'ok';\n\t}\n\n\tstatic ['load']() {\n\t\treturn 'static';\n\t}\n}\n\nconst obj = {\n\t['get']() {\n\t\treturn 'obj';\n\t},\n};\n\nconst generic = <T,>(value: T) => {\n\treturn value;\n};\n\nif (true) {\n\tthrow  Astro.redirect('/computed');\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('handles satisfies and as const in top-level conditionals', async () => {\n\tconst input = `---\nconst config = {\n\tflag: true,\n} as const;\n\nconst map = {\n\tname: 'astro',\n} satisfies Record<string, string>;\n\nif (config.flag) {\n\treturn Astro.redirect('/satisfies');\n}\n---`;\n\tconst output = `${TSXPrefix}\nconst config = {\n\tflag: true,\n} as const;\n\nconst map = {\n\tname: 'astro',\n} satisfies Record<string, string>;\n\nif (config.flag) {\n\tthrow  Astro.redirect('/satisfies');\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest('handles type-position arrows without missing top-level returns', async () => {\n\tconst input = `---\ntype Fn = () => void;\ntype Factory = (value: string) => { ok: boolean };\n\nif (true) {\n\treturn Astro.redirect('/types');\n}\n---`;\n\tconst output = `${TSXPrefix}\ntype Fn = () => void;\ntype Factory = (value: string) => { ok: boolean };\n\nif (true) {\n\tthrow  Astro.redirect('/types');\n}\n\n\nexport default function __AstroComponent_(_props: Record<string, any>): any {}\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'external' });\n\tassert.snapshot(code, output, 'expected code to match snapshot');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-errors/eof.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { TSXResult } from '../../types.js';\n\nconst FIXTURE = `<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    <div>\n      {/*\n    </div>\n  </body>\n</html>`;\n\nlet result: TSXResult;\ntest.before(async () => {\n\tresult = await convertToTSX(FIXTURE, {\n\t\tfilename: '/src/components/EOF.astro',\n\t});\n});\n\ntest('got a tokenizer error', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(result.diagnostics[0].text, 'Unterminated comment');\n\tassert.is(FIXTURE.split('\\n')[result.diagnostics[0].location.line - 1], '      {/*');\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-errors/fragment-shorthand.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { TSXResult } from '../../types.js';\n\nconst FIXTURE = `<html>\n  <head>\n    <title>Hello world</title>\n  </head>\n  <body>\n    < data-test=\"hello\"><div></div></>\n  </body>\n</html>`;\n\nlet result: TSXResult;\ntest.before(async () => {\n\tresult = await convertToTSX(FIXTURE, {\n\t\tfilename: '/src/components/fragment.astro',\n\t});\n});\n\ntest('got a tokenizer error', () => {\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 1);\n\tassert.is(\n\t\tresult.diagnostics[0].text,\n\t\t'Unable to assign attributes when using <> Fragment shorthand syntax!'\n\t);\n\tconst loc = result.diagnostics[0].location;\n\tassert.is(FIXTURE.split('\\n')[loc.line - 1], `    < data-test=\"hello\"><div></div></>`);\n\tassert.is(\n\t\tFIXTURE.split('\\n')[loc.line - 1].slice(loc.column - 1, loc.column - 1 + loc.length),\n\t\t`< data-test=\"hello\">`\n\t);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-errors/unfinished-component.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport type { TSXResult } from '../../types.js';\n\nconst FIXTURE = '<div class={';\n\nlet result: TSXResult;\ntest.before(async () => {\n\tresult = await convertToTSX(FIXTURE, {\n\t\tfilename: '/src/components/unfinished.astro',\n\t});\n});\n\ntest('did not crash on unfinished component', () => {\n\tassert.ok(result);\n\tassert.ok(Array.isArray(result.diagnostics));\n\tassert.is(result.diagnostics.length, 0);\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/404.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('404 generates a valid identifier', async () => {\n\tconst input = '<div {name} />';\n\n\tconst output = await convertToTSX(input, { filename: '404.astro', sourcemap: 'inline' });\n\tassert.match(output.code, 'export default function __AstroComponent_');\n});\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/attributes.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('shorthand attribute', async () => {\n\tconst input = '<div {name} />';\n\n\tconst output = await testTSXSourcemap(input, 'name');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 6,\n\t\tname: null,\n\t});\n});\n\ntest('empty quoted attribute', async () => {\n\tconst input = `<div src=\"\" />`;\n\n\tconst open = await testTSXSourcemap(input, '\"');\n\tassert.equal(open, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 9,\n\t\tname: null,\n\t});\n});\n\ntest('template literal attribute', async () => {\n\tconst input = `---\n---\n<Tag src=\\`bar\\${foo}\\` />`;\n\n\tconst open = await testTSXSourcemap(input, 'foo');\n\tassert.equal(open, {\n\t\tsource: 'index.astro',\n\t\tline: 3,\n\t\tcolumn: 16,\n\t\tname: null,\n\t});\n});\n\ntest('multiline quoted attribute', async () => {\n\tconst input = `<path d=\"M 0\nC100 0\nZ\" />`;\n\n\tconst output = await testTSXSourcemap(input, 'Z');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 3,\n\t\tcolumn: 1,\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/deprecated.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('script is:inline', async () => {\n\tconst input = `---\n    /** @deprecated */\nconst deprecated = \"Astro\"\ndeprecated;\nconst hello = \"Astro\"\n---\n`;\n\tconst output = await testTSXSourcemap(input, 'deprecated;');\n\n\tassert.equal(output, {\n\t\tline: 4,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/error.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('svelte error', async () => {\n\tconst input = `---\nimport SvelteOptionalProps from \"./SvelteOptionalProps.svelte\"\n---\n\n<SvelteOptionalProps></SvelteOptionalProps>`;\n\tconst output = await testTSXSourcemap(input, '<SvelteOptionalProps>');\n\n\tassert.equal(output, {\n\t\tline: 5,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest('vue error', async () => {\n\tconst input = `---\nimport SvelteError from \"./SvelteError.svelte\"\nimport VueError from \"./VueError.vue\"\n---\n\n<SvelteError></SvelteError>\n<VueError></VueError>`;\n\tconst svelte = await testTSXSourcemap(input, '<SvelteError>');\n\n\tassert.equal(svelte, {\n\t\tline: 6,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n\n\tconst vue = await testTSXSourcemap(input, '<VueError>');\n\n\tassert.equal(vue, {\n\t\tline: 7,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/frontmatter.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('frontmatter', async () => {\n\tconst input = `---\nnonexistent\n---\n`;\n\tconst output = await testTSXSourcemap(input, 'nonexistent');\n\n\tassert.equal(output, {\n\t\tline: 2,\n\t\tcolumn: 1,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/hover.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\nconst fixture = `---\n    const MyVariable = \"Astro\"\n\n    /** Documentation */\n    const MyDocumentedVariable = \"Astro\"\n\n    /** @author Astro */\n    const MyJSDocVariable = \"Astro\"\n---\n`;\n\ntest('hover I', async () => {\n\tconst input = fixture;\n\tconst output = await testTSXSourcemap(input, 'MyVariable');\n\n\tassert.equal(output, {\n\t\tline: 2,\n\t\tcolumn: 11,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest('hover II', async () => {\n\tconst input = fixture;\n\tconst output = await testTSXSourcemap(input, 'MyDocumentedVariable');\n\n\tassert.equal(output, {\n\t\tline: 5,\n\t\tcolumn: 11,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest('hover III', async () => {\n\tconst input = fixture;\n\tconst output = await testTSXSourcemap(input, 'MyJSDocVariable');\n\n\tassert.equal(output, {\n\t\tline: 8,\n\t\tcolumn: 11,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/module.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('script is:inline', async () => {\n\tconst input = `---\n  // valid\n  import { foo } from './script.js';\n    import ComponentAstro from './astro.astro';\n    import ComponentSvelte from './svelte.svelte';\n    import ComponentVue from './vue.vue';\n  // invalid\n  import { baz } from './script';\n  foo;baz;ComponentAstro;ComponentSvelte;ComponentVue;\n---\n`;\n\tconst output = await testTSXSourcemap(input, `'./script'`);\n\n\tassert.equal(output, {\n\t\tline: 8,\n\t\tcolumn: 23,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/multibyte.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('multibyte content', async () => {\n\tconst input = '<h1>ツ</h1>';\n\n\tconst output = await testTSXSourcemap(input, 'ツ');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 4,\n\t\tname: null,\n\t});\n});\n\ntest('content after multibyte character', async () => {\n\tconst input = '<h1>ツ</h1><p>foobar</p>';\n\n\tconst output = await testTSXSourcemap(input, 'foobar');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 13,\n\t\tname: null,\n\t});\n});\n\ntest('many characters', async () => {\n\tconst input = '<h1>こんにちは</h1>';\n\n\tconst output = await testTSXSourcemap(input, 'ん');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 5,\n\t\tname: null,\n\t});\n});\n\ntest('many characters', async () => {\n\tconst input = '<h1>こんにちは</h1>';\n\n\tconst output = await testTSXSourcemap(input, 'に');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 6,\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/script.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('script is:inline', async () => {\n\tconst input = `<script is:inline>\n  const MyNumber = 3;\n  console.log(MyNumber.toStrang());\n</script>\n`;\n\tconst output = await testTSXSourcemap(input, '\\n');\n\n\tassert.equal(output, {\n\t\tline: 1,\n\t\tcolumn: 18,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/tags.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { TraceMap, generatedPositionFor } from '@jridgewell/trace-mapping';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('tag close', async () => {\n\tconst input = '<Hello></Hello>';\n\tconst output = await testTSXSourcemap(input, '>');\n\n\tassert.equal(output, {\n\t\tline: 1,\n\t\tcolumn: 6,\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t});\n});\n\ntest('tag with spaces', async () => {\n\tconst input = '<Button      ></Button>';\n\tconst { map } = await convertToTSX(input, { sourcemap: 'both', filename: 'index.astro' });\n\tconst tracer = new TraceMap(map as any);\n\n\tconst generated = generatedPositionFor(tracer, { source: 'index.astro', line: 1, column: 14 });\n\n\tassert.equal(generated, {\n\t\tline: 4,\n\t\tcolumn: 9,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/template-windows.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('last character does not end up in middle of CRLF', async () => {\n\tconst input = \"---\\r\\nimport { Meta } from '$lib/components/Meta.astro';\\r\\n---\\r\\n\";\n\tconst output = await testTSXSourcemap(input, ';');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 2,\n\t\tcolumn: 50,\n\t\tname: null,\n\t});\n});\n\ntest('template expression basic', async () => {\n\tconst input = '<div>{\\r\\nnonexistent\\r\\n}</div>';\n\n\tconst output = await testTSXSourcemap(input, 'nonexistent');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 2,\n\t\tcolumn: 1,\n\t\tname: null,\n\t});\n});\n\ntest('template expression has dot', async () => {\n\tconst input = '<div>{\\nconsole.log(hey)\\n}</div>';\n\tconst output = await testTSXSourcemap(input, 'log');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 2,\n\t\tcolumn: 9,\n\t\tname: null,\n\t});\n});\n\ntest('template expression has dot', async () => {\n\tconst input = '<div>{\\r\\nconsole.log(hey)\\r\\n}</div>';\n\tconst output = await testTSXSourcemap(input, 'log');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 2,\n\t\tcolumn: 9,\n\t\tname: null,\n\t});\n});\n\ntest('template expression with addition', async () => {\n\tconst input = `{\"hello\" + \\nhey}`;\n\tconst output = await testTSXSourcemap(input, 'hey');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 2,\n\t\tcolumn: 1,\n\t\tname: null,\n\t});\n});\n\ntest('template expression with addition', async () => {\n\tconst input = `{\"hello\" + \\r\\nhey}`;\n\tconst output = await testTSXSourcemap(input, 'hey');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 2,\n\t\tcolumn: 1,\n\t\tname: null,\n\t});\n});\n\ntest('html attribute', async () => {\n\tconst input = `<svg\\nvalue=\"foo\" color=\"#000\"></svg>`;\n\tconst output = await testTSXSourcemap(input, 'color');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 2,\n\t\tcolumn: 12,\n\t});\n});\n\ntest('html attribute', async () => {\n\tconst input = `<svg\\r\\nvalue=\"foo\" color=\"#000\"></svg>`;\n\tconst output = await testTSXSourcemap(input, 'color');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 2,\n\t\tcolumn: 12,\n\t});\n});\n\ntest('complex template expression', async () => {\n\tconst input = `{[].map(ITEM => {\\r\\nv = \"what\";\\r\\nreturn <div>{ITEMS}</div>\\r\\n})}`;\n\tconst item = await testTSXSourcemap(input, 'ITEM');\n\tconst items = await testTSXSourcemap(input, 'ITEMS');\n\tassert.equal(item, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 8,\n\t});\n\tassert.equal(items, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 3,\n\t\tcolumn: 14,\n\t});\n});\n\ntest('attributes', async () => {\n\tconst input = `<div\\r\\na=\"b\" className=\"hello\" />`;\n\tconst className = await testTSXSourcemap(input, 'className');\n\tassert.equal(className, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 2,\n\t\tcolumn: 6,\n\t});\n});\n\ntest('special attributes', async () => {\n\tconst input = `<div\\r\\na=\"b\" @on.click=\"fn\" />`;\n\tconst onClick = await testTSXSourcemap(input, '@on.click');\n\tassert.equal(onClick, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 2,\n\t\tcolumn: 6,\n\t});\n});\n\ntest('whitespace', async () => {\n\tconst input = `---\\r\\nimport A from \"a\";\\r\\n\\timport B from \"b\";\\r\\n---\\r\\n`;\n\tconst { code } = await convertToTSX(input, { sourcemap: 'both', filename: 'index.astro' });\n\tassert.match(code, '\\t', 'output includes \\\\t');\n\n\tconst B = await testTSXSourcemap(input, 'B');\n\tassert.equal(B, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 3,\n\t\tcolumn: 9,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/template.ts",
    "content": "import { test } from 'uvu';\nimport * as assert from 'uvu/assert';\nimport { testTSXSourcemap } from '../utils.js';\n\ntest('template expression basic', async () => {\n\tconst input = '<div>{nonexistent}</div>';\n\n\tconst output = await testTSXSourcemap(input, 'nonexistent');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 6,\n\t\tname: null,\n\t});\n});\n\ntest('template expression has dot', async () => {\n\tconst input = '<div>{console.log(hey)}</div>';\n\tconst output = await testTSXSourcemap(input, 'log');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 14,\n\t\tname: null,\n\t});\n});\n\ntest('template expression with addition', async () => {\n\tconst input = `{\"hello\" + hey}`;\n\tconst output = await testTSXSourcemap(input, 'hey');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tline: 1,\n\t\tcolumn: 11,\n\t\tname: null,\n\t});\n});\n\ntest('html attribute', async () => {\n\tconst input = `<svg color=\"#000\"></svg>`;\n\tconst output = await testTSXSourcemap(input, 'color');\n\tassert.equal(output, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 5,\n\t});\n});\n\ntest('complex template expression', async () => {\n\tconst input = `{[].map(ITEM => {\nv = \"what\";\nreturn <div>{ITEMS}</div>\n})}`;\n\tconst item = await testTSXSourcemap(input, 'ITEM');\n\tconst items = await testTSXSourcemap(input, 'ITEMS');\n\tassert.equal(item, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 8,\n\t});\n\tassert.equal(items, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 3,\n\t\tcolumn: 14,\n\t});\n});\n\ntest('attributes', async () => {\n\tconst input = `<div className=\"hello\" />`;\n\tconst className = await testTSXSourcemap(input, 'className');\n\tassert.equal(className, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 5,\n\t});\n});\n\ntest('special attributes', async () => {\n\tconst input = `<div @on.click=\"fn\" />`;\n\tconst onClick = await testTSXSourcemap(input, '@on.click');\n\tassert.equal(onClick, {\n\t\tsource: 'index.astro',\n\t\tname: null,\n\t\tline: 1,\n\t\tcolumn: 5,\n\t});\n});\n\ntest.run();\n"
  },
  {
    "path": "packages/compiler/test/tsx-sourcemaps/unfinished-literal.ts",
    "content": "import { convertToTSX } from '@astrojs/compiler';\nimport { test } from 'uvu';\nimport * as assert from 'uvu/assert';\n\ntest('does not panic on unfinished template literal attribute', async () => {\n\tconst input = `<div class=\\`></div>\n  `;\n\tlet error = 0;\n\ttry {\n\t\tconst output = await convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tassert.match(output.code, 'class={``}');\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\n\tassert.equal(error, 0, 'compiler should not have panicked');\n});\n\ntest('does not panic on unfinished double quoted attribute', async () => {\n\tconst input = `<main id=\"gotcha />`;\n\tlet error = 0;\n\ttry {\n\t\tconst output = await convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tassert.match(output.code, `id=\"gotcha\"`);\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\n\tassert.equal(error, 0, 'compiler should not have panicked');\n});\n\ntest('does not panic on unfinished single quoted attribute', async () => {\n\tconst input = `<main id='gotcha/>`;\n\tlet error = 0;\n\ttry {\n\t\tconst output = await convertToTSX(input, { filename: 'index.astro', sourcemap: 'inline' });\n\t\tassert.match(output.code, `id=\"gotcha\"`);\n\t} catch (e) {\n\t\terror = 1;\n\t}\n\n\tassert.equal(error, 0, 'compiler should not have panicked');\n});\n"
  },
  {
    "path": "packages/compiler/test/utils.ts",
    "content": "import { convertToTSX, transform } from '@astrojs/compiler';\nimport { TraceMap, generatedPositionFor, originalPositionFor } from '@jridgewell/trace-mapping';\nimport sass from 'sass';\n\nexport async function preprocessStyle(value: any, attrs: any): Promise<any> {\n\tif (!attrs.lang) {\n\t\treturn null;\n\t}\n\tif (attrs.lang === 'scss') {\n\t\treturn transformSass(value);\n\t}\n\treturn null;\n}\n\nexport function transformSass(value: string) {\n\treturn new Promise((resolve, reject) => {\n\t\tsass.render({ data: value }, (err, result) => {\n\t\t\tif (err) {\n\t\t\t\treject(err);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tresolve({ code: result.css.toString('utf8'), map: result.map });\n\t\t\treturn;\n\t\t});\n\t});\n}\n\nexport function getPositionFor(input: string, snippet: string) {\n\tlet index = 0;\n\tlet line = 0;\n\tlet column = 0;\n\tfor (const c of input) {\n\t\tif (c === snippet[0] && input.slice(index).startsWith(snippet)) {\n\t\t\treturn { line: line + 1, column };\n\t\t}\n\t\tif (c === '\\n') {\n\t\t\tline++;\n\t\t\tcolumn = 0;\n\t\t}\n\t\tcolumn++;\n\t\tindex++;\n\t}\n\treturn null;\n}\n\nexport async function testTSXSourcemap(input: string, snippet: string) {\n\tconst snippetLoc = getPositionFor(input, snippet);\n\tif (!snippetLoc) throw new Error(`Unable to find \"${snippet}\"`);\n\n\tconst { code, map } = await convertToTSX(input, { sourcemap: 'both', filename: 'index.astro' });\n\tconst tracer = new TraceMap(map as any);\n\n\tconst generated = generatedPositionFor(tracer, {\n\t\tsource: 'index.astro',\n\t\tline: snippetLoc.line,\n\t\tcolumn: snippetLoc.column,\n\t});\n\tif (!generated || generated.line === null) {\n\t\tconsole.log(code);\n\t\tthrow new Error(`\"${snippet}\" position incorrectly mapped in generated output.`);\n\t}\n\tconst originalPosition = originalPositionFor(tracer, {\n\t\tline: generated.line,\n\t\tcolumn: generated.column,\n\t});\n\n\treturn originalPosition;\n}\n\nexport async function testJSSourcemap(input: string, snippet: string) {\n\tconst snippetLoc = getPositionFor(input, snippet);\n\tif (!snippetLoc) throw new Error(`Unable to find \"${snippet}\"`);\n\n\tconst { code, map } = await transform(input, {\n\t\tsourcemap: 'both',\n\t\tfilename: 'index.astro',\n\t\tresolvePath: (i: string) => i,\n\t});\n\tconst tracer = new TraceMap(map);\n\n\tconst generated = generatedPositionFor(tracer, {\n\t\tsource: 'index.astro',\n\t\tline: snippetLoc.line,\n\t\tcolumn: snippetLoc.column,\n\t});\n\tif (!generated || generated.line === null) {\n\t\tconsole.log(code);\n\t\tthrow new Error(`\"${snippet}\" position incorrectly mapped in generated output.`);\n\t}\n\tconst originalPosition = originalPositionFor(tracer, {\n\t\tline: generated.line,\n\t\tcolumn: generated.column,\n\t});\n\n\treturn originalPosition;\n}\nexport const TSXPrefix = '/* @jsxImportSource astro */\\n\\n';\n"
  },
  {
    "path": "packages/compiler/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2020\",\n    \"module\": \"Node16\",\n    \"moduleResolution\": \"Node16\",\n    \"strict\": true,\n    \"noEmit\": true,\n    \"declaration\": true,\n    \"noImplicitOverride\": true,\n    \"noUnusedLocals\": true,\n    \"esModuleInterop\": true,\n    \"verbatimModuleSyntax\": true\n  },\n  \"exclude\": [\"node_modules\"]\n}\n"
  },
  {
    "path": "packages/compiler/tsup.config.ts",
    "content": "import { defineConfig } from 'tsup';\n\nexport default defineConfig((options) => ({\n\tentry: ['src/node/**', 'src/browser/**', 'src/shared/**'],\n\toutDir: 'dist',\n\tformat: ['cjs', 'esm'],\n\tdts: true,\n\tclean: true,\n\tminify: !options.watch,\n\tsourcemap: Boolean(options.watch),\n\twatch: options.watch,\n\tpublicDir: 'wasm',\n\tshims: true,\n}));\n"
  },
  {
    "path": "packages/compiler/types.d.ts",
    "content": "export type * from './dist/shared/types.js';\n"
  },
  {
    "path": "packages/compiler/utils.d.ts",
    "content": "export * from './dist/node/utils.js';\n"
  },
  {
    "path": "pnpm-workspace.yaml",
    "content": "packages:\n  - 'packages/*'\n"
  }
]