`,
want: []ASTNode{{Type: "element", Name: "h1", Children: []ASTNode{{Type: "text", Value: "Hello world!"}}}},
},
{
name: "Comment preserves whitespace",
source: ``,
want: []ASTNode{{Type: "comment", Value: " hello "}},
}
}
}
```
In 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.
```shell
go test -v ./internal/... -run TestPrintToJSON/basic
go test -v ./internal/... -run TestPrintToJSON/Comment preserves whitespace
```
#### Snapshot testing
We use [go-snaps](https://github.com/gkampitakis/go-snaps) for snapshot testing. Visit their repository for more details on how to use it
#### Update snapshots
Some 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:
```shell
UPDATE_SNAPS=true go test -v ./internal/...
```
Instead, if there are some **obsolete snapshots**, you can `UPDATE_SNAPS=clean`:
```shell
UPDATE_SNAPS=clean go test -v ./internal/...
```
### Adding new test cases
The printer tests emit only snapshots. Go to `printer_test.go` and add a new test case:
```go
{
name: "New name for this test"
code: ""
}
```
Then run the below command, and a new snapshot named `new_name_for_this_test.snap` should appear in the snapshot folder.
```shell
go test -v ./internal/printer/printer_test.go
```
Other tests, like tokenizer and scanner be found in `internal/token_test.go`, `internal/js_scanner_test.go` and respectively.
Those tests don't emit any snapshot, and you'll have to add a `want` field:
```go
{
name: "New name for this test"
code: "",
want: want{
code: ""
}
}
```
[homebrew]: https://brew.sh/
[go]: https://golang.org/
[go-vscode]: https://marketplace.visualstudio.com/items?itemName=golang.go
[node]: https://nodejs.org/
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 [Astro contributors](https://github.com/withastro/compiler/graphs/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
This license applies to parts of the `internal/` subdirectory originating from
the https://cs.opensource.google/go/x/net/+/master:html/ repository:
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: Makefile
================================================
GO_FLAGS += "-ldflags=-s -w"
# Avoid embedding the build path in the executable for more reproducible builds
GO_FLAGS += -trimpath
wasm: internal/*/*.go go.mod
CGO_ENABLED=0 GOOS=js GOARCH=wasm go build $(GO_FLAGS) -o ./packages/compiler/wasm/astro.wasm ./cmd/astro-wasm/astro-wasm.go
publish-node:
make wasm
cd packages/compiler && pnpm run build
clean:
git clean -dxf
================================================
FILE: SYNTAX_SPEC.md
================================================
# The `.astro` File Format - Syntax Specification
**Version:** 1.0
**Status:** Draft
**Date:** 2026-02-03
---
## Table of Contents
1. [File Structure](#1-file-structure)
2. [Component Script (Frontmatter)](#2-component-script-frontmatter)
3. [Template](#3-template)
4. [Style Blocks](#4-style-blocks)
5. [Script Blocks](#5-script-blocks)
---
## 1. File Structure
An `.astro` file is composed of up to two sections described below. All are optional. When present, they must appear in this order:
```
┌──────────────────────────────────┐
│ --- │
│ Component Script │
│ --- │
├──────────────────────────────────┤
│ Template │
└──────────────────────────────────┘
```
### 1.1 Minimal examples
```astro
Hello, World!
```
```astro
---
const greeting = "Hello";
---
{greeting}, World!
```
---
## 2. Component Script (Frontmatter)
The region between the two `---` fences.
- The opening and closing fences are not required on their own line. Code may appear on the same line as both fences.
- Only one component script is allowed per file.
- Any amount of whitespace may appear before the opening fence or after the closing fence.
- Any content may appear before the opening fence, but is customarily ignored.
The component script is TypeScript. All standard TypeScript syntax is valid, apart from the exceptions and additions outlined in §2.1.
### 2.1 Top-level return
`return` may be used at the top level:
```astro
---
import { getUser } from "../lib/auth.js";
const user = await getUser();
if (!user) {
return Astro.redirect("/login");
}
---
```
---
## 3. Template
The template is considered to be everything after the closing fence of the component script, or the entire file when there is no component script.
The template mostly follows the [JSX specification](https://facebook.github.io/jsx/), with the differences and additions outlined in §3.2.
### 3.1 Whitespace between the component script and template is ignored
Any 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.
```astro
---
const greeting = "Hello";
---
{greeting}, World!
```
### 3.2 Differences from JSX
Unless mentioned otherwise, these differences apply both within the template and within expressions inside the template.
#### HTML comments
HTML comments `` are allowed.
```astro
{
}
```
####
In addition to the standard JSX fragment syntax `<>…>`, `Fragment` is supported as the tag name for fragments, i.e. `…`.
```astro
Item 1
Item 2
```
This form may accept attributes, unlike the shorthand syntax.
#### `is:raw` Directive
The `is:raw` attribute on any element allows the content to be treated as raw text instead of JSX.
```astro
{<% non-JS content %>}
{not an expression, just text}
```
#### HTML doctype
The [HTML doctype declaration](https://html.spec.whatwg.org/multipage/syntax.html#the-doctype) is allowed.
```astro
```
##### Top-level text nodes
Top-level text inside the template is treated as text nodes.
```astro
Hello, World!
```
#### Whitespace in expressions
Whitespace inside expressions `{ }` is preserved as text nodes, unlike JSX, where whitespace inside expression containers is ignored:
```astro
{
Hello
}
{
test
}
{ }
```
In Astro, all of these produce text nodes for the whitespace, whereas in JSX:
- Whitespace around elements inside `{ }` is ignored
- Whitespace-only expressions result in an empty expression, with no text nodes.
#### Multiple root elements
Unlike JSX, no single root element is required:
```astro
……
{
1
2
3
}
```
#### Attribute names
Attribute 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:
```astro
```
#### Namespace in component names is not supported
Colons in component names are not treated as namespace separators. For example:
```astro
```
Will be treated as a single component name (i.e. `Namespace:Component`). Spaces are not allowed in component names, so the following:
```astro
```
Would result in the component's name being Namespace, an attribute named `:` with no value, and an attribute named `Component` with no value.
#### Attribute shorthand
Attributes can use a shorthand syntax where `{prop}` is equivalent to `prop={prop}`:
```astro
```
#### Template literal attributes
Attributes can use backticks for interpolation without opening an expression:
```astro
```
#### Empty expressions inside attributes
Empty expressions `{}` inside attributes are allowed:
```astro
```
#### Comments inside opening tags
Comments are allowed inside the opening tag of an element:
```astro
```
#### Less-than signs in text nodes
Less-than signs `<` in text nodes are parsed following HTML rules, meaning they do not need to be escaped:
```astro
5 < 10
```
#### Non-ASCII tag names are not supported
Tag names must use ASCII characters only. Non-ASCII tag names (e.g. `<日本>`) are not supported and are treated as text nodes.
#### Unquoted attribute values
Attribute values do not need to be quoted if they contain only alphanumeric characters, hyphens, underscores, and periods:
```astro
```
#### Unclosed HTML tags
Like HTML, tags do not need to be explicitly closed.
```astro
Hello
World
```
It is up to the parser to optionally try to infer where tags close based on HTML parsing rules, or leave them unclosed.
##### Void elements
HTML void elements do not need to be self-closed:
```astro
```
#### Element-specific parsing rules
Certain HTML elements have special parsing rules that differ from the general rules outlined above. These include:
- `
```
Multiple `
```
If any attributes are present, the content instead follows standard [HTML `
```
================================================
FILE: biome.json
================================================
{
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"files": {
"ignore": ["**/dist/**", "**/pnpm-lock.yaml", "wasm_exec.ts"],
"include": ["packages/**"]
},
"formatter": {
"enabled": true,
"indentStyle": "tab",
"indentWidth": 2,
"lineWidth": 100
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "info",
"noConsoleLog": "info"
},
"style": {
"useTemplate": {
"level": "error",
"fix": "safe"
},
"noUnusedTemplateLiteral": {
"level": "error",
"fix": "safe"
}
}
}
},
"javascript": {
"formatter": {
"trailingCommas": "es5",
"quoteStyle": "single",
"semicolons": "always"
}
},
"json": {
"parser": {
"allowComments": true,
"allowTrailingCommas": true
},
"formatter": {
"indentStyle": "space",
"trailingCommas": "none"
}
},
"overrides": [
{
"include": ["**/stress/**"],
"linter": {
"rules": {
"suspicious": {
"noConsoleLog": "off"
}
}
}
},
{
"include": ["package.json"],
"json": {
"formatter": {
"lineWidth": 1
}
}
}
]
}
================================================
FILE: cmd/astro-wasm/astro-wasm.go
================================================
//go:build js && wasm
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"strings"
"sync"
"syscall/js"
"unicode"
"github.com/norunners/vert"
astro "github.com/withastro/compiler/internal"
"github.com/withastro/compiler/internal/handler"
"github.com/withastro/compiler/internal/loc"
"github.com/withastro/compiler/internal/printer"
"github.com/withastro/compiler/internal/sourcemap"
t "github.com/withastro/compiler/internal/t"
"github.com/withastro/compiler/internal/transform"
wasm_utils "github.com/withastro/compiler/internal_wasm/utils"
)
func main() {
js.Global().Set("@astrojs/compiler", js.ValueOf(make(map[string]interface{})))
module := js.Global().Get("@astrojs/compiler")
module.Set("transform", Transform())
module.Set("parse", Parse())
module.Set("convertToTSX", ConvertToTSX())
<-make(chan struct{})
}
func jsString(j js.Value) string {
if j.Equal(js.Undefined()) || j.Equal(js.Null()) {
return ""
}
return j.String()
}
func jsBoolOptional(j js.Value, defaultValue bool) bool {
if j.Equal(js.Undefined()) || j.Equal(js.Null()) {
return defaultValue
}
return j.Bool()
}
func jsBool(j js.Value) bool {
if j.Equal(js.Undefined()) || j.Equal(js.Null()) {
return false
}
return j.Bool()
}
func makeParseOptions(options js.Value) t.ParseOptions {
position := true
pos := options.Get("position")
if !pos.IsNull() && !pos.IsUndefined() {
position = pos.Bool()
}
filename := jsString(options.Get("filename"))
if filename == "" {
filename = ""
}
return t.ParseOptions{
Filename: filename,
Position: position,
}
}
func makeTransformOptions(options js.Value) transform.TransformOptions {
filename := jsString(options.Get("filename"))
if filename == "" {
filename = ""
}
normalizedFilename := jsString(options.Get("normalizedFilename"))
if normalizedFilename == "" {
normalizedFilename = filename
}
internalURL := jsString(options.Get("internalURL"))
if internalURL == "" {
internalURL = "astro/runtime/server/index.js"
}
sourcemap := jsString(options.Get("sourcemap"))
if sourcemap == "" {
sourcemap = "both"
}
astroGlobalArgs := jsString(options.Get("astroGlobalArgs"))
compact := false
if jsBool(options.Get("compact")) {
compact = true
}
scopedSlot := false
if jsBool(options.Get("resultScopedSlot")) {
scopedSlot = true
}
transitionsAnimationURL := jsString(options.Get("transitionsAnimationURL"))
if transitionsAnimationURL == "" {
transitionsAnimationURL = "astro/components/viewtransitions.css"
}
annotateSourceFile := false
if jsBool(options.Get("annotateSourceFile")) {
annotateSourceFile = true
}
var resolvePath any = options.Get("resolvePath")
var resolvePathFn func(string) string
if resolvePath.(js.Value).Type() == js.TypeFunction {
resolvePathFn = func(id string) string {
result, _ := wasm_utils.Await(resolvePath.(js.Value).Invoke(id))
if result[0].Equal(js.Undefined()) || result[0].Equal(js.Null()) {
return id
} else {
return result[0].String()
}
}
}
preprocessStyle := options.Get("preprocessStyle")
scopedStyleStrategy := jsString(options.Get("scopedStyleStrategy"))
if scopedStyleStrategy == "" {
scopedStyleStrategy = "where"
}
return transform.TransformOptions{
Filename: filename,
NormalizedFilename: normalizedFilename,
InternalURL: internalURL,
SourceMap: sourcemap,
AstroGlobalArgs: astroGlobalArgs,
Compact: compact,
ResolvePath: resolvePathFn,
PreprocessStyle: preprocessStyle,
ResultScopedSlot: scopedSlot,
ScopedStyleStrategy: scopedStyleStrategy,
TransitionsAnimationURL: transitionsAnimationURL,
AnnotateSourceFile: annotateSourceFile,
}
}
func makeTSXOptions(options js.Value) printer.TSXOptions {
includeScripts := jsBoolOptional(options.Get("includeScripts"), true)
includeStyles := jsBoolOptional(options.Get("includeStyles"), true)
return printer.TSXOptions{
IncludeScripts: includeScripts,
IncludeStyles: includeStyles,
}
}
type RawSourceMap struct {
File string `js:"file"`
Mappings string `js:"mappings"`
Names []string `js:"names"`
Sources []string `js:"sources"`
SourcesContent []string `js:"sourcesContent"`
Version int `js:"version"`
}
type HoistedScript struct {
Code string `js:"code"`
Src string `js:"src"`
Type string `js:"type"`
Map string `js:"map"`
}
type HydratedComponent struct {
ExportName string `js:"exportName"`
LocalName string `js:"localName"`
Specifier string `js:"specifier"`
ResolvedPath string `js:"resolvedPath"`
}
type ParseResult struct {
AST string `js:"ast"`
Diagnostics []loc.DiagnosticMessage `js:"diagnostics"`
}
type TSXResult struct {
Code string `js:"code"`
Map string `js:"map"`
Diagnostics []loc.DiagnosticMessage `js:"diagnostics"`
Ranges printer.TSXRanges `js:"metaRanges"`
}
type TransformResult struct {
Code string `js:"code"`
Diagnostics []loc.DiagnosticMessage `js:"diagnostics"`
Map string `js:"map"`
Scope string `js:"scope"`
CSS []string `js:"css"`
Scripts []HoistedScript `js:"scripts"`
HydratedComponents []HydratedComponent `js:"hydratedComponents"`
ClientOnlyComponents []HydratedComponent `js:"clientOnlyComponents"`
ServerComponents []HydratedComponent `js:"serverComponents"`
ContainsHead bool `js:"containsHead"`
StyleError []string `js:"styleError"`
Propagation bool `js:"propagation"`
}
// This is spawned as a goroutine to preprocess style nodes using an async function passed from JS
func preprocessStyle(i int, style *astro.Node, transformOptions transform.TransformOptions, styleError *[]string, cb func()) {
defer cb()
if style.FirstChild == nil {
return
}
attrs := wasm_utils.GetAttrs(style)
data, _ := wasm_utils.Await(transformOptions.PreprocessStyle.(js.Value).Invoke(style.FirstChild.Data, attrs))
// note: Rollup (and by extension our Astro Vite plugin) allows for "undefined" and "null" responses if a transform wishes to skip this occurrence
if data[0].Equal(js.Undefined()) || data[0].Equal(js.Null()) {
return
}
// If an error return, override the style's CSS so the compiler doesn't hang
// And return a styleError. The caller will use this to know that style processing failed.
if err := jsString(data[0].Get("error")); err != "" {
style.FirstChild.Data = ""
//*styleError = err
*styleError = append(*styleError, err)
return
}
str := jsString(data[0].Get("code"))
if str == "" {
return
}
style.FirstChild.Data = str
}
func Parse() any {
return js.FuncOf(func(this js.Value, args []js.Value) any {
source := jsString(args[0])
parseOptions := makeParseOptions(js.Value(args[1]))
transformOptions := makeTransformOptions(js.Value(args[1]))
transformOptions.Scope = "xxxxxx"
h := handler.NewHandler(source, parseOptions.Filename)
var doc *astro.Node
doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true))
if err != nil {
h.AppendError(err)
}
result := printer.PrintToJSON(source, doc, parseOptions)
// AFTER printing, exec transformations to pickup any errors/warnings
transform.Transform(doc, transformOptions, h)
return vert.ValueOf(ParseResult{
AST: string(result.Output),
Diagnostics: h.Diagnostics(),
}).Value
})
}
func ConvertToTSX() any {
return js.FuncOf(func(this js.Value, args []js.Value) any {
source := jsString(args[0])
transformOptions := makeTransformOptions(js.Value(args[1]))
transformOptions.Scope = "xxxxxx"
h := handler.NewHandler(source, transformOptions.Filename)
var doc *astro.Node
doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h), astro.ParseOptionEnableLiteral(true))
if err != nil {
h.AppendError(err)
}
tsxOptions := makeTSXOptions(js.Value(args[1]))
result := printer.PrintToTSX(source, doc, tsxOptions, transformOptions, h)
// AFTER printing, exec transformations to pickup any errors/warnings
transform.Transform(doc, transformOptions, h)
sourcemapString := createSourceMapString(source, result, transformOptions)
code := string(result.Output)
if transformOptions.SourceMap != "external" {
inlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))
code += "\n" + inlineSourcemap
}
return vert.ValueOf(TSXResult{
Code: code,
Map: sourcemapString,
Diagnostics: h.Diagnostics(),
Ranges: result.TSXRanges,
}).Value
})
}
func Transform() any {
return js.FuncOf(func(this js.Value, args []js.Value) any {
source := strings.TrimRightFunc(jsString(args[0]), unicode.IsSpace)
transformOptions := makeTransformOptions(js.Value(args[1]))
scopeStr := transformOptions.NormalizedFilename
if scopeStr == "" {
scopeStr = source
}
transformOptions.Scope = astro.HashString(scopeStr)
h := handler.NewHandler(source, transformOptions.Filename)
styleError := []string{}
promiseHandle := js.FuncOf(func(this js.Value, args []js.Value) any {
resolve := args[0]
reject := args[1]
go func() {
var doc *astro.Node
defer func() {
if err := recover(); err != nil {
reject.Invoke(wasm_utils.ErrorToJSError(h, err.(error)))
return
}
}()
doc, err := astro.ParseWithOptions(strings.NewReader(source), astro.ParseOptionWithHandler(h))
if err != nil {
reject.Invoke(wasm_utils.ErrorToJSError(h, err))
return
}
// Hoist styles and scripts to the top-level
transform.ExtractStyles(doc, &transformOptions)
// Pre-process styles
// Important! These goroutines need to be spawned from this file or they don't work
var wg sync.WaitGroup
if len(doc.Styles) > 0 {
if transformOptions.PreprocessStyle.(js.Value).Type() == js.TypeFunction {
for i, style := range doc.Styles {
wg.Add(1)
i := i
go preprocessStyle(i, style, transformOptions, &styleError, wg.Done)
}
}
}
// Wait for all the style goroutines to finish
wg.Wait()
// Perform CSS and element scoping as needed
transform.Transform(doc, transformOptions, h)
css := []string{}
scripts := []HoistedScript{}
hydratedComponents := []HydratedComponent{}
clientOnlyComponents := []HydratedComponent{}
serverComponents := []HydratedComponent{}
css_result := printer.PrintCSS(source, doc, transformOptions)
for _, bytes := range css_result.Output {
css = append(css, string(bytes))
}
// Append hoisted scripts
for _, node := range doc.Scripts {
src := astro.GetAttribute(node, "src")
script := HoistedScript{
Src: "",
Code: "",
Type: "",
Map: "",
}
if src != nil {
script.Type = "external"
script.Src = src.Val
} else if node.FirstChild != nil {
script.Type = "inline"
if transformOptions.SourceMap != "" {
isLine := func(r rune) bool { return r == '\r' || r == '\n' }
isNotLine := func(r rune) bool { return !(r == '\r' || r == '\n') }
output := make([]byte, 0)
builder := sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(source, len(strings.Split(source, "\n"))))
sourcesContent, _ := json.Marshal(source)
if len(node.FirstChild.Loc) > 0 {
i := node.FirstChild.Loc[0].Start
nonWS := strings.IndexFunc(node.FirstChild.Data, isNotLine)
i += nonWS
for _, ln := range strings.Split(strings.TrimFunc(node.FirstChild.Data, isLine), "\n") {
content := []byte(ln)
content = append(content, '\n')
for j, b := range content {
if j == 0 || !unicode.IsSpace(rune(b)) {
builder.AddSourceMapping(loc.Loc{Start: i}, output)
}
output = append(output, b)
i += 1
}
}
output = append(output, '\n')
} else {
output = append(output, []byte(strings.TrimSpace(node.FirstChild.Data))...)
}
sourcemap := fmt.Sprintf(
`{ "version": 3, "sources": ["%s"], "sourcesContent": [%s], "mappings": "%s", "names": [] }`,
transformOptions.Filename,
string(sourcesContent),
string(builder.GenerateChunk(output).Buffer),
)
script.Map = sourcemap
script.Code = string(output)
} else {
script.Code = node.FirstChild.Data
}
}
// sourcemapString := createSourceMapString(source, result, transformOptions)
// inlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))
scripts = append(scripts, script)
}
for _, c := range doc.HydratedComponents {
hydratedComponents = append(hydratedComponents, HydratedComponent{
ExportName: c.ExportName,
Specifier: c.Specifier,
ResolvedPath: c.ResolvedPath,
})
}
for _, c := range doc.ClientOnlyComponents {
clientOnlyComponents = append(clientOnlyComponents, HydratedComponent{
ExportName: c.ExportName,
Specifier: c.Specifier,
ResolvedPath: c.ResolvedPath,
})
}
for _, c := range doc.ServerComponents {
serverComponents = append(serverComponents, HydratedComponent{
ExportName: c.ExportName,
LocalName: c.LocalName,
Specifier: c.Specifier,
ResolvedPath: c.ResolvedPath,
})
}
var value vert.Value
result := printer.PrintToJS(source, doc, len(css), transformOptions, h)
transformResult := &TransformResult{
CSS: css,
Scope: transformOptions.Scope,
Scripts: scripts,
HydratedComponents: hydratedComponents,
ClientOnlyComponents: clientOnlyComponents,
ServerComponents: serverComponents,
ContainsHead: doc.ContainsHead,
StyleError: styleError,
Propagation: doc.HeadPropagation,
}
switch transformOptions.SourceMap {
case "external":
value = createExternalSourceMap(source, transformResult, result, transformOptions)
case "both":
value = createBothSourceMap(source, transformResult, result, transformOptions)
case "inline":
value = createInlineSourceMap(source, transformResult, result, transformOptions)
default:
transformResult.Code = string(result.Output)
transformResult.Map = ""
value = vert.ValueOf(transformResult)
}
value.Set("diagnostics", vert.ValueOf(h.Diagnostics()).Value)
resolve.Invoke(value.Value)
}()
return nil
})
defer promiseHandle.Release()
// Create and return the Promise object
promiseConstructor := js.Global().Get("Promise")
return promiseConstructor.New(promiseHandle)
})
}
func createSourceMapString(source string, result printer.PrintResult, transformOptions transform.TransformOptions) string {
sourcesContent, _ := json.Marshal(source)
sourcemap := RawSourceMap{
Version: 3,
Sources: []string{transformOptions.Filename},
SourcesContent: []string{string(sourcesContent)},
Mappings: string(result.SourceMapChunk.Buffer),
}
return fmt.Sprintf(`{
"version": 3,
"sources": ["%s"],
"sourcesContent": [%s],
"mappings": "%s",
"names": []
}`, sourcemap.Sources[0], sourcemap.SourcesContent[0], sourcemap.Mappings)
}
func createExternalSourceMap(source string, transformResult *TransformResult, result printer.PrintResult, transformOptions transform.TransformOptions) vert.Value {
transformResult.Code = string(result.Output)
transformResult.Map = createSourceMapString(source, result, transformOptions)
return vert.ValueOf(transformResult)
}
func createInlineSourceMap(source string, transformResult *TransformResult, result printer.PrintResult, transformOptions transform.TransformOptions) vert.Value {
sourcemapString := createSourceMapString(source, result, transformOptions)
inlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))
transformResult.Code = string(result.Output) + "\n" + inlineSourcemap
transformResult.Map = ""
return vert.ValueOf(transformResult)
}
func createBothSourceMap(source string, transformResult *TransformResult, result printer.PrintResult, transformOptions transform.TransformOptions) vert.Value {
sourcemapString := createSourceMapString(source, result, transformOptions)
inlineSourcemap := `//# sourceMappingURL=data:application/json;charset=utf-8;base64,` + base64.StdEncoding.EncodeToString([]byte(sourcemapString))
transformResult.Code = string(result.Output) + "\n" + inlineSourcemap
transformResult.Map = sourcemapString
return vert.ValueOf(transformResult)
}
================================================
FILE: go.mod
================================================
module github.com/withastro/compiler
go 1.21
require (
github.com/gkampitakis/go-snaps v0.5.2
github.com/google/go-cmp v0.5.9
github.com/iancoleman/strcase v0.2.0
github.com/lithammer/dedent v1.1.0
github.com/norunners/vert v0.0.0-20221203075838-106a353d42dd
github.com/tdewolff/parse/v2 v2.6.4
golang.org/x/net v0.0.0-20221004154528-8021a29435af
golang.org/x/sys v0.0.0-20221010170243-090e33056c14
)
require (
github.com/gkampitakis/ciinfo v0.3.0 // indirect
github.com/gkampitakis/go-diff v1.3.2 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/maruel/natural v1.1.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/tidwall/gjson v1.17.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tidwall/sjson v1.2.5 // indirect
)
================================================
FILE: go.sum
================================================
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/gkampitakis/ciinfo v0.3.0 h1:gWZlOC2+RYYttL0hBqcoQhM7h1qNkVqvRCV1fOvpAv8=
github.com/gkampitakis/ciinfo v0.3.0/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
github.com/gkampitakis/go-snaps v0.5.2 h1:ay/6f7WHwRkOgpBec9DjMLRBAApziJommZ21NkOOCwY=
github.com/gkampitakis/go-snaps v0.5.2/go.mod h1:ZABkO14uCuVxBHAXAfKG+bqNz+aa1bGPAg8jkI0Nk8Y=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY=
github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
github.com/norunners/vert v0.0.0-20221203075838-106a353d42dd h1:tHn7K76q9eJ2rXLH/OoxHkdprM3l2A+0kdxOrKYcV7U=
github.com/norunners/vert v0.0.0-20221203075838-106a353d42dd/go.mod h1:8iuQLyTSvuzwy6R6l6w6J+i9c/6xPEVoVdcMz9E8FEw=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/tdewolff/parse/v2 v2.6.4 h1:KCkDvNUMof10e3QExio9OPZJT8SbdKojLBumw8YZycQ=
github.com/tdewolff/parse/v2 v2.6.4/go.mod h1:woz0cgbLwFdtbjJu8PIKxhW05KplTFQkOdX78o+Jgrs=
github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM=
github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
================================================
FILE: internal/const.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
import a "golang.org/x/net/html/atom"
// Section 12.2.4.2 of the HTML5 specification says "The following elements
// have varying levels of special parsing rules".
// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements
var isSpecialElementMap = map[string]bool{
"address": true,
"applet": true,
"area": true,
"article": true,
"aside": true,
"base": true,
"basefont": true,
"bgsound": true,
"blockquote": true,
"body": true,
"br": true,
"button": true,
"caption": true,
"center": true,
"col": true,
"colgroup": true,
"dd": true,
"details": true,
"dir": true,
"div": true,
"dl": true,
"dt": true,
"embed": true,
"fieldset": true,
"figcaption": true,
"figure": true,
"footer": true,
"form": true,
"frame": true,
"frameset": true,
"h1": true,
"h2": true,
"h3": true,
"h4": true,
"h5": true,
"h6": true,
"head": true,
"header": true,
"hgroup": true,
"hr": true,
"html": true,
"iframe": true,
"img": true,
"input": true,
"keygen": true, // "keygen" has been removed from the spec, but are kept here for backwards compatibility.
"li": true,
"link": true,
"listing": true,
"main": true,
"marquee": true,
"menu": true,
"meta": true,
"nav": true,
"noembed": true,
"noframes": true,
"noscript": true,
"object": true,
"ol": true,
"p": true,
"param": true,
"plaintext": true,
"pre": true,
"script": true,
"section": true,
"select": true,
"source": true,
"style": true,
"summary": true,
"table": true,
"tbody": true,
"td": true,
"template": true,
"textarea": true,
"tfoot": true,
"th": true,
"thead": true,
"title": true,
"tr": true,
"track": true,
"ul": true,
"wbr": true,
"xmp": true,
}
func isSpecialElement(element *Node) bool {
switch element.Namespace {
case "", "html":
return isSpecialElementMap[element.Data]
case "math":
switch element.Data {
case "mi", "mo", "mn", "ms", "mtext", "annotation-xml":
return true
}
case "svg":
switch element.Data {
case "foreignObject", "desc", "title":
return true
}
}
return false
}
var knownDirectiveMap = map[string]bool{
"client:load": true,
"client:idle": true,
"client:visible": true,
"client:only": true,
"class:list": true,
"set:text": true,
"set:html": true,
}
func IsKnownDirective(element *Node, attr *Attribute) bool {
if knownDirectiveMap[attr.Key] {
return true
}
if element.DataAtom == a.Script {
return attr.Key == "hoist"
}
if element.DataAtom == a.Style {
return attr.Key == "global"
}
return false
}
================================================
FILE: internal/doc.go
================================================
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// This example demonstrates parsing HTML data and walking the resulting tree.
package astro
================================================
FILE: internal/doctype.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
import (
"strings"
)
// parseDoctype parses the data from a DoctypeToken into a name,
// public identifier, and system identifier. It returns a Node whose Type
// is DoctypeNode, whose Data is the name, and which has attributes
// named "system" and "public" for the two identifiers if they were present.
// quirks is whether the document should be parsed in "quirks mode".
func parseDoctype(s string) (n *Node, quirks bool) {
n = &Node{Type: DoctypeNode}
// Find the name.
space := strings.IndexAny(s, whitespace)
if space == -1 {
space = len(s)
}
n.Data = s[:space]
// The comparison to "html" is case-sensitive.
if n.Data != "html" {
quirks = true
}
n.Data = strings.ToLower(n.Data)
s = strings.TrimLeft(s[space:], whitespace)
if len(s) < 6 {
// It can't start with "PUBLIC" or "SYSTEM".
// Ignore the rest of the string.
return n, quirks || s != ""
}
key := strings.ToLower(s[:6])
s = s[6:]
for key == "public" || key == "system" {
s = strings.TrimLeft(s, whitespace)
if s == "" {
break
}
quote := s[0]
if quote != '"' && quote != '\'' {
break
}
s = s[1:]
q := strings.IndexRune(s, rune(quote))
var id string
if q == -1 {
id = s
s = ""
} else {
id = s[:q]
s = s[q+1:]
}
n.Attr = append(n.Attr, Attribute{Key: key, Val: id})
if key == "public" {
key = "system"
} else {
key = ""
}
}
if key != "" || s != "" {
quirks = true
} else if len(n.Attr) > 0 {
if n.Attr[0].Key == "public" {
public := strings.ToLower(n.Attr[0].Val)
switch public {
case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html":
quirks = true
default:
for _, q := range quirkyIDs {
if strings.HasPrefix(public, q) {
quirks = true
break
}
}
}
// The following two public IDs only cause quirks mode if there is no system ID.
if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") ||
strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) {
quirks = true
}
}
if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" &&
strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" {
quirks = true
}
}
return n, quirks
}
// quirkyIDs is a list of public doctype identifiers that cause a document
// to be interpreted in quirks mode. The identifiers should be in lower case.
var quirkyIDs = []string{
"+//silmaril//dtd html pro v0r11 19970101//",
"-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
"-//as//dtd html 3.0 aswedit + extensions//",
"-//ietf//dtd html 2.0 level 1//",
"-//ietf//dtd html 2.0 level 2//",
"-//ietf//dtd html 2.0 strict level 1//",
"-//ietf//dtd html 2.0 strict level 2//",
"-//ietf//dtd html 2.0 strict//",
"-//ietf//dtd html 2.0//",
"-//ietf//dtd html 2.1e//",
"-//ietf//dtd html 3.0//",
"-//ietf//dtd html 3.2 final//",
"-//ietf//dtd html 3.2//",
"-//ietf//dtd html 3//",
"-//ietf//dtd html level 0//",
"-//ietf//dtd html level 1//",
"-//ietf//dtd html level 2//",
"-//ietf//dtd html level 3//",
"-//ietf//dtd html strict level 0//",
"-//ietf//dtd html strict level 1//",
"-//ietf//dtd html strict level 2//",
"-//ietf//dtd html strict level 3//",
"-//ietf//dtd html strict//",
"-//ietf//dtd html//",
"-//metrius//dtd metrius presentational//",
"-//microsoft//dtd internet explorer 2.0 html strict//",
"-//microsoft//dtd internet explorer 2.0 html//",
"-//microsoft//dtd internet explorer 2.0 tables//",
"-//microsoft//dtd internet explorer 3.0 html strict//",
"-//microsoft//dtd internet explorer 3.0 html//",
"-//microsoft//dtd internet explorer 3.0 tables//",
"-//netscape comm. corp.//dtd html//",
"-//netscape comm. corp.//dtd strict html//",
"-//o'reilly and associates//dtd html 2.0//",
"-//o'reilly and associates//dtd html extended 1.0//",
"-//o'reilly and associates//dtd html extended relaxed 1.0//",
"-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
"-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
"-//spyglass//dtd html 2.0 extended//",
"-//sq//dtd html 2.0 hotmetal + extensions//",
"-//sun microsystems corp.//dtd hotjava html//",
"-//sun microsystems corp.//dtd hotjava strict html//",
"-//w3c//dtd html 3 1995-03-24//",
"-//w3c//dtd html 3.2 draft//",
"-//w3c//dtd html 3.2 final//",
"-//w3c//dtd html 3.2//",
"-//w3c//dtd html 3.2s draft//",
"-//w3c//dtd html 4.0 frameset//",
"-//w3c//dtd html 4.0 transitional//",
"-//w3c//dtd html experimental 19960712//",
"-//w3c//dtd html experimental 970421//",
"-//w3c//dtd w3 html//",
"-//w3o//dtd w3 html 3.0//",
"-//webtechs//dtd mozilla html 2.0//",
"-//webtechs//dtd mozilla html//",
}
================================================
FILE: internal/entity.go
================================================
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
// All entities that do not end with ';' are 6 or fewer bytes long.
const longestEntityWithoutSemicolon = 6
// entity is a map from HTML entity names to their values. The semicolon matters:
// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references
// lists both "amp" and "amp;" as two separate entries.
//
// Note that the HTML5 list is larger than the HTML4 list at
// http://www.w3.org/TR/html4/sgml/entities.html
var entity = map[string]rune{
"AElig;": '\U000000C6',
"AMP;": '\U00000026',
"Aacute;": '\U000000C1',
"Abreve;": '\U00000102',
"Acirc;": '\U000000C2',
"Acy;": '\U00000410',
"Afr;": '\U0001D504',
"Agrave;": '\U000000C0',
"Alpha;": '\U00000391',
"Amacr;": '\U00000100',
"And;": '\U00002A53',
"Aogon;": '\U00000104',
"Aopf;": '\U0001D538',
"ApplyFunction;": '\U00002061',
"Aring;": '\U000000C5',
"Ascr;": '\U0001D49C',
"Assign;": '\U00002254',
"Atilde;": '\U000000C3',
"Auml;": '\U000000C4',
"Backslash;": '\U00002216',
"Barv;": '\U00002AE7',
"Barwed;": '\U00002306',
"Bcy;": '\U00000411',
"Because;": '\U00002235',
"Bernoullis;": '\U0000212C',
"Beta;": '\U00000392',
"Bfr;": '\U0001D505',
"Bopf;": '\U0001D539',
"Breve;": '\U000002D8',
"Bscr;": '\U0000212C',
"Bumpeq;": '\U0000224E',
"CHcy;": '\U00000427',
"COPY;": '\U000000A9',
"Cacute;": '\U00000106',
"Cap;": '\U000022D2',
"CapitalDifferentialD;": '\U00002145',
"Cayleys;": '\U0000212D',
"Ccaron;": '\U0000010C',
"Ccedil;": '\U000000C7',
"Ccirc;": '\U00000108',
"Cconint;": '\U00002230',
"Cdot;": '\U0000010A',
"Cedilla;": '\U000000B8',
"CenterDot;": '\U000000B7',
"Cfr;": '\U0000212D',
"Chi;": '\U000003A7',
"CircleDot;": '\U00002299',
"CircleMinus;": '\U00002296',
"CirclePlus;": '\U00002295',
"CircleTimes;": '\U00002297',
"ClockwiseContourIntegral;": '\U00002232',
"CloseCurlyDoubleQuote;": '\U0000201D',
"CloseCurlyQuote;": '\U00002019',
"Colon;": '\U00002237',
"Colone;": '\U00002A74',
"Congruent;": '\U00002261',
"Conint;": '\U0000222F',
"ContourIntegral;": '\U0000222E',
"Copf;": '\U00002102',
"Coproduct;": '\U00002210',
"CounterClockwiseContourIntegral;": '\U00002233',
"Cross;": '\U00002A2F',
"Cscr;": '\U0001D49E',
"Cup;": '\U000022D3',
"CupCap;": '\U0000224D',
"DD;": '\U00002145',
"DDotrahd;": '\U00002911',
"DJcy;": '\U00000402',
"DScy;": '\U00000405',
"DZcy;": '\U0000040F',
"Dagger;": '\U00002021',
"Darr;": '\U000021A1',
"Dashv;": '\U00002AE4',
"Dcaron;": '\U0000010E',
"Dcy;": '\U00000414',
"Del;": '\U00002207',
"Delta;": '\U00000394',
"Dfr;": '\U0001D507',
"DiacriticalAcute;": '\U000000B4',
"DiacriticalDot;": '\U000002D9',
"DiacriticalDoubleAcute;": '\U000002DD',
"DiacriticalGrave;": '\U00000060',
"DiacriticalTilde;": '\U000002DC',
"Diamond;": '\U000022C4',
"DifferentialD;": '\U00002146',
"Dopf;": '\U0001D53B',
"Dot;": '\U000000A8',
"DotDot;": '\U000020DC',
"DotEqual;": '\U00002250',
"DoubleContourIntegral;": '\U0000222F',
"DoubleDot;": '\U000000A8',
"DoubleDownArrow;": '\U000021D3',
"DoubleLeftArrow;": '\U000021D0',
"DoubleLeftRightArrow;": '\U000021D4',
"DoubleLeftTee;": '\U00002AE4',
"DoubleLongLeftArrow;": '\U000027F8',
"DoubleLongLeftRightArrow;": '\U000027FA',
"DoubleLongRightArrow;": '\U000027F9',
"DoubleRightArrow;": '\U000021D2',
"DoubleRightTee;": '\U000022A8',
"DoubleUpArrow;": '\U000021D1',
"DoubleUpDownArrow;": '\U000021D5',
"DoubleVerticalBar;": '\U00002225',
"DownArrow;": '\U00002193',
"DownArrowBar;": '\U00002913',
"DownArrowUpArrow;": '\U000021F5',
"DownBreve;": '\U00000311',
"DownLeftRightVector;": '\U00002950',
"DownLeftTeeVector;": '\U0000295E',
"DownLeftVector;": '\U000021BD',
"DownLeftVectorBar;": '\U00002956',
"DownRightTeeVector;": '\U0000295F',
"DownRightVector;": '\U000021C1',
"DownRightVectorBar;": '\U00002957',
"DownTee;": '\U000022A4',
"DownTeeArrow;": '\U000021A7',
"Downarrow;": '\U000021D3',
"Dscr;": '\U0001D49F',
"Dstrok;": '\U00000110',
"ENG;": '\U0000014A',
"ETH;": '\U000000D0',
"Eacute;": '\U000000C9',
"Ecaron;": '\U0000011A',
"Ecirc;": '\U000000CA',
"Ecy;": '\U0000042D',
"Edot;": '\U00000116',
"Efr;": '\U0001D508',
"Egrave;": '\U000000C8',
"Element;": '\U00002208',
"Emacr;": '\U00000112',
"EmptySmallSquare;": '\U000025FB',
"EmptyVerySmallSquare;": '\U000025AB',
"Eogon;": '\U00000118',
"Eopf;": '\U0001D53C',
"Epsilon;": '\U00000395',
"Equal;": '\U00002A75',
"EqualTilde;": '\U00002242',
"Equilibrium;": '\U000021CC',
"Escr;": '\U00002130',
"Esim;": '\U00002A73',
"Eta;": '\U00000397',
"Euml;": '\U000000CB',
"Exists;": '\U00002203',
"ExponentialE;": '\U00002147',
"Fcy;": '\U00000424',
"Ffr;": '\U0001D509',
"FilledSmallSquare;": '\U000025FC',
"FilledVerySmallSquare;": '\U000025AA',
"Fopf;": '\U0001D53D',
"ForAll;": '\U00002200',
"Fouriertrf;": '\U00002131',
"Fscr;": '\U00002131',
"GJcy;": '\U00000403',
"GT;": '\U0000003E',
"Gamma;": '\U00000393',
"Gammad;": '\U000003DC',
"Gbreve;": '\U0000011E',
"Gcedil;": '\U00000122',
"Gcirc;": '\U0000011C',
"Gcy;": '\U00000413',
"Gdot;": '\U00000120',
"Gfr;": '\U0001D50A',
"Gg;": '\U000022D9',
"Gopf;": '\U0001D53E',
"GreaterEqual;": '\U00002265',
"GreaterEqualLess;": '\U000022DB',
"GreaterFullEqual;": '\U00002267',
"GreaterGreater;": '\U00002AA2',
"GreaterLess;": '\U00002277',
"GreaterSlantEqual;": '\U00002A7E',
"GreaterTilde;": '\U00002273',
"Gscr;": '\U0001D4A2',
"Gt;": '\U0000226B',
"HARDcy;": '\U0000042A',
"Hacek;": '\U000002C7',
"Hat;": '\U0000005E',
"Hcirc;": '\U00000124',
"Hfr;": '\U0000210C',
"HilbertSpace;": '\U0000210B',
"Hopf;": '\U0000210D',
"HorizontalLine;": '\U00002500',
"Hscr;": '\U0000210B',
"Hstrok;": '\U00000126',
"HumpDownHump;": '\U0000224E',
"HumpEqual;": '\U0000224F',
"IEcy;": '\U00000415',
"IJlig;": '\U00000132',
"IOcy;": '\U00000401',
"Iacute;": '\U000000CD',
"Icirc;": '\U000000CE',
"Icy;": '\U00000418',
"Idot;": '\U00000130',
"Ifr;": '\U00002111',
"Igrave;": '\U000000CC',
"Im;": '\U00002111',
"Imacr;": '\U0000012A',
"ImaginaryI;": '\U00002148',
"Implies;": '\U000021D2',
"Int;": '\U0000222C',
"Integral;": '\U0000222B',
"Intersection;": '\U000022C2',
"InvisibleComma;": '\U00002063',
"InvisibleTimes;": '\U00002062',
"Iogon;": '\U0000012E',
"Iopf;": '\U0001D540',
"Iota;": '\U00000399',
"Iscr;": '\U00002110',
"Itilde;": '\U00000128',
"Iukcy;": '\U00000406',
"Iuml;": '\U000000CF',
"Jcirc;": '\U00000134',
"Jcy;": '\U00000419',
"Jfr;": '\U0001D50D',
"Jopf;": '\U0001D541',
"Jscr;": '\U0001D4A5',
"Jsercy;": '\U00000408',
"Jukcy;": '\U00000404',
"KHcy;": '\U00000425',
"KJcy;": '\U0000040C',
"Kappa;": '\U0000039A',
"Kcedil;": '\U00000136',
"Kcy;": '\U0000041A',
"Kfr;": '\U0001D50E',
"Kopf;": '\U0001D542',
"Kscr;": '\U0001D4A6',
"LJcy;": '\U00000409',
"LT;": '\U0000003C',
"Lacute;": '\U00000139',
"Lambda;": '\U0000039B',
"Lang;": '\U000027EA',
"Laplacetrf;": '\U00002112',
"Larr;": '\U0000219E',
"Lcaron;": '\U0000013D',
"Lcedil;": '\U0000013B',
"Lcy;": '\U0000041B',
"LeftAngleBracket;": '\U000027E8',
"LeftArrow;": '\U00002190',
"LeftArrowBar;": '\U000021E4',
"LeftArrowRightArrow;": '\U000021C6',
"LeftCeiling;": '\U00002308',
"LeftDoubleBracket;": '\U000027E6',
"LeftDownTeeVector;": '\U00002961',
"LeftDownVector;": '\U000021C3',
"LeftDownVectorBar;": '\U00002959',
"LeftFloor;": '\U0000230A',
"LeftRightArrow;": '\U00002194',
"LeftRightVector;": '\U0000294E',
"LeftTee;": '\U000022A3',
"LeftTeeArrow;": '\U000021A4',
"LeftTeeVector;": '\U0000295A',
"LeftTriangle;": '\U000022B2',
"LeftTriangleBar;": '\U000029CF',
"LeftTriangleEqual;": '\U000022B4',
"LeftUpDownVector;": '\U00002951',
"LeftUpTeeVector;": '\U00002960',
"LeftUpVector;": '\U000021BF',
"LeftUpVectorBar;": '\U00002958',
"LeftVector;": '\U000021BC',
"LeftVectorBar;": '\U00002952',
"Leftarrow;": '\U000021D0',
"Leftrightarrow;": '\U000021D4',
"LessEqualGreater;": '\U000022DA',
"LessFullEqual;": '\U00002266',
"LessGreater;": '\U00002276',
"LessLess;": '\U00002AA1',
"LessSlantEqual;": '\U00002A7D',
"LessTilde;": '\U00002272',
"Lfr;": '\U0001D50F',
"Ll;": '\U000022D8',
"Lleftarrow;": '\U000021DA',
"Lmidot;": '\U0000013F',
"LongLeftArrow;": '\U000027F5',
"LongLeftRightArrow;": '\U000027F7',
"LongRightArrow;": '\U000027F6',
"Longleftarrow;": '\U000027F8',
"Longleftrightarrow;": '\U000027FA',
"Longrightarrow;": '\U000027F9',
"Lopf;": '\U0001D543',
"LowerLeftArrow;": '\U00002199',
"LowerRightArrow;": '\U00002198',
"Lscr;": '\U00002112',
"Lsh;": '\U000021B0',
"Lstrok;": '\U00000141',
"Lt;": '\U0000226A',
"Map;": '\U00002905',
"Mcy;": '\U0000041C',
"MediumSpace;": '\U0000205F',
"Mellintrf;": '\U00002133',
"Mfr;": '\U0001D510',
"MinusPlus;": '\U00002213',
"Mopf;": '\U0001D544',
"Mscr;": '\U00002133',
"Mu;": '\U0000039C',
"NJcy;": '\U0000040A',
"Nacute;": '\U00000143',
"Ncaron;": '\U00000147',
"Ncedil;": '\U00000145',
"Ncy;": '\U0000041D',
"NegativeMediumSpace;": '\U0000200B',
"NegativeThickSpace;": '\U0000200B',
"NegativeThinSpace;": '\U0000200B',
"NegativeVeryThinSpace;": '\U0000200B',
"NestedGreaterGreater;": '\U0000226B',
"NestedLessLess;": '\U0000226A',
"NewLine;": '\U0000000A',
"Nfr;": '\U0001D511',
"NoBreak;": '\U00002060',
"NonBreakingSpace;": '\U000000A0',
"Nopf;": '\U00002115',
"Not;": '\U00002AEC',
"NotCongruent;": '\U00002262',
"NotCupCap;": '\U0000226D',
"NotDoubleVerticalBar;": '\U00002226',
"NotElement;": '\U00002209',
"NotEqual;": '\U00002260',
"NotExists;": '\U00002204',
"NotGreater;": '\U0000226F',
"NotGreaterEqual;": '\U00002271',
"NotGreaterLess;": '\U00002279',
"NotGreaterTilde;": '\U00002275',
"NotLeftTriangle;": '\U000022EA',
"NotLeftTriangleEqual;": '\U000022EC',
"NotLess;": '\U0000226E',
"NotLessEqual;": '\U00002270',
"NotLessGreater;": '\U00002278',
"NotLessTilde;": '\U00002274',
"NotPrecedes;": '\U00002280',
"NotPrecedesSlantEqual;": '\U000022E0',
"NotReverseElement;": '\U0000220C',
"NotRightTriangle;": '\U000022EB',
"NotRightTriangleEqual;": '\U000022ED',
"NotSquareSubsetEqual;": '\U000022E2',
"NotSquareSupersetEqual;": '\U000022E3',
"NotSubsetEqual;": '\U00002288',
"NotSucceeds;": '\U00002281',
"NotSucceedsSlantEqual;": '\U000022E1',
"NotSupersetEqual;": '\U00002289',
"NotTilde;": '\U00002241',
"NotTildeEqual;": '\U00002244',
"NotTildeFullEqual;": '\U00002247',
"NotTildeTilde;": '\U00002249',
"NotVerticalBar;": '\U00002224',
"Nscr;": '\U0001D4A9',
"Ntilde;": '\U000000D1',
"Nu;": '\U0000039D',
"OElig;": '\U00000152',
"Oacute;": '\U000000D3',
"Ocirc;": '\U000000D4',
"Ocy;": '\U0000041E',
"Odblac;": '\U00000150',
"Ofr;": '\U0001D512',
"Ograve;": '\U000000D2',
"Omacr;": '\U0000014C',
"Omega;": '\U000003A9',
"Omicron;": '\U0000039F',
"Oopf;": '\U0001D546',
"OpenCurlyDoubleQuote;": '\U0000201C',
"OpenCurlyQuote;": '\U00002018',
"Or;": '\U00002A54',
"Oscr;": '\U0001D4AA',
"Oslash;": '\U000000D8',
"Otilde;": '\U000000D5',
"Otimes;": '\U00002A37',
"Ouml;": '\U000000D6',
"OverBar;": '\U0000203E',
"OverBrace;": '\U000023DE',
"OverBracket;": '\U000023B4',
"OverParenthesis;": '\U000023DC',
"PartialD;": '\U00002202',
"Pcy;": '\U0000041F',
"Pfr;": '\U0001D513',
"Phi;": '\U000003A6',
"Pi;": '\U000003A0',
"PlusMinus;": '\U000000B1',
"Poincareplane;": '\U0000210C',
"Popf;": '\U00002119',
"Pr;": '\U00002ABB',
"Precedes;": '\U0000227A',
"PrecedesEqual;": '\U00002AAF',
"PrecedesSlantEqual;": '\U0000227C',
"PrecedesTilde;": '\U0000227E',
"Prime;": '\U00002033',
"Product;": '\U0000220F',
"Proportion;": '\U00002237',
"Proportional;": '\U0000221D',
"Pscr;": '\U0001D4AB',
"Psi;": '\U000003A8',
"QUOT;": '\U00000022',
"Qfr;": '\U0001D514',
"Qopf;": '\U0000211A',
"Qscr;": '\U0001D4AC',
"RBarr;": '\U00002910',
"REG;": '\U000000AE',
"Racute;": '\U00000154',
"Rang;": '\U000027EB',
"Rarr;": '\U000021A0',
"Rarrtl;": '\U00002916',
"Rcaron;": '\U00000158',
"Rcedil;": '\U00000156',
"Rcy;": '\U00000420',
"Re;": '\U0000211C',
"ReverseElement;": '\U0000220B',
"ReverseEquilibrium;": '\U000021CB',
"ReverseUpEquilibrium;": '\U0000296F',
"Rfr;": '\U0000211C',
"Rho;": '\U000003A1',
"RightAngleBracket;": '\U000027E9',
"RightArrow;": '\U00002192',
"RightArrowBar;": '\U000021E5',
"RightArrowLeftArrow;": '\U000021C4',
"RightCeiling;": '\U00002309',
"RightDoubleBracket;": '\U000027E7',
"RightDownTeeVector;": '\U0000295D',
"RightDownVector;": '\U000021C2',
"RightDownVectorBar;": '\U00002955',
"RightFloor;": '\U0000230B',
"RightTee;": '\U000022A2',
"RightTeeArrow;": '\U000021A6',
"RightTeeVector;": '\U0000295B',
"RightTriangle;": '\U000022B3',
"RightTriangleBar;": '\U000029D0',
"RightTriangleEqual;": '\U000022B5',
"RightUpDownVector;": '\U0000294F',
"RightUpTeeVector;": '\U0000295C',
"RightUpVector;": '\U000021BE',
"RightUpVectorBar;": '\U00002954',
"RightVector;": '\U000021C0',
"RightVectorBar;": '\U00002953',
"Rightarrow;": '\U000021D2',
"Ropf;": '\U0000211D',
"RoundImplies;": '\U00002970',
"Rrightarrow;": '\U000021DB',
"Rscr;": '\U0000211B',
"Rsh;": '\U000021B1',
"RuleDelayed;": '\U000029F4',
"SHCHcy;": '\U00000429',
"SHcy;": '\U00000428',
"SOFTcy;": '\U0000042C',
"Sacute;": '\U0000015A',
"Sc;": '\U00002ABC',
"Scaron;": '\U00000160',
"Scedil;": '\U0000015E',
"Scirc;": '\U0000015C',
"Scy;": '\U00000421',
"Sfr;": '\U0001D516',
"ShortDownArrow;": '\U00002193',
"ShortLeftArrow;": '\U00002190',
"ShortRightArrow;": '\U00002192',
"ShortUpArrow;": '\U00002191',
"Sigma;": '\U000003A3',
"SmallCircle;": '\U00002218',
"Sopf;": '\U0001D54A',
"Sqrt;": '\U0000221A',
"Square;": '\U000025A1',
"SquareIntersection;": '\U00002293',
"SquareSubset;": '\U0000228F',
"SquareSubsetEqual;": '\U00002291',
"SquareSuperset;": '\U00002290',
"SquareSupersetEqual;": '\U00002292',
"SquareUnion;": '\U00002294',
"Sscr;": '\U0001D4AE',
"Star;": '\U000022C6',
"Sub;": '\U000022D0',
"Subset;": '\U000022D0',
"SubsetEqual;": '\U00002286',
"Succeeds;": '\U0000227B',
"SucceedsEqual;": '\U00002AB0',
"SucceedsSlantEqual;": '\U0000227D',
"SucceedsTilde;": '\U0000227F',
"SuchThat;": '\U0000220B',
"Sum;": '\U00002211',
"Sup;": '\U000022D1',
"Superset;": '\U00002283',
"SupersetEqual;": '\U00002287',
"Supset;": '\U000022D1',
"THORN;": '\U000000DE',
"TRADE;": '\U00002122',
"TSHcy;": '\U0000040B',
"TScy;": '\U00000426',
"Tab;": '\U00000009',
"Tau;": '\U000003A4',
"Tcaron;": '\U00000164',
"Tcedil;": '\U00000162',
"Tcy;": '\U00000422',
"Tfr;": '\U0001D517',
"Therefore;": '\U00002234',
"Theta;": '\U00000398',
"ThinSpace;": '\U00002009',
"Tilde;": '\U0000223C',
"TildeEqual;": '\U00002243',
"TildeFullEqual;": '\U00002245',
"TildeTilde;": '\U00002248',
"Topf;": '\U0001D54B',
"TripleDot;": '\U000020DB',
"Tscr;": '\U0001D4AF',
"Tstrok;": '\U00000166',
"Uacute;": '\U000000DA',
"Uarr;": '\U0000219F',
"Uarrocir;": '\U00002949',
"Ubrcy;": '\U0000040E',
"Ubreve;": '\U0000016C',
"Ucirc;": '\U000000DB',
"Ucy;": '\U00000423',
"Udblac;": '\U00000170',
"Ufr;": '\U0001D518',
"Ugrave;": '\U000000D9',
"Umacr;": '\U0000016A',
"UnderBar;": '\U0000005F',
"UnderBrace;": '\U000023DF',
"UnderBracket;": '\U000023B5',
"UnderParenthesis;": '\U000023DD',
"Union;": '\U000022C3',
"UnionPlus;": '\U0000228E',
"Uogon;": '\U00000172',
"Uopf;": '\U0001D54C',
"UpArrow;": '\U00002191',
"UpArrowBar;": '\U00002912',
"UpArrowDownArrow;": '\U000021C5',
"UpDownArrow;": '\U00002195',
"UpEquilibrium;": '\U0000296E',
"UpTee;": '\U000022A5',
"UpTeeArrow;": '\U000021A5',
"Uparrow;": '\U000021D1',
"Updownarrow;": '\U000021D5',
"UpperLeftArrow;": '\U00002196',
"UpperRightArrow;": '\U00002197',
"Upsi;": '\U000003D2',
"Upsilon;": '\U000003A5',
"Uring;": '\U0000016E',
"Uscr;": '\U0001D4B0',
"Utilde;": '\U00000168',
"Uuml;": '\U000000DC',
"VDash;": '\U000022AB',
"Vbar;": '\U00002AEB',
"Vcy;": '\U00000412',
"Vdash;": '\U000022A9',
"Vdashl;": '\U00002AE6',
"Vee;": '\U000022C1',
"Verbar;": '\U00002016',
"Vert;": '\U00002016',
"VerticalBar;": '\U00002223',
"VerticalLine;": '\U0000007C',
"VerticalSeparator;": '\U00002758',
"VerticalTilde;": '\U00002240',
"VeryThinSpace;": '\U0000200A',
"Vfr;": '\U0001D519',
"Vopf;": '\U0001D54D',
"Vscr;": '\U0001D4B1',
"Vvdash;": '\U000022AA',
"Wcirc;": '\U00000174',
"Wedge;": '\U000022C0',
"Wfr;": '\U0001D51A',
"Wopf;": '\U0001D54E',
"Wscr;": '\U0001D4B2',
"Xfr;": '\U0001D51B',
"Xi;": '\U0000039E',
"Xopf;": '\U0001D54F',
"Xscr;": '\U0001D4B3',
"YAcy;": '\U0000042F',
"YIcy;": '\U00000407',
"YUcy;": '\U0000042E',
"Yacute;": '\U000000DD',
"Ycirc;": '\U00000176',
"Ycy;": '\U0000042B',
"Yfr;": '\U0001D51C',
"Yopf;": '\U0001D550',
"Yscr;": '\U0001D4B4',
"Yuml;": '\U00000178',
"ZHcy;": '\U00000416',
"Zacute;": '\U00000179',
"Zcaron;": '\U0000017D',
"Zcy;": '\U00000417',
"Zdot;": '\U0000017B',
"ZeroWidthSpace;": '\U0000200B',
"Zeta;": '\U00000396',
"Zfr;": '\U00002128',
"Zopf;": '\U00002124',
"Zscr;": '\U0001D4B5',
"aacute;": '\U000000E1',
"abreve;": '\U00000103',
"ac;": '\U0000223E',
"acd;": '\U0000223F',
"acirc;": '\U000000E2',
"acute;": '\U000000B4',
"acy;": '\U00000430',
"aelig;": '\U000000E6',
"af;": '\U00002061',
"afr;": '\U0001D51E',
"agrave;": '\U000000E0',
"alefsym;": '\U00002135',
"aleph;": '\U00002135',
"alpha;": '\U000003B1',
"amacr;": '\U00000101',
"amalg;": '\U00002A3F',
"amp;": '\U00000026',
"and;": '\U00002227',
"andand;": '\U00002A55',
"andd;": '\U00002A5C',
"andslope;": '\U00002A58',
"andv;": '\U00002A5A',
"ang;": '\U00002220',
"ange;": '\U000029A4',
"angle;": '\U00002220',
"angmsd;": '\U00002221',
"angmsdaa;": '\U000029A8',
"angmsdab;": '\U000029A9',
"angmsdac;": '\U000029AA',
"angmsdad;": '\U000029AB',
"angmsdae;": '\U000029AC',
"angmsdaf;": '\U000029AD',
"angmsdag;": '\U000029AE',
"angmsdah;": '\U000029AF',
"angrt;": '\U0000221F',
"angrtvb;": '\U000022BE',
"angrtvbd;": '\U0000299D',
"angsph;": '\U00002222',
"angst;": '\U000000C5',
"angzarr;": '\U0000237C',
"aogon;": '\U00000105',
"aopf;": '\U0001D552',
"ap;": '\U00002248',
"apE;": '\U00002A70',
"apacir;": '\U00002A6F',
"ape;": '\U0000224A',
"apid;": '\U0000224B',
"apos;": '\U00000027',
"approx;": '\U00002248',
"approxeq;": '\U0000224A',
"aring;": '\U000000E5',
"ascr;": '\U0001D4B6',
"ast;": '\U0000002A',
"asymp;": '\U00002248',
"asympeq;": '\U0000224D',
"atilde;": '\U000000E3',
"auml;": '\U000000E4',
"awconint;": '\U00002233',
"awint;": '\U00002A11',
"bNot;": '\U00002AED',
"backcong;": '\U0000224C',
"backepsilon;": '\U000003F6',
"backprime;": '\U00002035',
"backsim;": '\U0000223D',
"backsimeq;": '\U000022CD',
"barvee;": '\U000022BD',
"barwed;": '\U00002305',
"barwedge;": '\U00002305',
"bbrk;": '\U000023B5',
"bbrktbrk;": '\U000023B6',
"bcong;": '\U0000224C',
"bcy;": '\U00000431',
"bdquo;": '\U0000201E',
"becaus;": '\U00002235',
"because;": '\U00002235',
"bemptyv;": '\U000029B0',
"bepsi;": '\U000003F6',
"bernou;": '\U0000212C',
"beta;": '\U000003B2',
"beth;": '\U00002136',
"between;": '\U0000226C',
"bfr;": '\U0001D51F',
"bigcap;": '\U000022C2',
"bigcirc;": '\U000025EF',
"bigcup;": '\U000022C3',
"bigodot;": '\U00002A00',
"bigoplus;": '\U00002A01',
"bigotimes;": '\U00002A02',
"bigsqcup;": '\U00002A06',
"bigstar;": '\U00002605',
"bigtriangledown;": '\U000025BD',
"bigtriangleup;": '\U000025B3',
"biguplus;": '\U00002A04',
"bigvee;": '\U000022C1',
"bigwedge;": '\U000022C0',
"bkarow;": '\U0000290D',
"blacklozenge;": '\U000029EB',
"blacksquare;": '\U000025AA',
"blacktriangle;": '\U000025B4',
"blacktriangledown;": '\U000025BE',
"blacktriangleleft;": '\U000025C2',
"blacktriangleright;": '\U000025B8',
"blank;": '\U00002423',
"blk12;": '\U00002592',
"blk14;": '\U00002591',
"blk34;": '\U00002593',
"block;": '\U00002588',
"bnot;": '\U00002310',
"bopf;": '\U0001D553',
"bot;": '\U000022A5',
"bottom;": '\U000022A5',
"bowtie;": '\U000022C8',
"boxDL;": '\U00002557',
"boxDR;": '\U00002554',
"boxDl;": '\U00002556',
"boxDr;": '\U00002553',
"boxH;": '\U00002550',
"boxHD;": '\U00002566',
"boxHU;": '\U00002569',
"boxHd;": '\U00002564',
"boxHu;": '\U00002567',
"boxUL;": '\U0000255D',
"boxUR;": '\U0000255A',
"boxUl;": '\U0000255C',
"boxUr;": '\U00002559',
"boxV;": '\U00002551',
"boxVH;": '\U0000256C',
"boxVL;": '\U00002563',
"boxVR;": '\U00002560',
"boxVh;": '\U0000256B',
"boxVl;": '\U00002562',
"boxVr;": '\U0000255F',
"boxbox;": '\U000029C9',
"boxdL;": '\U00002555',
"boxdR;": '\U00002552',
"boxdl;": '\U00002510',
"boxdr;": '\U0000250C',
"boxh;": '\U00002500',
"boxhD;": '\U00002565',
"boxhU;": '\U00002568',
"boxhd;": '\U0000252C',
"boxhu;": '\U00002534',
"boxminus;": '\U0000229F',
"boxplus;": '\U0000229E',
"boxtimes;": '\U000022A0',
"boxuL;": '\U0000255B',
"boxuR;": '\U00002558',
"boxul;": '\U00002518',
"boxur;": '\U00002514',
"boxv;": '\U00002502',
"boxvH;": '\U0000256A',
"boxvL;": '\U00002561',
"boxvR;": '\U0000255E',
"boxvh;": '\U0000253C',
"boxvl;": '\U00002524',
"boxvr;": '\U0000251C',
"bprime;": '\U00002035',
"breve;": '\U000002D8',
"brvbar;": '\U000000A6',
"bscr;": '\U0001D4B7',
"bsemi;": '\U0000204F',
"bsim;": '\U0000223D',
"bsime;": '\U000022CD',
"bsol;": '\U0000005C',
"bsolb;": '\U000029C5',
"bsolhsub;": '\U000027C8',
"bull;": '\U00002022',
"bullet;": '\U00002022',
"bump;": '\U0000224E',
"bumpE;": '\U00002AAE',
"bumpe;": '\U0000224F',
"bumpeq;": '\U0000224F',
"cacute;": '\U00000107',
"cap;": '\U00002229',
"capand;": '\U00002A44',
"capbrcup;": '\U00002A49',
"capcap;": '\U00002A4B',
"capcup;": '\U00002A47',
"capdot;": '\U00002A40',
"caret;": '\U00002041',
"caron;": '\U000002C7',
"ccaps;": '\U00002A4D',
"ccaron;": '\U0000010D',
"ccedil;": '\U000000E7',
"ccirc;": '\U00000109',
"ccups;": '\U00002A4C',
"ccupssm;": '\U00002A50',
"cdot;": '\U0000010B',
"cedil;": '\U000000B8',
"cemptyv;": '\U000029B2',
"cent;": '\U000000A2',
"centerdot;": '\U000000B7',
"cfr;": '\U0001D520',
"chcy;": '\U00000447',
"check;": '\U00002713',
"checkmark;": '\U00002713',
"chi;": '\U000003C7',
"cir;": '\U000025CB',
"cirE;": '\U000029C3',
"circ;": '\U000002C6',
"circeq;": '\U00002257',
"circlearrowleft;": '\U000021BA',
"circlearrowright;": '\U000021BB',
"circledR;": '\U000000AE',
"circledS;": '\U000024C8',
"circledast;": '\U0000229B',
"circledcirc;": '\U0000229A',
"circleddash;": '\U0000229D',
"cire;": '\U00002257',
"cirfnint;": '\U00002A10',
"cirmid;": '\U00002AEF',
"cirscir;": '\U000029C2',
"clubs;": '\U00002663',
"clubsuit;": '\U00002663',
"colon;": '\U0000003A',
"colone;": '\U00002254',
"coloneq;": '\U00002254',
"comma;": '\U0000002C',
"commat;": '\U00000040',
"comp;": '\U00002201',
"compfn;": '\U00002218',
"complement;": '\U00002201',
"complexes;": '\U00002102',
"cong;": '\U00002245',
"congdot;": '\U00002A6D',
"conint;": '\U0000222E',
"copf;": '\U0001D554',
"coprod;": '\U00002210',
"copy;": '\U000000A9',
"copysr;": '\U00002117',
"crarr;": '\U000021B5',
"cross;": '\U00002717',
"cscr;": '\U0001D4B8',
"csub;": '\U00002ACF',
"csube;": '\U00002AD1',
"csup;": '\U00002AD0',
"csupe;": '\U00002AD2',
"ctdot;": '\U000022EF',
"cudarrl;": '\U00002938',
"cudarrr;": '\U00002935',
"cuepr;": '\U000022DE',
"cuesc;": '\U000022DF',
"cularr;": '\U000021B6',
"cularrp;": '\U0000293D',
"cup;": '\U0000222A',
"cupbrcap;": '\U00002A48',
"cupcap;": '\U00002A46',
"cupcup;": '\U00002A4A',
"cupdot;": '\U0000228D',
"cupor;": '\U00002A45',
"curarr;": '\U000021B7',
"curarrm;": '\U0000293C',
"curlyeqprec;": '\U000022DE',
"curlyeqsucc;": '\U000022DF',
"curlyvee;": '\U000022CE',
"curlywedge;": '\U000022CF',
"curren;": '\U000000A4',
"curvearrowleft;": '\U000021B6',
"curvearrowright;": '\U000021B7',
"cuvee;": '\U000022CE',
"cuwed;": '\U000022CF',
"cwconint;": '\U00002232',
"cwint;": '\U00002231',
"cylcty;": '\U0000232D',
"dArr;": '\U000021D3',
"dHar;": '\U00002965',
"dagger;": '\U00002020',
"daleth;": '\U00002138',
"darr;": '\U00002193',
"dash;": '\U00002010',
"dashv;": '\U000022A3',
"dbkarow;": '\U0000290F',
"dblac;": '\U000002DD',
"dcaron;": '\U0000010F',
"dcy;": '\U00000434',
"dd;": '\U00002146',
"ddagger;": '\U00002021',
"ddarr;": '\U000021CA',
"ddotseq;": '\U00002A77',
"deg;": '\U000000B0',
"delta;": '\U000003B4',
"demptyv;": '\U000029B1',
"dfisht;": '\U0000297F',
"dfr;": '\U0001D521',
"dharl;": '\U000021C3',
"dharr;": '\U000021C2',
"diam;": '\U000022C4',
"diamond;": '\U000022C4',
"diamondsuit;": '\U00002666',
"diams;": '\U00002666',
"die;": '\U000000A8',
"digamma;": '\U000003DD',
"disin;": '\U000022F2',
"div;": '\U000000F7',
"divide;": '\U000000F7',
"divideontimes;": '\U000022C7',
"divonx;": '\U000022C7',
"djcy;": '\U00000452',
"dlcorn;": '\U0000231E',
"dlcrop;": '\U0000230D',
"dollar;": '\U00000024',
"dopf;": '\U0001D555',
"dot;": '\U000002D9',
"doteq;": '\U00002250',
"doteqdot;": '\U00002251',
"dotminus;": '\U00002238',
"dotplus;": '\U00002214',
"dotsquare;": '\U000022A1',
"doublebarwedge;": '\U00002306',
"downarrow;": '\U00002193',
"downdownarrows;": '\U000021CA',
"downharpoonleft;": '\U000021C3',
"downharpoonright;": '\U000021C2',
"drbkarow;": '\U00002910',
"drcorn;": '\U0000231F',
"drcrop;": '\U0000230C',
"dscr;": '\U0001D4B9',
"dscy;": '\U00000455',
"dsol;": '\U000029F6',
"dstrok;": '\U00000111',
"dtdot;": '\U000022F1',
"dtri;": '\U000025BF',
"dtrif;": '\U000025BE',
"duarr;": '\U000021F5',
"duhar;": '\U0000296F',
"dwangle;": '\U000029A6',
"dzcy;": '\U0000045F',
"dzigrarr;": '\U000027FF',
"eDDot;": '\U00002A77',
"eDot;": '\U00002251',
"eacute;": '\U000000E9',
"easter;": '\U00002A6E',
"ecaron;": '\U0000011B',
"ecir;": '\U00002256',
"ecirc;": '\U000000EA',
"ecolon;": '\U00002255',
"ecy;": '\U0000044D',
"edot;": '\U00000117',
"ee;": '\U00002147',
"efDot;": '\U00002252',
"efr;": '\U0001D522',
"eg;": '\U00002A9A',
"egrave;": '\U000000E8',
"egs;": '\U00002A96',
"egsdot;": '\U00002A98',
"el;": '\U00002A99',
"elinters;": '\U000023E7',
"ell;": '\U00002113',
"els;": '\U00002A95',
"elsdot;": '\U00002A97',
"emacr;": '\U00000113',
"empty;": '\U00002205',
"emptyset;": '\U00002205',
"emptyv;": '\U00002205',
"emsp;": '\U00002003',
"emsp13;": '\U00002004',
"emsp14;": '\U00002005',
"eng;": '\U0000014B',
"ensp;": '\U00002002',
"eogon;": '\U00000119',
"eopf;": '\U0001D556',
"epar;": '\U000022D5',
"eparsl;": '\U000029E3',
"eplus;": '\U00002A71',
"epsi;": '\U000003B5',
"epsilon;": '\U000003B5',
"epsiv;": '\U000003F5',
"eqcirc;": '\U00002256',
"eqcolon;": '\U00002255',
"eqsim;": '\U00002242',
"eqslantgtr;": '\U00002A96',
"eqslantless;": '\U00002A95',
"equals;": '\U0000003D',
"equest;": '\U0000225F',
"equiv;": '\U00002261',
"equivDD;": '\U00002A78',
"eqvparsl;": '\U000029E5',
"erDot;": '\U00002253',
"erarr;": '\U00002971',
"escr;": '\U0000212F',
"esdot;": '\U00002250',
"esim;": '\U00002242',
"eta;": '\U000003B7',
"eth;": '\U000000F0',
"euml;": '\U000000EB',
"euro;": '\U000020AC',
"excl;": '\U00000021',
"exist;": '\U00002203',
"expectation;": '\U00002130',
"exponentiale;": '\U00002147',
"fallingdotseq;": '\U00002252',
"fcy;": '\U00000444',
"female;": '\U00002640',
"ffilig;": '\U0000FB03',
"fflig;": '\U0000FB00',
"ffllig;": '\U0000FB04',
"ffr;": '\U0001D523',
"filig;": '\U0000FB01',
"flat;": '\U0000266D',
"fllig;": '\U0000FB02',
"fltns;": '\U000025B1',
"fnof;": '\U00000192',
"fopf;": '\U0001D557',
"forall;": '\U00002200',
"fork;": '\U000022D4',
"forkv;": '\U00002AD9',
"fpartint;": '\U00002A0D',
"frac12;": '\U000000BD',
"frac13;": '\U00002153',
"frac14;": '\U000000BC',
"frac15;": '\U00002155',
"frac16;": '\U00002159',
"frac18;": '\U0000215B',
"frac23;": '\U00002154',
"frac25;": '\U00002156',
"frac34;": '\U000000BE',
"frac35;": '\U00002157',
"frac38;": '\U0000215C',
"frac45;": '\U00002158',
"frac56;": '\U0000215A',
"frac58;": '\U0000215D',
"frac78;": '\U0000215E',
"frasl;": '\U00002044',
"frown;": '\U00002322',
"fscr;": '\U0001D4BB',
"gE;": '\U00002267',
"gEl;": '\U00002A8C',
"gacute;": '\U000001F5',
"gamma;": '\U000003B3',
"gammad;": '\U000003DD',
"gap;": '\U00002A86',
"gbreve;": '\U0000011F',
"gcirc;": '\U0000011D',
"gcy;": '\U00000433',
"gdot;": '\U00000121',
"ge;": '\U00002265',
"gel;": '\U000022DB',
"geq;": '\U00002265',
"geqq;": '\U00002267',
"geqslant;": '\U00002A7E',
"ges;": '\U00002A7E',
"gescc;": '\U00002AA9',
"gesdot;": '\U00002A80',
"gesdoto;": '\U00002A82',
"gesdotol;": '\U00002A84',
"gesles;": '\U00002A94',
"gfr;": '\U0001D524',
"gg;": '\U0000226B',
"ggg;": '\U000022D9',
"gimel;": '\U00002137',
"gjcy;": '\U00000453',
"gl;": '\U00002277',
"glE;": '\U00002A92',
"gla;": '\U00002AA5',
"glj;": '\U00002AA4',
"gnE;": '\U00002269',
"gnap;": '\U00002A8A',
"gnapprox;": '\U00002A8A',
"gne;": '\U00002A88',
"gneq;": '\U00002A88',
"gneqq;": '\U00002269',
"gnsim;": '\U000022E7',
"gopf;": '\U0001D558',
"grave;": '\U00000060',
"gscr;": '\U0000210A',
"gsim;": '\U00002273',
"gsime;": '\U00002A8E',
"gsiml;": '\U00002A90',
"gt;": '\U0000003E',
"gtcc;": '\U00002AA7',
"gtcir;": '\U00002A7A',
"gtdot;": '\U000022D7',
"gtlPar;": '\U00002995',
"gtquest;": '\U00002A7C',
"gtrapprox;": '\U00002A86',
"gtrarr;": '\U00002978',
"gtrdot;": '\U000022D7',
"gtreqless;": '\U000022DB',
"gtreqqless;": '\U00002A8C',
"gtrless;": '\U00002277',
"gtrsim;": '\U00002273',
"hArr;": '\U000021D4',
"hairsp;": '\U0000200A',
"half;": '\U000000BD',
"hamilt;": '\U0000210B',
"hardcy;": '\U0000044A',
"harr;": '\U00002194',
"harrcir;": '\U00002948',
"harrw;": '\U000021AD',
"hbar;": '\U0000210F',
"hcirc;": '\U00000125',
"hearts;": '\U00002665',
"heartsuit;": '\U00002665',
"hellip;": '\U00002026',
"hercon;": '\U000022B9',
"hfr;": '\U0001D525',
"hksearow;": '\U00002925',
"hkswarow;": '\U00002926',
"hoarr;": '\U000021FF',
"homtht;": '\U0000223B',
"hookleftarrow;": '\U000021A9',
"hookrightarrow;": '\U000021AA',
"hopf;": '\U0001D559',
"horbar;": '\U00002015',
"hscr;": '\U0001D4BD',
"hslash;": '\U0000210F',
"hstrok;": '\U00000127',
"hybull;": '\U00002043',
"hyphen;": '\U00002010',
"iacute;": '\U000000ED',
"ic;": '\U00002063',
"icirc;": '\U000000EE',
"icy;": '\U00000438',
"iecy;": '\U00000435',
"iexcl;": '\U000000A1',
"iff;": '\U000021D4',
"ifr;": '\U0001D526',
"igrave;": '\U000000EC',
"ii;": '\U00002148',
"iiiint;": '\U00002A0C',
"iiint;": '\U0000222D',
"iinfin;": '\U000029DC',
"iiota;": '\U00002129',
"ijlig;": '\U00000133',
"imacr;": '\U0000012B',
"image;": '\U00002111',
"imagline;": '\U00002110',
"imagpart;": '\U00002111',
"imath;": '\U00000131',
"imof;": '\U000022B7',
"imped;": '\U000001B5',
"in;": '\U00002208',
"incare;": '\U00002105',
"infin;": '\U0000221E',
"infintie;": '\U000029DD',
"inodot;": '\U00000131',
"int;": '\U0000222B',
"intcal;": '\U000022BA',
"integers;": '\U00002124',
"intercal;": '\U000022BA',
"intlarhk;": '\U00002A17',
"intprod;": '\U00002A3C',
"iocy;": '\U00000451',
"iogon;": '\U0000012F',
"iopf;": '\U0001D55A',
"iota;": '\U000003B9',
"iprod;": '\U00002A3C',
"iquest;": '\U000000BF',
"iscr;": '\U0001D4BE',
"isin;": '\U00002208',
"isinE;": '\U000022F9',
"isindot;": '\U000022F5',
"isins;": '\U000022F4',
"isinsv;": '\U000022F3',
"isinv;": '\U00002208',
"it;": '\U00002062',
"itilde;": '\U00000129',
"iukcy;": '\U00000456',
"iuml;": '\U000000EF',
"jcirc;": '\U00000135',
"jcy;": '\U00000439',
"jfr;": '\U0001D527',
"jmath;": '\U00000237',
"jopf;": '\U0001D55B',
"jscr;": '\U0001D4BF',
"jsercy;": '\U00000458',
"jukcy;": '\U00000454',
"kappa;": '\U000003BA',
"kappav;": '\U000003F0',
"kcedil;": '\U00000137',
"kcy;": '\U0000043A',
"kfr;": '\U0001D528',
"kgreen;": '\U00000138',
"khcy;": '\U00000445',
"kjcy;": '\U0000045C',
"kopf;": '\U0001D55C',
"kscr;": '\U0001D4C0',
"lAarr;": '\U000021DA',
"lArr;": '\U000021D0',
"lAtail;": '\U0000291B',
"lBarr;": '\U0000290E',
"lE;": '\U00002266',
"lEg;": '\U00002A8B',
"lHar;": '\U00002962',
"lacute;": '\U0000013A',
"laemptyv;": '\U000029B4',
"lagran;": '\U00002112',
"lambda;": '\U000003BB',
"lang;": '\U000027E8',
"langd;": '\U00002991',
"langle;": '\U000027E8',
"lap;": '\U00002A85',
"laquo;": '\U000000AB',
"larr;": '\U00002190',
"larrb;": '\U000021E4',
"larrbfs;": '\U0000291F',
"larrfs;": '\U0000291D',
"larrhk;": '\U000021A9',
"larrlp;": '\U000021AB',
"larrpl;": '\U00002939',
"larrsim;": '\U00002973',
"larrtl;": '\U000021A2',
"lat;": '\U00002AAB',
"latail;": '\U00002919',
"late;": '\U00002AAD',
"lbarr;": '\U0000290C',
"lbbrk;": '\U00002772',
"lbrace;": '\U0000007B',
"lbrack;": '\U0000005B',
"lbrke;": '\U0000298B',
"lbrksld;": '\U0000298F',
"lbrkslu;": '\U0000298D',
"lcaron;": '\U0000013E',
"lcedil;": '\U0000013C',
"lceil;": '\U00002308',
"lcub;": '\U0000007B',
"lcy;": '\U0000043B',
"ldca;": '\U00002936',
"ldquo;": '\U0000201C',
"ldquor;": '\U0000201E',
"ldrdhar;": '\U00002967',
"ldrushar;": '\U0000294B',
"ldsh;": '\U000021B2',
"le;": '\U00002264',
"leftarrow;": '\U00002190',
"leftarrowtail;": '\U000021A2',
"leftharpoondown;": '\U000021BD',
"leftharpoonup;": '\U000021BC',
"leftleftarrows;": '\U000021C7',
"leftrightarrow;": '\U00002194',
"leftrightarrows;": '\U000021C6',
"leftrightharpoons;": '\U000021CB',
"leftrightsquigarrow;": '\U000021AD',
"leftthreetimes;": '\U000022CB',
"leg;": '\U000022DA',
"leq;": '\U00002264',
"leqq;": '\U00002266',
"leqslant;": '\U00002A7D',
"les;": '\U00002A7D',
"lescc;": '\U00002AA8',
"lesdot;": '\U00002A7F',
"lesdoto;": '\U00002A81',
"lesdotor;": '\U00002A83',
"lesges;": '\U00002A93',
"lessapprox;": '\U00002A85',
"lessdot;": '\U000022D6',
"lesseqgtr;": '\U000022DA',
"lesseqqgtr;": '\U00002A8B',
"lessgtr;": '\U00002276',
"lesssim;": '\U00002272',
"lfisht;": '\U0000297C',
"lfloor;": '\U0000230A',
"lfr;": '\U0001D529',
"lg;": '\U00002276',
"lgE;": '\U00002A91',
"lhard;": '\U000021BD',
"lharu;": '\U000021BC',
"lharul;": '\U0000296A',
"lhblk;": '\U00002584',
"ljcy;": '\U00000459',
"ll;": '\U0000226A',
"llarr;": '\U000021C7',
"llcorner;": '\U0000231E',
"llhard;": '\U0000296B',
"lltri;": '\U000025FA',
"lmidot;": '\U00000140',
"lmoust;": '\U000023B0',
"lmoustache;": '\U000023B0',
"lnE;": '\U00002268',
"lnap;": '\U00002A89',
"lnapprox;": '\U00002A89',
"lne;": '\U00002A87',
"lneq;": '\U00002A87',
"lneqq;": '\U00002268',
"lnsim;": '\U000022E6',
"loang;": '\U000027EC',
"loarr;": '\U000021FD',
"lobrk;": '\U000027E6',
"longleftarrow;": '\U000027F5',
"longleftrightarrow;": '\U000027F7',
"longmapsto;": '\U000027FC',
"longrightarrow;": '\U000027F6',
"looparrowleft;": '\U000021AB',
"looparrowright;": '\U000021AC',
"lopar;": '\U00002985',
"lopf;": '\U0001D55D',
"loplus;": '\U00002A2D',
"lotimes;": '\U00002A34',
"lowast;": '\U00002217',
"lowbar;": '\U0000005F',
"loz;": '\U000025CA',
"lozenge;": '\U000025CA',
"lozf;": '\U000029EB',
"lpar;": '\U00000028',
"lparlt;": '\U00002993',
"lrarr;": '\U000021C6',
"lrcorner;": '\U0000231F',
"lrhar;": '\U000021CB',
"lrhard;": '\U0000296D',
"lrm;": '\U0000200E',
"lrtri;": '\U000022BF',
"lsaquo;": '\U00002039',
"lscr;": '\U0001D4C1',
"lsh;": '\U000021B0',
"lsim;": '\U00002272',
"lsime;": '\U00002A8D',
"lsimg;": '\U00002A8F',
"lsqb;": '\U0000005B',
"lsquo;": '\U00002018',
"lsquor;": '\U0000201A',
"lstrok;": '\U00000142',
"lt;": '\U0000003C',
"ltcc;": '\U00002AA6',
"ltcir;": '\U00002A79',
"ltdot;": '\U000022D6',
"lthree;": '\U000022CB',
"ltimes;": '\U000022C9',
"ltlarr;": '\U00002976',
"ltquest;": '\U00002A7B',
"ltrPar;": '\U00002996',
"ltri;": '\U000025C3',
"ltrie;": '\U000022B4',
"ltrif;": '\U000025C2',
"lurdshar;": '\U0000294A',
"luruhar;": '\U00002966',
"mDDot;": '\U0000223A',
"macr;": '\U000000AF',
"male;": '\U00002642',
"malt;": '\U00002720',
"maltese;": '\U00002720',
"map;": '\U000021A6',
"mapsto;": '\U000021A6',
"mapstodown;": '\U000021A7',
"mapstoleft;": '\U000021A4',
"mapstoup;": '\U000021A5',
"marker;": '\U000025AE',
"mcomma;": '\U00002A29',
"mcy;": '\U0000043C',
"mdash;": '\U00002014',
"measuredangle;": '\U00002221',
"mfr;": '\U0001D52A',
"mho;": '\U00002127',
"micro;": '\U000000B5',
"mid;": '\U00002223',
"midast;": '\U0000002A',
"midcir;": '\U00002AF0',
"middot;": '\U000000B7',
"minus;": '\U00002212',
"minusb;": '\U0000229F',
"minusd;": '\U00002238',
"minusdu;": '\U00002A2A',
"mlcp;": '\U00002ADB',
"mldr;": '\U00002026',
"mnplus;": '\U00002213',
"models;": '\U000022A7',
"mopf;": '\U0001D55E',
"mp;": '\U00002213',
"mscr;": '\U0001D4C2',
"mstpos;": '\U0000223E',
"mu;": '\U000003BC',
"multimap;": '\U000022B8',
"mumap;": '\U000022B8',
"nLeftarrow;": '\U000021CD',
"nLeftrightarrow;": '\U000021CE',
"nRightarrow;": '\U000021CF',
"nVDash;": '\U000022AF',
"nVdash;": '\U000022AE',
"nabla;": '\U00002207',
"nacute;": '\U00000144',
"nap;": '\U00002249',
"napos;": '\U00000149',
"napprox;": '\U00002249',
"natur;": '\U0000266E',
"natural;": '\U0000266E',
"naturals;": '\U00002115',
"nbsp;": '\U000000A0',
"ncap;": '\U00002A43',
"ncaron;": '\U00000148',
"ncedil;": '\U00000146',
"ncong;": '\U00002247',
"ncup;": '\U00002A42',
"ncy;": '\U0000043D',
"ndash;": '\U00002013',
"ne;": '\U00002260',
"neArr;": '\U000021D7',
"nearhk;": '\U00002924',
"nearr;": '\U00002197',
"nearrow;": '\U00002197',
"nequiv;": '\U00002262',
"nesear;": '\U00002928',
"nexist;": '\U00002204',
"nexists;": '\U00002204',
"nfr;": '\U0001D52B',
"nge;": '\U00002271',
"ngeq;": '\U00002271',
"ngsim;": '\U00002275',
"ngt;": '\U0000226F',
"ngtr;": '\U0000226F',
"nhArr;": '\U000021CE',
"nharr;": '\U000021AE',
"nhpar;": '\U00002AF2',
"ni;": '\U0000220B',
"nis;": '\U000022FC',
"nisd;": '\U000022FA',
"niv;": '\U0000220B',
"njcy;": '\U0000045A',
"nlArr;": '\U000021CD',
"nlarr;": '\U0000219A',
"nldr;": '\U00002025',
"nle;": '\U00002270',
"nleftarrow;": '\U0000219A',
"nleftrightarrow;": '\U000021AE',
"nleq;": '\U00002270',
"nless;": '\U0000226E',
"nlsim;": '\U00002274',
"nlt;": '\U0000226E',
"nltri;": '\U000022EA',
"nltrie;": '\U000022EC',
"nmid;": '\U00002224',
"nopf;": '\U0001D55F',
"not;": '\U000000AC',
"notin;": '\U00002209',
"notinva;": '\U00002209',
"notinvb;": '\U000022F7',
"notinvc;": '\U000022F6',
"notni;": '\U0000220C',
"notniva;": '\U0000220C',
"notnivb;": '\U000022FE',
"notnivc;": '\U000022FD',
"npar;": '\U00002226',
"nparallel;": '\U00002226',
"npolint;": '\U00002A14',
"npr;": '\U00002280',
"nprcue;": '\U000022E0',
"nprec;": '\U00002280',
"nrArr;": '\U000021CF',
"nrarr;": '\U0000219B',
"nrightarrow;": '\U0000219B',
"nrtri;": '\U000022EB',
"nrtrie;": '\U000022ED',
"nsc;": '\U00002281',
"nsccue;": '\U000022E1',
"nscr;": '\U0001D4C3',
"nshortmid;": '\U00002224',
"nshortparallel;": '\U00002226',
"nsim;": '\U00002241',
"nsime;": '\U00002244',
"nsimeq;": '\U00002244',
"nsmid;": '\U00002224',
"nspar;": '\U00002226',
"nsqsube;": '\U000022E2',
"nsqsupe;": '\U000022E3',
"nsub;": '\U00002284',
"nsube;": '\U00002288',
"nsubseteq;": '\U00002288',
"nsucc;": '\U00002281',
"nsup;": '\U00002285',
"nsupe;": '\U00002289',
"nsupseteq;": '\U00002289',
"ntgl;": '\U00002279',
"ntilde;": '\U000000F1',
"ntlg;": '\U00002278',
"ntriangleleft;": '\U000022EA',
"ntrianglelefteq;": '\U000022EC',
"ntriangleright;": '\U000022EB',
"ntrianglerighteq;": '\U000022ED',
"nu;": '\U000003BD',
"num;": '\U00000023',
"numero;": '\U00002116',
"numsp;": '\U00002007',
"nvDash;": '\U000022AD',
"nvHarr;": '\U00002904',
"nvdash;": '\U000022AC',
"nvinfin;": '\U000029DE',
"nvlArr;": '\U00002902',
"nvrArr;": '\U00002903',
"nwArr;": '\U000021D6',
"nwarhk;": '\U00002923',
"nwarr;": '\U00002196',
"nwarrow;": '\U00002196',
"nwnear;": '\U00002927',
"oS;": '\U000024C8',
"oacute;": '\U000000F3',
"oast;": '\U0000229B',
"ocir;": '\U0000229A',
"ocirc;": '\U000000F4',
"ocy;": '\U0000043E',
"odash;": '\U0000229D',
"odblac;": '\U00000151',
"odiv;": '\U00002A38',
"odot;": '\U00002299',
"odsold;": '\U000029BC',
"oelig;": '\U00000153',
"ofcir;": '\U000029BF',
"ofr;": '\U0001D52C',
"ogon;": '\U000002DB',
"ograve;": '\U000000F2',
"ogt;": '\U000029C1',
"ohbar;": '\U000029B5',
"ohm;": '\U000003A9',
"oint;": '\U0000222E',
"olarr;": '\U000021BA',
"olcir;": '\U000029BE',
"olcross;": '\U000029BB',
"oline;": '\U0000203E',
"olt;": '\U000029C0',
"omacr;": '\U0000014D',
"omega;": '\U000003C9',
"omicron;": '\U000003BF',
"omid;": '\U000029B6',
"ominus;": '\U00002296',
"oopf;": '\U0001D560',
"opar;": '\U000029B7',
"operp;": '\U000029B9',
"oplus;": '\U00002295',
"or;": '\U00002228',
"orarr;": '\U000021BB',
"ord;": '\U00002A5D',
"order;": '\U00002134',
"orderof;": '\U00002134',
"ordf;": '\U000000AA',
"ordm;": '\U000000BA',
"origof;": '\U000022B6',
"oror;": '\U00002A56',
"orslope;": '\U00002A57',
"orv;": '\U00002A5B',
"oscr;": '\U00002134',
"oslash;": '\U000000F8',
"osol;": '\U00002298',
"otilde;": '\U000000F5',
"otimes;": '\U00002297',
"otimesas;": '\U00002A36',
"ouml;": '\U000000F6',
"ovbar;": '\U0000233D',
"par;": '\U00002225',
"para;": '\U000000B6',
"parallel;": '\U00002225',
"parsim;": '\U00002AF3',
"parsl;": '\U00002AFD',
"part;": '\U00002202',
"pcy;": '\U0000043F',
"percnt;": '\U00000025',
"period;": '\U0000002E',
"permil;": '\U00002030',
"perp;": '\U000022A5',
"pertenk;": '\U00002031',
"pfr;": '\U0001D52D',
"phi;": '\U000003C6',
"phiv;": '\U000003D5',
"phmmat;": '\U00002133',
"phone;": '\U0000260E',
"pi;": '\U000003C0',
"pitchfork;": '\U000022D4',
"piv;": '\U000003D6',
"planck;": '\U0000210F',
"planckh;": '\U0000210E',
"plankv;": '\U0000210F',
"plus;": '\U0000002B',
"plusacir;": '\U00002A23',
"plusb;": '\U0000229E',
"pluscir;": '\U00002A22',
"plusdo;": '\U00002214',
"plusdu;": '\U00002A25',
"pluse;": '\U00002A72',
"plusmn;": '\U000000B1',
"plussim;": '\U00002A26',
"plustwo;": '\U00002A27',
"pm;": '\U000000B1',
"pointint;": '\U00002A15',
"popf;": '\U0001D561',
"pound;": '\U000000A3',
"pr;": '\U0000227A',
"prE;": '\U00002AB3',
"prap;": '\U00002AB7',
"prcue;": '\U0000227C',
"pre;": '\U00002AAF',
"prec;": '\U0000227A',
"precapprox;": '\U00002AB7',
"preccurlyeq;": '\U0000227C',
"preceq;": '\U00002AAF',
"precnapprox;": '\U00002AB9',
"precneqq;": '\U00002AB5',
"precnsim;": '\U000022E8',
"precsim;": '\U0000227E',
"prime;": '\U00002032',
"primes;": '\U00002119',
"prnE;": '\U00002AB5',
"prnap;": '\U00002AB9',
"prnsim;": '\U000022E8',
"prod;": '\U0000220F',
"profalar;": '\U0000232E',
"profline;": '\U00002312',
"profsurf;": '\U00002313',
"prop;": '\U0000221D',
"propto;": '\U0000221D',
"prsim;": '\U0000227E',
"prurel;": '\U000022B0',
"pscr;": '\U0001D4C5',
"psi;": '\U000003C8',
"puncsp;": '\U00002008',
"qfr;": '\U0001D52E',
"qint;": '\U00002A0C',
"qopf;": '\U0001D562',
"qprime;": '\U00002057',
"qscr;": '\U0001D4C6',
"quaternions;": '\U0000210D',
"quatint;": '\U00002A16',
"quest;": '\U0000003F',
"questeq;": '\U0000225F',
"quot;": '\U00000022',
"rAarr;": '\U000021DB',
"rArr;": '\U000021D2',
"rAtail;": '\U0000291C',
"rBarr;": '\U0000290F',
"rHar;": '\U00002964',
"racute;": '\U00000155',
"radic;": '\U0000221A',
"raemptyv;": '\U000029B3',
"rang;": '\U000027E9',
"rangd;": '\U00002992',
"range;": '\U000029A5',
"rangle;": '\U000027E9',
"raquo;": '\U000000BB',
"rarr;": '\U00002192',
"rarrap;": '\U00002975',
"rarrb;": '\U000021E5',
"rarrbfs;": '\U00002920',
"rarrc;": '\U00002933',
"rarrfs;": '\U0000291E',
"rarrhk;": '\U000021AA',
"rarrlp;": '\U000021AC',
"rarrpl;": '\U00002945',
"rarrsim;": '\U00002974',
"rarrtl;": '\U000021A3',
"rarrw;": '\U0000219D',
"ratail;": '\U0000291A',
"ratio;": '\U00002236',
"rationals;": '\U0000211A',
"rbarr;": '\U0000290D',
"rbbrk;": '\U00002773',
"rbrace;": '\U0000007D',
"rbrack;": '\U0000005D',
"rbrke;": '\U0000298C',
"rbrksld;": '\U0000298E',
"rbrkslu;": '\U00002990',
"rcaron;": '\U00000159',
"rcedil;": '\U00000157',
"rceil;": '\U00002309',
"rcub;": '\U0000007D',
"rcy;": '\U00000440',
"rdca;": '\U00002937',
"rdldhar;": '\U00002969',
"rdquo;": '\U0000201D',
"rdquor;": '\U0000201D',
"rdsh;": '\U000021B3',
"real;": '\U0000211C',
"realine;": '\U0000211B',
"realpart;": '\U0000211C',
"reals;": '\U0000211D',
"rect;": '\U000025AD',
"reg;": '\U000000AE',
"rfisht;": '\U0000297D',
"rfloor;": '\U0000230B',
"rfr;": '\U0001D52F',
"rhard;": '\U000021C1',
"rharu;": '\U000021C0',
"rharul;": '\U0000296C',
"rho;": '\U000003C1',
"rhov;": '\U000003F1',
"rightarrow;": '\U00002192',
"rightarrowtail;": '\U000021A3',
"rightharpoondown;": '\U000021C1',
"rightharpoonup;": '\U000021C0',
"rightleftarrows;": '\U000021C4',
"rightleftharpoons;": '\U000021CC',
"rightrightarrows;": '\U000021C9',
"rightsquigarrow;": '\U0000219D',
"rightthreetimes;": '\U000022CC',
"ring;": '\U000002DA',
"risingdotseq;": '\U00002253',
"rlarr;": '\U000021C4',
"rlhar;": '\U000021CC',
"rlm;": '\U0000200F',
"rmoust;": '\U000023B1',
"rmoustache;": '\U000023B1',
"rnmid;": '\U00002AEE',
"roang;": '\U000027ED',
"roarr;": '\U000021FE',
"robrk;": '\U000027E7',
"ropar;": '\U00002986',
"ropf;": '\U0001D563',
"roplus;": '\U00002A2E',
"rotimes;": '\U00002A35',
"rpar;": '\U00000029',
"rpargt;": '\U00002994',
"rppolint;": '\U00002A12',
"rrarr;": '\U000021C9',
"rsaquo;": '\U0000203A',
"rscr;": '\U0001D4C7',
"rsh;": '\U000021B1',
"rsqb;": '\U0000005D',
"rsquo;": '\U00002019',
"rsquor;": '\U00002019',
"rthree;": '\U000022CC',
"rtimes;": '\U000022CA',
"rtri;": '\U000025B9',
"rtrie;": '\U000022B5',
"rtrif;": '\U000025B8',
"rtriltri;": '\U000029CE',
"ruluhar;": '\U00002968',
"rx;": '\U0000211E',
"sacute;": '\U0000015B',
"sbquo;": '\U0000201A',
"sc;": '\U0000227B',
"scE;": '\U00002AB4',
"scap;": '\U00002AB8',
"scaron;": '\U00000161',
"sccue;": '\U0000227D',
"sce;": '\U00002AB0',
"scedil;": '\U0000015F',
"scirc;": '\U0000015D',
"scnE;": '\U00002AB6',
"scnap;": '\U00002ABA',
"scnsim;": '\U000022E9',
"scpolint;": '\U00002A13',
"scsim;": '\U0000227F',
"scy;": '\U00000441',
"sdot;": '\U000022C5',
"sdotb;": '\U000022A1',
"sdote;": '\U00002A66',
"seArr;": '\U000021D8',
"searhk;": '\U00002925',
"searr;": '\U00002198',
"searrow;": '\U00002198',
"sect;": '\U000000A7',
"semi;": '\U0000003B',
"seswar;": '\U00002929',
"setminus;": '\U00002216',
"setmn;": '\U00002216',
"sext;": '\U00002736',
"sfr;": '\U0001D530',
"sfrown;": '\U00002322',
"sharp;": '\U0000266F',
"shchcy;": '\U00000449',
"shcy;": '\U00000448',
"shortmid;": '\U00002223',
"shortparallel;": '\U00002225',
"shy;": '\U000000AD',
"sigma;": '\U000003C3',
"sigmaf;": '\U000003C2',
"sigmav;": '\U000003C2',
"sim;": '\U0000223C',
"simdot;": '\U00002A6A',
"sime;": '\U00002243',
"simeq;": '\U00002243',
"simg;": '\U00002A9E',
"simgE;": '\U00002AA0',
"siml;": '\U00002A9D',
"simlE;": '\U00002A9F',
"simne;": '\U00002246',
"simplus;": '\U00002A24',
"simrarr;": '\U00002972',
"slarr;": '\U00002190',
"smallsetminus;": '\U00002216',
"smashp;": '\U00002A33',
"smeparsl;": '\U000029E4',
"smid;": '\U00002223',
"smile;": '\U00002323',
"smt;": '\U00002AAA',
"smte;": '\U00002AAC',
"softcy;": '\U0000044C',
"sol;": '\U0000002F',
"solb;": '\U000029C4',
"solbar;": '\U0000233F',
"sopf;": '\U0001D564',
"spades;": '\U00002660',
"spadesuit;": '\U00002660',
"spar;": '\U00002225',
"sqcap;": '\U00002293',
"sqcup;": '\U00002294',
"sqsub;": '\U0000228F',
"sqsube;": '\U00002291',
"sqsubset;": '\U0000228F',
"sqsubseteq;": '\U00002291',
"sqsup;": '\U00002290',
"sqsupe;": '\U00002292',
"sqsupset;": '\U00002290',
"sqsupseteq;": '\U00002292',
"squ;": '\U000025A1',
"square;": '\U000025A1',
"squarf;": '\U000025AA',
"squf;": '\U000025AA',
"srarr;": '\U00002192',
"sscr;": '\U0001D4C8',
"ssetmn;": '\U00002216',
"ssmile;": '\U00002323',
"sstarf;": '\U000022C6',
"star;": '\U00002606',
"starf;": '\U00002605',
"straightepsilon;": '\U000003F5',
"straightphi;": '\U000003D5',
"strns;": '\U000000AF',
"sub;": '\U00002282',
"subE;": '\U00002AC5',
"subdot;": '\U00002ABD',
"sube;": '\U00002286',
"subedot;": '\U00002AC3',
"submult;": '\U00002AC1',
"subnE;": '\U00002ACB',
"subne;": '\U0000228A',
"subplus;": '\U00002ABF',
"subrarr;": '\U00002979',
"subset;": '\U00002282',
"subseteq;": '\U00002286',
"subseteqq;": '\U00002AC5',
"subsetneq;": '\U0000228A',
"subsetneqq;": '\U00002ACB',
"subsim;": '\U00002AC7',
"subsub;": '\U00002AD5',
"subsup;": '\U00002AD3',
"succ;": '\U0000227B',
"succapprox;": '\U00002AB8',
"succcurlyeq;": '\U0000227D',
"succeq;": '\U00002AB0',
"succnapprox;": '\U00002ABA',
"succneqq;": '\U00002AB6',
"succnsim;": '\U000022E9',
"succsim;": '\U0000227F',
"sum;": '\U00002211',
"sung;": '\U0000266A',
"sup;": '\U00002283',
"sup1;": '\U000000B9',
"sup2;": '\U000000B2',
"sup3;": '\U000000B3',
"supE;": '\U00002AC6',
"supdot;": '\U00002ABE',
"supdsub;": '\U00002AD8',
"supe;": '\U00002287',
"supedot;": '\U00002AC4',
"suphsol;": '\U000027C9',
"suphsub;": '\U00002AD7',
"suplarr;": '\U0000297B',
"supmult;": '\U00002AC2',
"supnE;": '\U00002ACC',
"supne;": '\U0000228B',
"supplus;": '\U00002AC0',
"supset;": '\U00002283',
"supseteq;": '\U00002287',
"supseteqq;": '\U00002AC6',
"supsetneq;": '\U0000228B',
"supsetneqq;": '\U00002ACC',
"supsim;": '\U00002AC8',
"supsub;": '\U00002AD4',
"supsup;": '\U00002AD6',
"swArr;": '\U000021D9',
"swarhk;": '\U00002926',
"swarr;": '\U00002199',
"swarrow;": '\U00002199',
"swnwar;": '\U0000292A',
"szlig;": '\U000000DF',
"target;": '\U00002316',
"tau;": '\U000003C4',
"tbrk;": '\U000023B4',
"tcaron;": '\U00000165',
"tcedil;": '\U00000163',
"tcy;": '\U00000442',
"tdot;": '\U000020DB',
"telrec;": '\U00002315',
"tfr;": '\U0001D531',
"there4;": '\U00002234',
"therefore;": '\U00002234',
"theta;": '\U000003B8',
"thetasym;": '\U000003D1',
"thetav;": '\U000003D1',
"thickapprox;": '\U00002248',
"thicksim;": '\U0000223C',
"thinsp;": '\U00002009',
"thkap;": '\U00002248',
"thksim;": '\U0000223C',
"thorn;": '\U000000FE',
"tilde;": '\U000002DC',
"times;": '\U000000D7',
"timesb;": '\U000022A0',
"timesbar;": '\U00002A31',
"timesd;": '\U00002A30',
"tint;": '\U0000222D',
"toea;": '\U00002928',
"top;": '\U000022A4',
"topbot;": '\U00002336',
"topcir;": '\U00002AF1',
"topf;": '\U0001D565',
"topfork;": '\U00002ADA',
"tosa;": '\U00002929',
"tprime;": '\U00002034',
"trade;": '\U00002122',
"triangle;": '\U000025B5',
"triangledown;": '\U000025BF',
"triangleleft;": '\U000025C3',
"trianglelefteq;": '\U000022B4',
"triangleq;": '\U0000225C',
"triangleright;": '\U000025B9',
"trianglerighteq;": '\U000022B5',
"tridot;": '\U000025EC',
"trie;": '\U0000225C',
"triminus;": '\U00002A3A',
"triplus;": '\U00002A39',
"trisb;": '\U000029CD',
"tritime;": '\U00002A3B',
"trpezium;": '\U000023E2',
"tscr;": '\U0001D4C9',
"tscy;": '\U00000446',
"tshcy;": '\U0000045B',
"tstrok;": '\U00000167',
"twixt;": '\U0000226C',
"twoheadleftarrow;": '\U0000219E',
"twoheadrightarrow;": '\U000021A0',
"uArr;": '\U000021D1',
"uHar;": '\U00002963',
"uacute;": '\U000000FA',
"uarr;": '\U00002191',
"ubrcy;": '\U0000045E',
"ubreve;": '\U0000016D',
"ucirc;": '\U000000FB',
"ucy;": '\U00000443',
"udarr;": '\U000021C5',
"udblac;": '\U00000171',
"udhar;": '\U0000296E',
"ufisht;": '\U0000297E',
"ufr;": '\U0001D532',
"ugrave;": '\U000000F9',
"uharl;": '\U000021BF',
"uharr;": '\U000021BE',
"uhblk;": '\U00002580',
"ulcorn;": '\U0000231C',
"ulcorner;": '\U0000231C',
"ulcrop;": '\U0000230F',
"ultri;": '\U000025F8',
"umacr;": '\U0000016B',
"uml;": '\U000000A8',
"uogon;": '\U00000173',
"uopf;": '\U0001D566',
"uparrow;": '\U00002191',
"updownarrow;": '\U00002195',
"upharpoonleft;": '\U000021BF',
"upharpoonright;": '\U000021BE',
"uplus;": '\U0000228E',
"upsi;": '\U000003C5',
"upsih;": '\U000003D2',
"upsilon;": '\U000003C5',
"upuparrows;": '\U000021C8',
"urcorn;": '\U0000231D',
"urcorner;": '\U0000231D',
"urcrop;": '\U0000230E',
"uring;": '\U0000016F',
"urtri;": '\U000025F9',
"uscr;": '\U0001D4CA',
"utdot;": '\U000022F0',
"utilde;": '\U00000169',
"utri;": '\U000025B5',
"utrif;": '\U000025B4',
"uuarr;": '\U000021C8',
"uuml;": '\U000000FC',
"uwangle;": '\U000029A7',
"vArr;": '\U000021D5',
"vBar;": '\U00002AE8',
"vBarv;": '\U00002AE9',
"vDash;": '\U000022A8',
"vangrt;": '\U0000299C',
"varepsilon;": '\U000003F5',
"varkappa;": '\U000003F0',
"varnothing;": '\U00002205',
"varphi;": '\U000003D5',
"varpi;": '\U000003D6',
"varpropto;": '\U0000221D',
"varr;": '\U00002195',
"varrho;": '\U000003F1',
"varsigma;": '\U000003C2',
"vartheta;": '\U000003D1',
"vartriangleleft;": '\U000022B2',
"vartriangleright;": '\U000022B3',
"vcy;": '\U00000432',
"vdash;": '\U000022A2',
"vee;": '\U00002228',
"veebar;": '\U000022BB',
"veeeq;": '\U0000225A',
"vellip;": '\U000022EE',
"verbar;": '\U0000007C',
"vert;": '\U0000007C',
"vfr;": '\U0001D533',
"vltri;": '\U000022B2',
"vopf;": '\U0001D567',
"vprop;": '\U0000221D',
"vrtri;": '\U000022B3',
"vscr;": '\U0001D4CB',
"vzigzag;": '\U0000299A',
"wcirc;": '\U00000175',
"wedbar;": '\U00002A5F',
"wedge;": '\U00002227',
"wedgeq;": '\U00002259',
"weierp;": '\U00002118',
"wfr;": '\U0001D534',
"wopf;": '\U0001D568',
"wp;": '\U00002118',
"wr;": '\U00002240',
"wreath;": '\U00002240',
"wscr;": '\U0001D4CC',
"xcap;": '\U000022C2',
"xcirc;": '\U000025EF',
"xcup;": '\U000022C3',
"xdtri;": '\U000025BD',
"xfr;": '\U0001D535',
"xhArr;": '\U000027FA',
"xharr;": '\U000027F7',
"xi;": '\U000003BE',
"xlArr;": '\U000027F8',
"xlarr;": '\U000027F5',
"xmap;": '\U000027FC',
"xnis;": '\U000022FB',
"xodot;": '\U00002A00',
"xopf;": '\U0001D569',
"xoplus;": '\U00002A01',
"xotime;": '\U00002A02',
"xrArr;": '\U000027F9',
"xrarr;": '\U000027F6',
"xscr;": '\U0001D4CD',
"xsqcup;": '\U00002A06',
"xuplus;": '\U00002A04',
"xutri;": '\U000025B3',
"xvee;": '\U000022C1',
"xwedge;": '\U000022C0',
"yacute;": '\U000000FD',
"yacy;": '\U0000044F',
"ycirc;": '\U00000177',
"ycy;": '\U0000044B',
"yen;": '\U000000A5',
"yfr;": '\U0001D536',
"yicy;": '\U00000457',
"yopf;": '\U0001D56A',
"yscr;": '\U0001D4CE',
"yucy;": '\U0000044E',
"yuml;": '\U000000FF',
"zacute;": '\U0000017A',
"zcaron;": '\U0000017E',
"zcy;": '\U00000437',
"zdot;": '\U0000017C',
"zeetrf;": '\U00002128',
"zeta;": '\U000003B6',
"zfr;": '\U0001D537',
"zhcy;": '\U00000436',
"zigrarr;": '\U000021DD',
"zopf;": '\U0001D56B',
"zscr;": '\U0001D4CF',
"zwj;": '\U0000200D',
"zwnj;": '\U0000200C',
"AElig": '\U000000C6',
"AMP": '\U00000026',
"Aacute": '\U000000C1',
"Acirc": '\U000000C2',
"Agrave": '\U000000C0',
"Aring": '\U000000C5',
"Atilde": '\U000000C3',
"Auml": '\U000000C4',
"COPY": '\U000000A9',
"Ccedil": '\U000000C7',
"ETH": '\U000000D0',
"Eacute": '\U000000C9',
"Ecirc": '\U000000CA',
"Egrave": '\U000000C8',
"Euml": '\U000000CB',
"GT": '\U0000003E',
"Iacute": '\U000000CD',
"Icirc": '\U000000CE',
"Igrave": '\U000000CC',
"Iuml": '\U000000CF',
"LT": '\U0000003C',
"Ntilde": '\U000000D1',
"Oacute": '\U000000D3',
"Ocirc": '\U000000D4',
"Ograve": '\U000000D2',
"Oslash": '\U000000D8',
"Otilde": '\U000000D5',
"Ouml": '\U000000D6',
"QUOT": '\U00000022',
"REG": '\U000000AE',
"THORN": '\U000000DE',
"Uacute": '\U000000DA',
"Ucirc": '\U000000DB',
"Ugrave": '\U000000D9',
"Uuml": '\U000000DC',
"Yacute": '\U000000DD',
"aacute": '\U000000E1',
"acirc": '\U000000E2',
"acute": '\U000000B4',
"aelig": '\U000000E6',
"agrave": '\U000000E0',
"amp": '\U00000026',
"aring": '\U000000E5',
"atilde": '\U000000E3',
"auml": '\U000000E4',
"brvbar": '\U000000A6',
"ccedil": '\U000000E7',
"cedil": '\U000000B8',
"cent": '\U000000A2',
"copy": '\U000000A9',
"curren": '\U000000A4',
"deg": '\U000000B0',
"divide": '\U000000F7',
"eacute": '\U000000E9',
"ecirc": '\U000000EA',
"egrave": '\U000000E8',
"eth": '\U000000F0',
"euml": '\U000000EB',
"frac12": '\U000000BD',
"frac14": '\U000000BC',
"frac34": '\U000000BE',
"gt": '\U0000003E',
"iacute": '\U000000ED',
"icirc": '\U000000EE',
"iexcl": '\U000000A1',
"igrave": '\U000000EC',
"iquest": '\U000000BF',
"iuml": '\U000000EF',
"laquo": '\U000000AB',
"lt": '\U0000003C',
"macr": '\U000000AF',
"micro": '\U000000B5',
"middot": '\U000000B7',
"nbsp": '\U000000A0',
"not": '\U000000AC',
"ntilde": '\U000000F1',
"oacute": '\U000000F3',
"ocirc": '\U000000F4',
"ograve": '\U000000F2',
"ordf": '\U000000AA',
"ordm": '\U000000BA',
"oslash": '\U000000F8',
"otilde": '\U000000F5',
"ouml": '\U000000F6',
"para": '\U000000B6',
"plusmn": '\U000000B1',
"pound": '\U000000A3',
"quot": '\U00000022',
"raquo": '\U000000BB',
"reg": '\U000000AE',
"sect": '\U000000A7',
"shy": '\U000000AD',
"sup1": '\U000000B9',
"sup2": '\U000000B2',
"sup3": '\U000000B3',
"szlig": '\U000000DF',
"thorn": '\U000000FE',
"times": '\U000000D7',
"uacute": '\U000000FA',
"ucirc": '\U000000FB',
"ugrave": '\U000000F9',
"uml": '\U000000A8',
"uuml": '\U000000FC',
"yacute": '\U000000FD',
"yen": '\U000000A5',
"yuml": '\U000000FF',
}
// HTML entities that are two unicode codepoints.
var entity2 = map[string][2]rune{
// TODO(nigeltao): Handle replacements that are wider than their names.
// "nLt;": {'\u226A', '\u20D2'},
// "nGt;": {'\u226B', '\u20D2'},
"NotEqualTilde;": {'\u2242', '\u0338'},
"NotGreaterFullEqual;": {'\u2267', '\u0338'},
"NotGreaterGreater;": {'\u226B', '\u0338'},
"NotGreaterSlantEqual;": {'\u2A7E', '\u0338'},
"NotHumpDownHump;": {'\u224E', '\u0338'},
"NotHumpEqual;": {'\u224F', '\u0338'},
"NotLeftTriangleBar;": {'\u29CF', '\u0338'},
"NotLessLess;": {'\u226A', '\u0338'},
"NotLessSlantEqual;": {'\u2A7D', '\u0338'},
"NotNestedGreaterGreater;": {'\u2AA2', '\u0338'},
"NotNestedLessLess;": {'\u2AA1', '\u0338'},
"NotPrecedesEqual;": {'\u2AAF', '\u0338'},
"NotRightTriangleBar;": {'\u29D0', '\u0338'},
"NotSquareSubset;": {'\u228F', '\u0338'},
"NotSquareSuperset;": {'\u2290', '\u0338'},
"NotSubset;": {'\u2282', '\u20D2'},
"NotSucceedsEqual;": {'\u2AB0', '\u0338'},
"NotSucceedsTilde;": {'\u227F', '\u0338'},
"NotSuperset;": {'\u2283', '\u20D2'},
"ThickSpace;": {'\u205F', '\u200A'},
"acE;": {'\u223E', '\u0333'},
"bne;": {'\u003D', '\u20E5'},
"bnequiv;": {'\u2261', '\u20E5'},
"caps;": {'\u2229', '\uFE00'},
"cups;": {'\u222A', '\uFE00'},
"fjlig;": {'\u0066', '\u006A'},
"gesl;": {'\u22DB', '\uFE00'},
"gvertneqq;": {'\u2269', '\uFE00'},
"gvnE;": {'\u2269', '\uFE00'},
"lates;": {'\u2AAD', '\uFE00'},
"lesg;": {'\u22DA', '\uFE00'},
"lvertneqq;": {'\u2268', '\uFE00'},
"lvnE;": {'\u2268', '\uFE00'},
"nGg;": {'\u22D9', '\u0338'},
"nGtv;": {'\u226B', '\u0338'},
"nLl;": {'\u22D8', '\u0338'},
"nLtv;": {'\u226A', '\u0338'},
"nang;": {'\u2220', '\u20D2'},
"napE;": {'\u2A70', '\u0338'},
"napid;": {'\u224B', '\u0338'},
"nbump;": {'\u224E', '\u0338'},
"nbumpe;": {'\u224F', '\u0338'},
"ncongdot;": {'\u2A6D', '\u0338'},
"nedot;": {'\u2250', '\u0338'},
"nesim;": {'\u2242', '\u0338'},
"ngE;": {'\u2267', '\u0338'},
"ngeqq;": {'\u2267', '\u0338'},
"ngeqslant;": {'\u2A7E', '\u0338'},
"nges;": {'\u2A7E', '\u0338'},
"nlE;": {'\u2266', '\u0338'},
"nleqq;": {'\u2266', '\u0338'},
"nleqslant;": {'\u2A7D', '\u0338'},
"nles;": {'\u2A7D', '\u0338'},
"notinE;": {'\u22F9', '\u0338'},
"notindot;": {'\u22F5', '\u0338'},
"nparsl;": {'\u2AFD', '\u20E5'},
"npart;": {'\u2202', '\u0338'},
"npre;": {'\u2AAF', '\u0338'},
"npreceq;": {'\u2AAF', '\u0338'},
"nrarrc;": {'\u2933', '\u0338'},
"nrarrw;": {'\u219D', '\u0338'},
"nsce;": {'\u2AB0', '\u0338'},
"nsubE;": {'\u2AC5', '\u0338'},
"nsubset;": {'\u2282', '\u20D2'},
"nsubseteqq;": {'\u2AC5', '\u0338'},
"nsucceq;": {'\u2AB0', '\u0338'},
"nsupE;": {'\u2AC6', '\u0338'},
"nsupset;": {'\u2283', '\u20D2'},
"nsupseteqq;": {'\u2AC6', '\u0338'},
"nvap;": {'\u224D', '\u20D2'},
"nvge;": {'\u2265', '\u20D2'},
"nvgt;": {'\u003E', '\u20D2'},
"nvle;": {'\u2264', '\u20D2'},
"nvlt;": {'\u003C', '\u20D2'},
"nvltrie;": {'\u22B4', '\u20D2'},
"nvrtrie;": {'\u22B5', '\u20D2'},
"nvsim;": {'\u223C', '\u20D2'},
"race;": {'\u223D', '\u0331'},
"smtes;": {'\u2AAC', '\uFE00'},
"sqcaps;": {'\u2293', '\uFE00'},
"sqcups;": {'\u2294', '\uFE00'},
"varsubsetneq;": {'\u228A', '\uFE00'},
"varsubsetneqq;": {'\u2ACB', '\uFE00'},
"varsupsetneq;": {'\u228B', '\uFE00'},
"varsupsetneqq;": {'\u2ACC', '\uFE00'},
"vnsub;": {'\u2282', '\u20D2'},
"vnsup;": {'\u2283', '\u20D2'},
"vsubnE;": {'\u2ACB', '\uFE00'},
"vsubne;": {'\u228A', '\uFE00'},
"vsupnE;": {'\u2ACC', '\uFE00'},
"vsupne;": {'\u228B', '\uFE00'},
}
================================================
FILE: internal/escape.go
================================================
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
import (
"bytes"
"io"
"strings"
"unicode/utf8"
)
type writer interface {
io.Writer
io.ByteWriter
WriteString(string) (int, error)
}
// These replacements permit compatibility with old numeric entities that
// assumed Windows-1252 encoding.
// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
var replacementTable = [...]rune{
'\u20AC', // First entry is what 0x80 should be replaced with.
'\u0081',
'\u201A',
'\u0192',
'\u201E',
'\u2026',
'\u2020',
'\u2021',
'\u02C6',
'\u2030',
'\u0160',
'\u2039',
'\u0152',
'\u008D',
'\u017D',
'\u008F',
'\u0090',
'\u2018',
'\u2019',
'\u201C',
'\u201D',
'\u2022',
'\u2013',
'\u2014',
'\u02DC',
'\u2122',
'\u0161',
'\u203A',
'\u0153',
'\u009D',
'\u017E',
'\u0178', // Last entry is 0x9F.
// 0x00->'\uFFFD' is handled programmatically.
// 0x0D->'\u000D' is a no-op.
}
// unescapeEntity reads an entity like "<" from b[src:] and writes the
// corresponding "<" to b[dst:], returning the incremented dst and src cursors.
// Precondition: b[src] == '&' && dst <= src.
// attribute should be true if parsing an attribute value.
func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference
// i starts at 1 because we already know that s[0] == '&'.
i, s := 1, b[src:]
if len(s) <= 1 {
b[dst] = b[src]
return dst + 1, src + 1
}
if s[i] == '#' {
if len(s) <= 3 { // We need to have at least ".".
b[dst] = b[src]
return dst + 1, src + 1
}
i++
c := s[i]
hex := false
if c == 'x' || c == 'X' {
hex = true
i++
}
x := '\x00'
for i < len(s) {
c = s[i]
i++
if hex {
if '0' <= c && c <= '9' {
x = 16*x + rune(c) - '0'
continue
} else if 'a' <= c && c <= 'f' {
x = 16*x + rune(c) - 'a' + 10
continue
} else if 'A' <= c && c <= 'F' {
x = 16*x + rune(c) - 'A' + 10
continue
}
} else if '0' <= c && c <= '9' {
x = 10*x + rune(c) - '0'
continue
}
if c != ';' {
i--
}
break
}
if i <= 3 { // No characters matched.
b[dst] = b[src]
return dst + 1, src + 1
}
if 0x80 <= x && x <= 0x9F {
// Replace characters from Windows-1252 with UTF-8 equivalents.
x = replacementTable[x-0x80]
} else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF {
// Replace invalid characters with the replacement character.
x = '\uFFFD'
}
return dst + utf8.EncodeRune(b[dst:], x), src + i
}
// Consume the maximum number of characters possible, with the
// consumed characters matching one of the named references.
for i < len(s) {
c := s[i]
i++
// Lower-cased characters are more common in entities, so we check for them first.
if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' {
continue
}
if c != ';' {
i--
}
break
}
entityName := string(s[1:i])
if entityName == "" {
// No-op.
} else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' {
// No-op.
} else if x := entity[entityName]; x != 0 {
return dst + utf8.EncodeRune(b[dst:], x), src + i
} else if x := entity2[entityName]; x[0] != 0 {
dst1 := dst + utf8.EncodeRune(b[dst:], x[0])
return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i
} else if !attribute {
maxLen := len(entityName) - 1
if maxLen > longestEntityWithoutSemicolon {
maxLen = longestEntityWithoutSemicolon
}
for j := maxLen; j > 1; j-- {
if x := entity[entityName[:j]]; x != 0 {
return dst + utf8.EncodeRune(b[dst:], x), src + j + 1
}
}
}
dst1, src1 = dst+i, src+i
copy(b[dst:dst1], b[src:src1])
return dst1, src1
}
// unescape unescapes b's entities in-place, so that "a<b" becomes "a':
esc = ">"
case '"':
// """ is shorter than """.
esc = """
case '\r':
esc = "
"
default:
panic("unrecognized escape character")
}
s = s[i+1:]
if _, err := w.WriteString(esc); err != nil {
return err
}
i = strings.IndexAny(s, escapedChars)
}
_, err := w.WriteString(s)
return err
}
// EscapeString escapes special characters like "<" to become "<". It
// escapes only five such characters: <, >, &, ' and ".
// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
// always true.
func EscapeString(s string) string {
if !strings.ContainsAny(s, escapedChars) {
return s
}
var buf bytes.Buffer
escape(&buf, s)
return buf.String()
}
// UnescapeString unescapes entities like "<" to become "<". It unescapes a
// larger range of entities than EscapeString escapes. For example, "á"
// unescapes to "á", as does "á" and "&xE1;".
// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't
// always true.
func UnescapeString(s string) string {
for _, c := range s {
if c == '&' {
return string(unescape([]byte(s), false))
}
}
return s
}
================================================
FILE: internal/foreign.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
import (
"strings"
)
func adjustAttributeNames(aa []Attribute, nameMap map[string]string) {
for i := range aa {
if newName, ok := nameMap[aa[i].Key]; ok {
aa[i].Key = newName
}
}
}
func adjustForeignAttributes(aa []Attribute) {
for i, a := range aa {
if a.Key == "" || a.Key[0] != 'x' {
continue
}
switch a.Key {
case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show",
"xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink":
j := strings.Index(a.Key, ":")
aa[i].Namespace = a.Key[:j]
aa[i].Key = a.Key[j+1:]
}
}
}
func htmlIntegrationPoint(n *Node) bool {
if n.Type != ElementNode {
return false
}
switch n.Namespace {
case "math":
if n.Data == "annotation-xml" {
for _, a := range n.Attr {
if a.Key == "encoding" {
val := strings.ToLower(a.Val)
if val == "text/html" || val == "application/xhtml+xml" {
return true
}
}
}
}
case "svg":
switch n.Data {
case "desc", "foreignObject", "title":
return true
}
}
return false
}
func mathMLTextIntegrationPoint(n *Node) bool {
if n.Namespace != "math" {
return false
}
switch n.Data {
case "mi", "mo", "mn", "ms", "mtext":
return true
}
return false
}
// Section 12.2.6.5.
var breakout = map[string]bool{
"b": true,
"big": true,
"blockquote": true,
"body": true,
"br": true,
"center": true,
"code": true,
"dd": true,
"div": true,
"dl": true,
"dt": true,
"em": true,
"embed": true,
"h1": true,
"h2": true,
"h3": true,
"h4": true,
"h5": true,
"h6": true,
"head": true,
"hr": true,
"i": true,
"img": true,
"li": true,
"listing": true,
"menu": true,
"meta": true,
"nobr": true,
"ol": true,
"p": true,
"pre": true,
"ruby": true,
"s": true,
"small": true,
"span": true,
"strong": true,
"strike": true,
"sub": true,
"sup": true,
"table": true,
"tt": true,
"u": true,
"ul": true,
"var": true,
}
// Section 12.2.6.5.
var svgTagNameAdjustments = map[string]string{
"altglyph": "altGlyph",
"altglyphdef": "altGlyphDef",
"altglyphitem": "altGlyphItem",
"animatecolor": "animateColor",
"animatemotion": "animateMotion",
"animatetransform": "animateTransform",
"clippath": "clipPath",
"feblend": "feBlend",
"fecolormatrix": "feColorMatrix",
"fecomponenttransfer": "feComponentTransfer",
"fecomposite": "feComposite",
"feconvolvematrix": "feConvolveMatrix",
"fediffuselighting": "feDiffuseLighting",
"fedisplacementmap": "feDisplacementMap",
"fedistantlight": "feDistantLight",
"feflood": "feFlood",
"fefunca": "feFuncA",
"fefuncb": "feFuncB",
"fefuncg": "feFuncG",
"fefuncr": "feFuncR",
"fegaussianblur": "feGaussianBlur",
"feimage": "feImage",
"femerge": "feMerge",
"femergenode": "feMergeNode",
"femorphology": "feMorphology",
"feoffset": "feOffset",
"fepointlight": "fePointLight",
"fespecularlighting": "feSpecularLighting",
"fespotlight": "feSpotLight",
"fetile": "feTile",
"feturbulence": "feTurbulence",
"foreignobject": "foreignObject",
"glyphref": "glyphRef",
"lineargradient": "linearGradient",
"radialgradient": "radialGradient",
"textpath": "textPath",
}
// Section 12.2.6.1
var mathMLAttributeAdjustments = map[string]string{
"definitionurl": "definitionURL",
}
var svgAttributeAdjustments = map[string]string{
"attributename": "attributeName",
"attributetype": "attributeType",
"basefrequency": "baseFrequency",
"baseprofile": "baseProfile",
"calcmode": "calcMode",
"clippathunits": "clipPathUnits",
"diffuseconstant": "diffuseConstant",
"edgemode": "edgeMode",
"filterunits": "filterUnits",
"glyphref": "glyphRef",
"gradienttransform": "gradientTransform",
"gradientunits": "gradientUnits",
"kernelmatrix": "kernelMatrix",
"kernelunitlength": "kernelUnitLength",
"keypoints": "keyPoints",
"keysplines": "keySplines",
"keytimes": "keyTimes",
"lengthadjust": "lengthAdjust",
"limitingconeangle": "limitingConeAngle",
"markerheight": "markerHeight",
"markerunits": "markerUnits",
"markerwidth": "markerWidth",
"maskcontentunits": "maskContentUnits",
"maskunits": "maskUnits",
"numoctaves": "numOctaves",
"pathlength": "pathLength",
"patterncontentunits": "patternContentUnits",
"patterntransform": "patternTransform",
"patternunits": "patternUnits",
"pointsatx": "pointsAtX",
"pointsaty": "pointsAtY",
"pointsatz": "pointsAtZ",
"preservealpha": "preserveAlpha",
"preserveaspectratio": "preserveAspectRatio",
"primitiveunits": "primitiveUnits",
"refx": "refX",
"refy": "refY",
"repeatcount": "repeatCount",
"repeatdur": "repeatDur",
"requiredextensions": "requiredExtensions",
"requiredfeatures": "requiredFeatures",
"specularconstant": "specularConstant",
"specularexponent": "specularExponent",
"spreadmethod": "spreadMethod",
"startoffset": "startOffset",
"stddeviation": "stdDeviation",
"stitchtiles": "stitchTiles",
"surfacescale": "surfaceScale",
"systemlanguage": "systemLanguage",
"tablevalues": "tableValues",
"targetx": "targetX",
"targety": "targetY",
"textlength": "textLength",
"viewbox": "viewBox",
"viewtarget": "viewTarget",
"xchannelselector": "xChannelSelector",
"ychannelselector": "yChannelSelector",
"zoomandpan": "zoomAndPan",
}
================================================
FILE: internal/handler/handler.go
================================================
package handler
import (
"errors"
"strings"
"github.com/withastro/compiler/internal/loc"
"github.com/withastro/compiler/internal/sourcemap"
)
type Handler struct {
sourcetext string
filename string
builder sourcemap.ChunkBuilder
errors []error
warnings []error
infos []error
hints []error
}
func NewHandler(sourcetext string, filename string) *Handler {
return &Handler{
sourcetext: sourcetext,
filename: filename,
builder: sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(sourcetext, len(strings.Split(sourcetext, "\n")))),
errors: make([]error, 0),
warnings: make([]error, 0),
infos: make([]error, 0),
hints: make([]error, 0),
}
}
func (h *Handler) HasErrors() bool {
return len(h.errors) > 0
}
func (h *Handler) AppendError(err error) {
h.errors = append(h.errors, err)
}
func (h *Handler) AppendWarning(err error) {
h.warnings = append(h.warnings, err)
}
func (h *Handler) AppendInfo(err error) {
h.infos = append(h.infos, err)
}
func (h *Handler) AppendHint(err error) {
h.hints = append(h.hints, err)
}
func (h *Handler) Errors() []loc.DiagnosticMessage {
msgs := make([]loc.DiagnosticMessage, 0)
for _, err := range h.errors {
if err != nil {
msgs = append(msgs, ErrorToMessage(h, loc.ErrorType, err))
}
}
return msgs
}
func (h *Handler) Warnings() []loc.DiagnosticMessage {
msgs := make([]loc.DiagnosticMessage, 0)
for _, err := range h.warnings {
if err != nil {
msgs = append(msgs, ErrorToMessage(h, loc.WarningType, err))
}
}
return msgs
}
func (h *Handler) Diagnostics() []loc.DiagnosticMessage {
msgs := make([]loc.DiagnosticMessage, 0)
for _, err := range h.errors {
if err != nil {
msgs = append(msgs, ErrorToMessage(h, loc.ErrorType, err))
}
}
for _, err := range h.warnings {
if err != nil {
msgs = append(msgs, ErrorToMessage(h, loc.WarningType, err))
}
}
for _, err := range h.infos {
if err != nil {
msgs = append(msgs, ErrorToMessage(h, loc.InformationType, err))
}
}
for _, err := range h.hints {
if err != nil {
msgs = append(msgs, ErrorToMessage(h, loc.HintType, err))
}
}
return msgs
}
func ErrorToMessage(h *Handler, severity loc.DiagnosticSeverity, err error) loc.DiagnosticMessage {
var rangedError *loc.ErrorWithRange
switch {
case errors.As(err, &rangedError):
pos := h.builder.GetLineAndColumnForLocation(rangedError.Range.Loc)
location := &loc.DiagnosticLocation{
File: h.filename,
Line: pos[0],
Column: pos[1],
Length: rangedError.Range.Len,
}
message := rangedError.ToMessage(location)
message.Severity = int(severity)
return message
default:
return loc.DiagnosticMessage{Text: err.Error()}
}
}
================================================
FILE: internal/hash.go
================================================
package astro
import (
"encoding/base32"
"strings"
"github.com/withastro/compiler/internal/xxhash"
)
func HashString(str string) string {
h := xxhash.New()
//nolint
h.Write([]byte(str))
hashBytes := h.Sum(nil)
return strings.ToLower(base32.StdEncoding.EncodeToString(hashBytes)[:8])
}
================================================
FILE: internal/helpers/joiner.go
================================================
package helpers
import (
"bytes"
"strings"
)
// This provides an efficient way to join lots of big string and byte slices
// together. It avoids the cost of repeatedly reallocating as the buffer grows
// by measuring exactly how big the buffer should be and then allocating once.
// This is a measurable speedup.
type Joiner struct {
lastByte byte
strings []joinerString
bytes []joinerBytes
length uint32
}
type joinerString struct {
data string
offset uint32
}
type joinerBytes struct {
data []byte
offset uint32
}
func (j *Joiner) AddString(data string) {
if len(data) > 0 {
j.lastByte = data[len(data)-1]
}
j.strings = append(j.strings, joinerString{data, j.length})
j.length += uint32(len(data))
}
func (j *Joiner) AddBytes(data []byte) {
if len(data) > 0 {
j.lastByte = data[len(data)-1]
}
j.bytes = append(j.bytes, joinerBytes{data, j.length})
j.length += uint32(len(data))
}
func (j *Joiner) LastByte() byte {
return j.lastByte
}
func (j *Joiner) Length() uint32 {
return j.length
}
func (j *Joiner) EnsureNewlineAtEnd() {
if j.length > 0 && j.lastByte != '\n' {
j.AddString("\n")
}
}
func (j *Joiner) Done() []byte {
if len(j.strings) == 0 && len(j.bytes) == 1 && j.bytes[0].offset == 0 {
// No need to allocate if there was only a single byte array written
return j.bytes[0].data
}
buffer := make([]byte, j.length)
for _, item := range j.strings {
copy(buffer[item.offset:], item.data)
}
for _, item := range j.bytes {
copy(buffer[item.offset:], item.data)
}
return buffer
}
func (j *Joiner) Contains(s string, b []byte) bool {
for _, item := range j.strings {
if strings.Contains(item.data, s) {
return true
}
}
for _, item := range j.bytes {
if bytes.Contains(item.data, b) {
return true
}
}
return false
}
================================================
FILE: internal/helpers/js_comment_utils.go
================================================
package helpers
import (
"strings"
)
func peekIs(input string, cur int, assert byte) bool {
return cur+1 < len(input) && input[cur+1] == assert
}
// RemoveComments removes both block and inline comments from a string
func RemoveComments(input string) string {
var (
sb = strings.Builder{}
inComment = false
)
for cur := 0; cur < len(input); cur++ {
if input[cur] == '/' && !inComment {
if peekIs(input, cur, '*') {
inComment = true
cur++
} else if peekIs(input, cur, '/') {
// Skip until the end of line for inline comments
for cur < len(input) && input[cur] != '\n' {
cur++
}
continue
}
} else if input[cur] == '*' && inComment && peekIs(input, cur, '/') {
inComment = false
cur++
continue
}
if !inComment {
sb.WriteByte(input[cur])
}
}
if inComment {
return ""
}
return strings.TrimSpace(sb.String())
}
================================================
FILE: internal/js_scanner/js_scanner.go
================================================
package js_scanner
import (
"bytes"
"fmt"
"io"
"strings"
"github.com/iancoleman/strcase"
"github.com/tdewolff/parse/v2"
"github.com/tdewolff/parse/v2/js"
"github.com/withastro/compiler/internal/loc"
)
// FindTopLevelReturns scans JavaScript/TypeScript source code and returns the
// byte positions of all `return` statements that are at the top level (i.e., not
// inside any function, arrow function, method, or class method).
//
// This is used to transform top-level returns into throws in TSX output, because
// top-level returns are valid in Astro frontmatter but cause TypeScript parsing errors.
func FindTopLevelReturns(source []byte) []int {
l := js.NewLexer(parse.NewInputBytes(source))
i := 0
returns := make([]int, 0)
// We need to track "function scope depth" - returns are only top-level
// if they're not inside any function body.
//
// The challenge is distinguishing between:
// - `if (cond) { return; }` - top-level return (inside if block)
// - `function f() { return; }` - not top-level (inside function)
// - `() => { return; }` - not top-level (inside arrow function)
// - `class C { method() { return; } }` - not top-level (inside class method)
// - `{ method() { return; } }` - not top-level (inside object method)
// - `{ ['computed']() { return; } }` - not top-level (computed method)
//
// Strategy: Track when we're expecting a function body to start.
// A function body starts with `{` after:
// - `function` keyword followed by optional name and `()`
// - `=>` (arrow function)
// - `identifier()` where `{` follows (method shorthand in objects/classes)
// - `[expr]()` where `{` follows (computed method in objects/classes)
functionScopeStack := make([]int, 0) // stack of brace depths when entering function scopes
braceDepth := 0
bracketDepth := 0
// Track parentheses depth to detect when we close params
parenDepth := 0
parenDepthAtFunctionStart := -1 // the paren depth when we saw `function` keyword
// Track if we're expecting a function body
expectingFunctionBody := false
// Track method shorthand: identifier + () + { = method shorthand
// We need to track the paren depth when we see an identifier, so we know
// if the identifier is BEFORE the parens (method shorthand) or INSIDE them (not method)
// E.g., `method() { }` vs `if (condition) { }`
identParenDepth := -1 // paren depth when we last saw an identifier at current level
// Track that we actually went through parens after seeing identifier
// This distinguishes `method() {` from `class Foo {`
wentThroughParensForMethod := false
// Track computed property: [expr] + () + { = computed method
// After we see `]` that closes a bracket at the same level, we may have a computed method
sawCloseBracketForMethod := false
for {
token, value := l.Next()
// Handle regex vs division ambiguity
if token == js.DivToken || token == js.DivEqToken {
if i+1 < len(source) {
lns := bytes.Split(source[i+1:], []byte{'\n'})
if bytes.Contains(lns[0], []byte{'/'}) {
token, value = l.RegExp()
}
}
}
if token == js.ErrorToken {
if l.Err() != io.EOF {
return returns
}
break
}
// Skip whitespace and comments
if token == js.WhitespaceToken || token == js.LineTerminatorToken ||
token == js.CommentToken || token == js.CommentLineTerminatorToken {
i += len(value)
continue
}
// Track identifiers (for method shorthand pattern: identifier + () + {)
// Only track if we're not already inside parens from something else
if js.IsIdentifier(token) {
identParenDepth = parenDepth
wentThroughParensForMethod = false
sawCloseBracketForMethod = false
i += len(value)
continue
}
// Track parentheses
if js.IsPunctuator(token) {
if value[0] == '(' {
parenDepth++
i += len(value)
continue
} else if value[0] == ')' {
parenDepth--
// If we close parens back to function start level, we expect function body next
if parenDepthAtFunctionStart >= 0 && parenDepth == parenDepthAtFunctionStart {
expectingFunctionBody = true
parenDepthAtFunctionStart = -1
}
// Check if we just closed parens back to where we saw an identifier
// This means we went through `identifier()` pattern
if identParenDepth >= 0 && parenDepth == identParenDepth {
wentThroughParensForMethod = true
}
i += len(value)
continue
}
}
// Track square brackets for computed properties [expr]
if js.IsPunctuator(token) {
if value[0] == '[' {
bracketDepth++
sawCloseBracketForMethod = false
i += len(value)
continue
} else if value[0] == ']' {
bracketDepth--
// Mark that we just closed a bracket - this could be a computed property name
// The next thing should be `()` for it to be a method
sawCloseBracketForMethod = true
identParenDepth = -1
i += len(value)
continue
}
}
// Detect arrow function: `=>` means we expect a function body
if token == js.ArrowToken {
expectingFunctionBody = true
identParenDepth = -1
sawCloseBracketForMethod = false
i += len(value)
continue
}
// Track function keywords - after `function`, we wait for `(` then `)`
if token == js.FunctionToken {
parenDepthAtFunctionStart = parenDepth
identParenDepth = -1
sawCloseBracketForMethod = false
i += len(value)
continue
}
// Track braces
if js.IsPunctuator(token) {
if value[0] == '{' {
// Check if this brace opens a function body
// This happens after:
// 1. `function name()` or `function()`
// 2. `=>`
// 3. `identifier()` (method shorthand) - identifier followed by () then {
// 4. `[expr]()` (computed method) - sawCloseBracketForMethod was set and we went through ()
isMethodShorthand := wentThroughParensForMethod
isComputedMethod := sawCloseBracketForMethod
if expectingFunctionBody || isMethodShorthand || isComputedMethod {
// Entering a function scope
functionScopeStack = append(functionScopeStack, braceDepth)
expectingFunctionBody = false
}
identParenDepth = -1
wentThroughParensForMethod = false
sawCloseBracketForMethod = false
braceDepth++
i += len(value)
continue
} else if value[0] == '}' {
braceDepth--
// Check if we're exiting a function scope
if len(functionScopeStack) > 0 && braceDepth == functionScopeStack[len(functionScopeStack)-1] {
functionScopeStack = functionScopeStack[:len(functionScopeStack)-1]
}
identParenDepth = -1
wentThroughParensForMethod = false
sawCloseBracketForMethod = false
i += len(value)
continue
}
}
// Reset identifier tracking on other tokens (but preserve sawCloseBracketForMethod
// through parens so `[expr]()` works)
identParenDepth = -1
// A return is top-level if we're not inside any function scope
if token == js.ReturnToken && len(functionScopeStack) == 0 {
returns = append(returns, i)
}
i += len(value)
}
return returns
}
type HoistedScripts struct {
Hoisted [][]byte
HoistedLocs []loc.Loc
Body [][]byte
BodyLocs []loc.Loc
}
func HoistExports(source []byte) HoistedScripts {
shouldHoist := bytes.Contains(source, []byte("export"))
if !shouldHoist {
body := make([][]byte, 0)
body = append(body, source)
bodyLocs := make([]loc.Loc, 0)
bodyLocs = append(bodyLocs, loc.Loc{Start: 0})
return HoistedScripts{
Body: body,
BodyLocs: bodyLocs,
}
}
l := js.NewLexer(parse.NewInputBytes(source))
i := 0
end := 0
hoisted := make([][]byte, 0)
hoistedLocs := make([]loc.Loc, 0)
body := make([][]byte, 0)
bodyLocs := make([]loc.Loc, 0)
pairs := make(map[byte]int)
// Let's lex the script until we find what we need!
outer:
for {
token, value := l.Next()
if token == js.DivToken || token == js.DivEqToken {
lns := bytes.Split(source[i+1:], []byte{'\n'})
if bytes.Contains(lns[0], []byte{'/'}) {
token, value = l.RegExp()
}
}
if token == js.ErrorToken {
if l.Err() != io.EOF {
body := make([][]byte, 0)
body = append(body, source)
bodyLocs := make([]loc.Loc, 0)
bodyLocs = append(bodyLocs, loc.Loc{Start: 0})
return HoistedScripts{
Hoisted: hoisted,
HoistedLocs: hoistedLocs,
Body: body,
BodyLocs: bodyLocs,
}
}
break
}
// Common delimiters. Track their length, then skip.
if token == js.WhitespaceToken || token == js.LineTerminatorToken || token == js.SemicolonToken {
i += len(value)
continue
}
// Exports should be consumed until all opening braces are closed,
// a specifier is found, and a line terminator has been found
if token == js.ExportToken {
flags := make(map[string]bool)
tokensFound := make(map[string]bool)
foundIdent := false
foundSemicolonOrLineTerminator := false
foundBody := false
start := i
i += len(value)
for {
next, nextValue := l.Next()
if next == js.DivToken || next == js.DivEqToken {
lns := bytes.Split(source[i+1:], []byte{'\n'})
if bytes.Contains(lns[0], []byte{'/'}) {
next, nextValue = l.RegExp()
}
}
i += len(nextValue)
flags[string(nextValue)] = true
tokensFound[string(nextValue)] = true
if next == js.ErrorToken && l.Err() == io.EOF {
foundSemicolonOrLineTerminator = true
}
if js.IsIdentifier(next) {
if isKeyword(nextValue) && next != js.FromToken {
continue
}
if string(nextValue) == "type" {
continue
}
if !foundIdent {
foundIdent = true
}
} else if next == js.LineTerminatorToken || next == js.SemicolonToken {
if next == js.LineTerminatorToken && i < len(source) && (source[i] == '&' || source[i] == '|') {
continue
}
if (flags["function"] || flags["=>"] || flags["interface"]) && !foundBody {
continue
}
if flags["&"] || flags["="] {
continue
}
if pairs['('] > 0 {
continue
}
foundSemicolonOrLineTerminator = true
} else if js.IsPunctuator(next) {
if nextValue[0] == '{' {
if flags["function"] {
// Curly braces can occur in a function parameter destructuring, which we don't want to consider
foundBody = foundBody || pairs['('] == 0
} else if flags["=>"] {
// Arrow can also occur in type definition before arrow function body (which we don't want to consider), but `=` cannot
foundBody = foundBody || tokensFound["="]
} else {
foundBody = true
}
}
if nextValue[0] == '{' || nextValue[0] == '(' || nextValue[0] == '[' {
flags[string(nextValue[0])] = true
pairs[nextValue[0]]++
} else if nextValue[0] == '}' {
pairs['{']--
} else if nextValue[0] == ')' {
pairs['(']--
} else if nextValue[0] == ']' {
pairs['[']--
}
} else {
// Sometimes, exports are written in multiple lines, like
//
// export const foo =
// [...]
// export type Props = ThisProps &
// SomeWeirdType<{ thatsSuperLong: SoItEndsUpFormattedLikeThis }>
//
// So, we omit the semicolon check if the line ends up with one of these
if flags["&"] && nextValue[0] != '&' {
flags["&"] = false
}
if flags["="] && nextValue[0] != '=' {
flags["="] = false
}
}
if foundIdent && foundSemicolonOrLineTerminator && pairs['{'] == 0 && pairs['('] == 0 && pairs['['] == 0 {
hoisted = append(hoisted, source[start:i])
hoistedLocs = append(hoistedLocs, loc.Loc{Start: start})
if end < start {
body = append(body, source[end:start])
bodyLocs = append(bodyLocs, loc.Loc{Start: end})
}
end = i
continue outer
}
if next == js.ErrorToken {
if l.Err() != io.EOF {
body := make([][]byte, 0)
body = append(body, source)
bodyLocs := make([]loc.Loc, 0)
bodyLocs = append(bodyLocs, loc.Loc{Start: 0})
return HoistedScripts{
Hoisted: hoisted,
HoistedLocs: hoistedLocs,
Body: body,
BodyLocs: bodyLocs,
}
}
break outer
}
}
}
// Track opening and closing braces
if js.IsPunctuator(token) {
if value[0] == '{' || value[0] == '(' || value[0] == '[' {
pairs[value[0]]++
i += len(value)
continue
} else if value[0] == '}' {
pairs['{']--
} else if value[0] == ')' {
pairs['(']--
} else if value[0] == ']' {
pairs['[']--
}
}
// Track our current position
i += len(value)
}
body = append(body, source[end:])
bodyLocs = append(bodyLocs, loc.Loc{Start: end})
return HoistedScripts{
Hoisted: hoisted,
HoistedLocs: hoistedLocs,
Body: body,
BodyLocs: bodyLocs,
}
}
func isKeyword(value []byte) bool {
return js.Keywords[string(value)] != 0
}
// isPropsAliasing checks if we're in a Props aliasing context (import { Props as X })
// rather than destructuring with 'as' property ({ as: Component })
func isPropsAliasing(idents []string) bool {
return len(idents) > 0 && idents[len(idents)-1] == "Props"
}
func HoistImports(source []byte) HoistedScripts {
imports := make([][]byte, 0)
importLocs := make([]loc.Loc, 0)
body := make([][]byte, 0)
bodyLocs := make([]loc.Loc, 0)
prev := 0
for i, statement := NextImportStatement(source, 0); i > -1 && i < len(source)+1; i, statement = NextImportStatement(source, i) {
bodyLocs = append(bodyLocs, loc.Loc{Start: prev})
body = append(body, source[prev:statement.Span.Start])
imports = append(imports, statement.Value)
importLocs = append(importLocs, loc.Loc{Start: statement.Span.Start})
prev = i
}
if prev == 0 {
bodyLocs = append(bodyLocs, loc.Loc{Start: 0})
body = append(body, source)
return HoistedScripts{Body: body, BodyLocs: bodyLocs}
}
bodyLocs = append(bodyLocs, loc.Loc{Start: prev})
body = append(body, source[prev:])
return HoistedScripts{Hoisted: imports, HoistedLocs: importLocs, Body: body, BodyLocs: bodyLocs}
}
func HasGetStaticPaths(source []byte) bool {
ident := []byte("getStaticPaths")
if !bytes.Contains(source, ident) {
return false
}
exports := HoistExports(source)
for _, statement := range exports.Hoisted {
if bytes.Contains(statement, ident) {
return true
}
}
return false
}
type Props struct {
Ident string
Statement string
Generics string
}
func GetPropsType(source []byte) Props {
defaultPropType := "Record"
ident := defaultPropType
genericsIdents := make([]string, 0)
generics := ""
statement := ""
if !bytes.Contains(source, []byte("Props")) {
return Props{
Ident: ident,
Statement: statement,
Generics: generics,
}
}
l := js.NewLexer(parse.NewInputBytes(source))
i := 0
pairs := make(map[byte]int)
idents := make([]string, 0)
start := 0
end := 0
outer:
for {
token, value := l.Next()
if token == js.DivToken || token == js.DivEqToken {
if len(source) > i {
lns := bytes.Split(source[i+1:], []byte{'\n'})
if bytes.Contains(lns[0], []byte{'/'}) {
token, value = l.RegExp()
}
}
}
if token == js.ErrorToken {
if l.Err() != io.EOF {
return Props{
Ident: ident,
}
}
break
}
// Common delimiters. Track their length, then skip.
if token == js.WhitespaceToken || token == js.LineTerminatorToken || token == js.SemicolonToken {
i += len(value)
continue
}
if token == js.ExtendsToken {
if bytes.Equal(value, []byte("extends")) {
idents = append(idents, "extends")
}
i += len(value)
continue
}
if pairs['{'] == 0 && pairs['('] == 0 && pairs['['] == 0 && pairs['<'] == 1 && token == js.CommaToken {
idents = make([]string, 0)
i += len(value)
continue
}
if js.IsIdentifier(token) {
if isKeyword(value) {
// fix(#814): fix Props detection when using `{ Props as SomethingElse }`
// fix(#927): only reset Props when 'as' follows 'Props' in the same context
if ident == "Props" && string(value) == "as" && isPropsAliasing(idents) {
start = 0
ident = defaultPropType
idents = make([]string, 0)
}
i += len(value)
continue
}
if pairs['<'] == 1 && pairs['{'] == 0 {
foundExtends := false
for _, id := range idents {
if id == "extends" {
foundExtends = true
}
}
if !foundExtends {
genericsIdents = append(genericsIdents, string(value))
}
i += len(value)
continue
}
// Note: do not check that `pairs['{'] == 0` to support named imports
if pairs['('] == 0 && pairs['['] == 0 && string(value) == "Props" {
ident = "Props"
}
idents = append(idents, string(value))
i += len(value)
continue
}
if bytes.ContainsAny(value, "<>") {
if len(idents) > 0 && idents[len(idents)-1] == "Props" {
start = i
ident = "Props"
idents = make([]string, 0)
}
for _, c := range value {
if c == '<' {
pairs['<']++
i += len(value)
continue
}
if c == '>' {
pairs['<']--
if pairs['<'] == 0 {
end = i
// Important: only break out if we've already found `Props`!
if ident != defaultPropType {
break outer
} else {
continue
}
}
}
}
}
if token == js.QuestionToken || (pairs['{'] == 0 && token == js.ColonToken) {
idents = make([]string, 0)
idents = append(idents, "extends")
}
// Track opening and closing braces
if js.IsPunctuator(token) {
if value[0] == '{' || value[0] == '(' || value[0] == '[' {
idents = make([]string, 0)
pairs[value[0]]++
i += len(value)
continue
} else if value[0] == '}' {
pairs['{']--
if pairs['<'] == 0 && pairs['{'] == 0 && ident != defaultPropType {
end = i
break outer
}
} else if value[0] == ')' {
pairs['(']--
} else if value[0] == ']' {
pairs['[']--
}
}
// Track our current position
i += len(value)
}
if start > 0 && len(genericsIdents) > 0 && ident != defaultPropType {
generics = fmt.Sprintf("<%s>", strings.Join(genericsIdents, ", "))
statement = strings.TrimSpace(string(source[start:end]))
}
return Props{
Ident: ident,
Statement: statement,
Generics: generics,
}
}
func IsIdentifier(value []byte) bool {
valid := true
for i, b := range value {
if i == 0 {
valid = js.IsIdentifierStart([]byte{b})
} else if i < len(value)-1 {
valid = js.IsIdentifierContinue([]byte{b})
} else {
valid = js.IsIdentifierEnd([]byte{b})
}
if !valid {
break
}
}
return valid
}
func GetObjectKeys(source []byte) [][]byte {
keys := make([][]byte, 0)
pairs := make(map[byte]int)
if source[0] == '{' && source[len(source)-1] == '}' {
l := js.NewLexer(parse.NewInputBytes(source[1 : len(source)-1]))
i := 0
var prev js.TokenType
for {
token, value := l.Next()
openPairs := pairs['{'] > 0 || pairs['('] > 0 || pairs['['] > 0
if token == js.DivToken || token == js.DivEqToken {
lns := bytes.Split(source[i+1:], []byte{'\n'})
if bytes.Contains(lns[0], []byte{'/'}) {
token, value = l.RegExp()
}
}
i += len(value)
if token == js.ErrorToken {
return keys
}
if js.IsPunctuator(token) {
if value[0] == '{' || value[0] == '(' || value[0] == '[' {
pairs[value[0]]++
continue
} else if value[0] == '}' {
pairs['{']--
} else if value[0] == ')' {
pairs['(']--
} else if value[0] == ']' {
pairs['[']--
}
}
if prev != js.ColonToken {
push := func() {
if token != js.StringToken {
keys = append(keys, value)
} else {
key := value[1 : len(value)-1]
ident := string(key)
if !IsIdentifier(key) {
ident = strcase.ToLowerCamel(string(key))
}
if string(key) == ident {
keys = append(keys, []byte(key))
} else {
keys = append(keys, []byte(fmt.Sprintf("%s: %s", value, ident)))
}
}
}
if !openPairs && (token == js.IdentifierToken || token == js.StringToken) {
push()
} else if pairs['['] == 1 && token == js.StringToken {
push()
}
}
if !openPairs && token != js.WhitespaceToken {
prev = token
}
}
}
return keys
}
type Import struct {
IsType bool
ExportName string
LocalName string
Assertions string
}
type ImportStatement struct {
Span loc.Span
Value []byte
IsType bool
Imports []Import
Specifier string
Assertions string
}
type ImportState uint32
const (
ImportDefault ImportState = iota
ImportNamed
)
func NextImportStatement(source []byte, pos int) (int, ImportStatement) {
l := js.NewLexer(parse.NewInputBytes(source[pos:]))
i := pos
for {
token, value := l.Next()
if len(source) > i && token == js.DivToken || token == js.DivEqToken {
lns := bytes.Split(source[i+1:], []byte{'\n'})
if bytes.Contains(lns[0], []byte{'/'}) {
token, value = l.RegExp()
}
}
if token == js.ErrorToken {
// EOF or other error
return -1, ImportStatement{}
}
// Imports should be consumed up until we find a specifier,
// then we can exit after the following line terminator or semicolon
if token == js.ImportToken {
i += len(value)
text := []byte(value)
isType := false
specifier := ""
assertion := ""
foundSpecifier := false
foundAssertion := false
imports := make([]Import, 0)
importState := ImportDefault
currImport := Import{}
pairs := make(map[byte]int)
for {
next, nextValue := l.Next()
if len(source) > i && (next == js.DivToken || next == js.DivEqToken) {
lns := bytes.Split(source[i+1:], []byte{'\n'})
if bytes.Contains(lns[0], []byte{'/'}) {
next, nextValue = l.RegExp()
}
}
i += len(nextValue)
text = append(text, nextValue...)
if next == js.ErrorToken {
break
}
if next == js.DotToken {
isMeta := false
for {
next, _ := l.Next()
if next == js.MetaToken {
isMeta = true
}
if next != js.WhitespaceToken && next != js.MetaToken {
break
}
}
if isMeta {
continue
}
}
if !foundSpecifier && next == js.StringToken {
if len(nextValue) > 1 {
specifier = string(nextValue[1 : len(nextValue)-1])
foundSpecifier = true
}
continue
}
if !foundSpecifier && next == js.IdentifierToken && string(nextValue) == "type" {
isType = true
}
if foundSpecifier && (next == js.LineTerminatorToken || next == js.SemicolonToken) && pairs['{'] == 0 && pairs['('] == 0 && pairs['['] == 0 {
if currImport.ExportName != "" {
if currImport.LocalName == "" {
currImport.LocalName = currImport.ExportName
}
imports = append(imports, currImport)
}
return i, ImportStatement{
Span: loc.Span{Start: i - len(text), End: i},
Value: text,
IsType: isType,
Imports: imports,
Specifier: specifier,
Assertions: assertion,
}
}
if next == js.WhitespaceToken {
continue
}
if foundAssertion {
assertion += string(nextValue)
}
if !foundAssertion && next == js.StringToken {
specifier = string(nextValue[1 : len(nextValue)-1])
foundSpecifier = true
continue
}
if !foundAssertion && foundSpecifier && next == js.IdentifierToken && string(nextValue) == "assert" {
foundAssertion = true
continue
}
if !foundAssertion && next == js.OpenBraceToken {
importState = ImportNamed
}
if !foundAssertion && next == js.CommaToken {
if currImport.LocalName == "" {
currImport.LocalName = currImport.ExportName
}
imports = append(imports, currImport)
currImport = Import{}
}
if !foundAssertion && next == js.IdentifierToken {
if currImport.ExportName != "" {
currImport.LocalName = string(nextValue)
} else if importState == ImportNamed {
currImport.ExportName = string(nextValue)
} else if importState == ImportDefault {
currImport.ExportName = "default"
currImport.LocalName = string(nextValue)
}
}
if !foundAssertion && next == js.MulToken {
currImport.ExportName = string(nextValue)
}
if js.IsPunctuator(next) {
if nextValue[0] == '{' || nextValue[0] == '(' || nextValue[0] == '[' {
pairs[nextValue[0]]++
} else if nextValue[0] == '}' {
pairs['{']--
} else if nextValue[0] == ')' {
pairs['(']--
} else if nextValue[0] == ']' {
pairs['[']--
}
}
// do not hoist dynamic imports
if next == js.OpenParenToken && len(specifier) == 0 {
break
}
// do not hoist `{ import: "value" }`
if next == js.ColonToken && len(specifier) == 0 {
break
}
// if this is import.meta.*, ignore (watch for first dot)
if next == js.DotToken && len(specifier) == 0 {
break
}
}
}
i += len(value)
}
}
/*
Determines the export name of a component, i.e. the object path to which
we can access the module, if it were imported using a dynamic import (`import()`)
Returns the export name and a boolean indicating whether
the component is imported AND used in the template.
*/
func ExtractComponentExportName(data string, imported Import) (string, bool) {
namespacePrefix := fmt.Sprintf("%s.", imported.LocalName)
isNamespacedComponent := strings.Contains(data, ".") && strings.HasPrefix(data, namespacePrefix)
localNameEqualsData := imported.LocalName == data
if isNamespacedComponent || localNameEqualsData {
var exportName string
switch true {
case localNameEqualsData:
exportName = imported.ExportName
case imported.ExportName == "*":
// matched a namespaced import
exportName = strings.Replace(data, namespacePrefix, "", 1)
case imported.ExportName == "default":
// matched a default import
exportName = strings.Replace(data, imported.LocalName, "default", 1)
default:
// matched a named import
exportName = data
}
return exportName, true
}
return "", false
}
================================================
FILE: internal/js_scanner/js_scanner_test.go
================================================
package js_scanner
import (
"bytes"
"encoding/json"
"fmt"
"strings"
"testing"
"unicode/utf8"
"github.com/withastro/compiler/internal/test_utils"
)
type testcase struct {
name string
source string
want string
only bool
}
// Test cases for FindTopLevelReturns
func TestFindTopLevelReturns(t *testing.T) {
tests := []struct {
name string
source string
want []int
only bool
}{
{
name: "basic top-level return",
source: `return "value";`,
want: []int{0},
},
{
name: "return inside function declaration",
source: `function foo() {
return "value";
}`,
want: nil,
},
{
name: "return inside arrow function",
source: `const foo = () => {
return "value";
}`,
want: nil,
},
{
name: "return inside class method",
source: `class Component {
render() {
return "wow"!
}
}`,
want: nil,
},
{
name: "return inside exported async function",
source: `export async function getStaticPaths({ paginate }: { paginate: PaginateFunction }) {
const { data: products }: { data: IProduct[] } = await getEntry("products", "products");
return paginate(products, {
pageSize: 10,
});
}`,
want: nil,
},
{
name: "mixed: function with return, then top-level return",
source: `const foo = () => {
return "value";
}
if (true) {
return "value";
}
`,
want: []int{51},
},
{
name: "multiple top-level returns",
source: `const foo = () => {
return "value";
}
if (true) {
return "value";
}
if (true) {
return "value";
}
`,
want: []int{51, 83},
},
{
name: "return inside object method shorthand",
source: `const something = {
someFunction: () => {
return "Hello World";
},
someOtherFunction() {
return "Hello World";
},
};`,
want: nil,
},
{
name: "return inside arrow function with satisfies",
source: `export const getStaticPaths = (({ paginate }) => {
const data = [0, 1, 2];
return paginate(data, {
pageSize: 10,
});
}) satisfies GetStaticPaths;`,
want: nil,
},
{
name: "top-level return with Astro.redirect",
source: `if (something) {
return Astro.redirect();
}`,
want: []int{18},
},
{
name: "no returns at all",
source: `const foo = "bar";
console.log(foo);`,
want: nil,
},
{
name: "computed method in class with generic arrow",
source: `class Foo {
['get']() {
return 'ok';
}
}
const generic = (value: T) => { return value; };
if (true) { return Astro.redirect('/test'); }`,
want: []int{110},
},
{
name: "computed method in object",
source: `const obj = { ['get']() { return 'obj'; } };
if (true) { return Astro.redirect(); }`,
want: []int{57},
},
{
name: "generic arrow function",
source: `const generic = (value: T) => { return value; };
if (true) { return Astro.redirect(); }`,
want: []int{65},
},
}
for _, tt := range tests {
if tt.only {
tests = []struct {
name string
source string
want []int
only bool
}{tt}
break
}
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := FindTopLevelReturns([]byte(tt.source))
if diff := test_utils.ANSIDiff(fmt.Sprint(tt.want), fmt.Sprint(got)); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}
}
func fixturesHoistImport() []testcase {
return []testcase{
{
name: "basic",
source: `const value = "test"`,
want: ``,
},
{
name: "import",
source: `import { fn } from "package";
const b = await fetch();`,
want: `import { fn } from "package";
`,
},
{
name: "dynamic",
source: `const markdownDocs = await Astro.glob('../markdown/*.md')
const article2 = await import('../markdown/article2.md')
`,
want: "",
},
{
name: "big import",
source: `import {
a,
b,
c,
d,
} from "package"
const b = await fetch();`,
want: `import {
a,
b,
c,
d,
} from "package"
`,
},
{
name: "import with comment",
source: `// comment
import { fn } from "package";
const b = await fetch();`,
want: `import { fn } from "package";`,
},
{
name: "import assertion",
source: `// comment
import { fn } from "package" assert { it: 'works' };
const b = await fetch();`,
want: `import { fn } from "package" assert { it: 'works' };`,
},
{
name: "import assertion 2",
source: `// comment
import {
fn
} from
"package" assert {
it: 'works'
};
const b = await fetch();`,
want: `import {
fn
} from
"package" assert {
it: 'works'
};
`,
},
{
name: "import.meta.env",
source: `console.log(import.meta.env.FOO);
import Test from "../components/Test.astro";`,
want: `import Test from "../components/Test.astro";`,
},
{
name: "import.meta.env II",
source: `console.log(
import
.meta
.env
.FOO
);
import Test from "../components/Test.astro";`,
want: `import Test from "../components/Test.astro";`,
},
{
name: "import/export",
source: `import { fn } from "package";
export async fn() {}
const b = await fetch()`,
want: `import { fn } from "package";`,
},
{
name: "getStaticPaths",
source: `import { fn } from "package";
export async function getStaticPaths() {
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `import { fn } from "package";`,
},
{
name: "getStaticPaths with comments",
source: `import { fn } from "package";
export async function getStaticPaths() {
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `import { fn } from "package";`,
},
{
name: "getStaticPaths with semicolon",
source: `import { fn } from "package";
export async function getStaticPaths() {
const content = Astro.fetchContent('**/*.md');
}; const b = await fetch()`,
want: `import { fn } from "package";`,
},
{
name: "getStaticPaths with RegExp escape",
source: `export async function getStaticPaths() {
const pattern = /\.md$/g.test('value');
}
import a from "a";`,
want: `import a from "a";`,
},
{
name: "getStaticPaths with divider",
source: `export async function getStaticPaths() {
const pattern = a / b;
}`,
want: ``,
},
{
name: "getStaticPaths with divider and following content",
source: `export async function getStaticPaths() {
const value = 1 / 2;
}
// comment
import { b } from "b";
const { a } = Astro.props;`,
want: `import { b } from "b";`,
},
{
name: "getStaticPaths with regex and following content",
source: `export async function getStaticPaths() {
const value = /2/g;
}
// comment
import { b } from "b";
const { a } = Astro.props;`,
want: `import { b } from "b";`,
},
{
name: "multiple imports",
source: `import { a } from "a";
import { b } from "b";
// comment
import { c } from "c";
const d = await fetch()
// comment
import { d } from "d";`,
want: `import { a } from "a";
import { b } from "b";
import { c } from "c";
import { d } from "d";
`,
},
{
name: "assignment",
source: `let show = true;`,
want: ``,
},
{
name: "RegExp is not a comment",
source: `import { a } from "a";
/import \{ b \} from "b";/;
import { c } from "c";`,
want: `import { a } from "a";
import { c } from "c";
`,
},
}
}
func TestHoistImport(t *testing.T) {
tests := fixturesHoistImport()
for _, tt := range tests {
if tt.only {
tests = make([]testcase, 0)
tests = append(tests, tt)
break
}
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := HoistImports([]byte(tt.source))
got := []byte{}
for _, imp := range result.Hoisted {
got = append(got, bytes.TrimSpace(imp)...)
got = append(got, '\n')
}
// compare to expected string, show diff if mismatch
if diff := test_utils.ANSIDiff(strings.TrimSpace(tt.want), strings.TrimSpace(string(got))); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}
}
func FuzzHoistImport(f *testing.F) {
tests := fixturesHoistImport()
for _, tt := range tests {
f.Add(tt.source) // Use f.Add to provide a seed corpus
}
f.Fuzz(func(t *testing.T, source string) {
result := HoistImports([]byte(source))
got := []byte{}
for _, imp := range result.Hoisted {
got = append(got, bytes.TrimSpace(imp)...)
got = append(got, '\n')
}
if utf8.ValidString(source) && !utf8.ValidString(string(got)) {
t.Errorf("Import hoisting produced an invalid string: %q", got)
}
})
}
func TestHoistExport(t *testing.T) {
tests := []testcase{
{
name: "getStaticPaths",
source: `import { fn } from "package";
export async function getStaticPaths() {
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export async function getStaticPaths() {
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and destructured props",
source: `import { fn } from "package";
export async function getStaticPaths({ paginate })
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export async function getStaticPaths({ paginate })
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and param definition type in curly braces",
source: `import { fn } from "package";
export async function getStaticPaths(input: { paginate: any })
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export async function getStaticPaths(input: { paginate: any })
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and param definition type in square braces",
source: `import { fn } from "package";
export async function getStaticPaths([{ stuff }])
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export async function getStaticPaths([{ stuff }])
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and type specified with square braces 1",
source: `import { fn } from "package";
export const getStaticPaths: () => { params: any }[]
= () =>
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export const getStaticPaths: () => { params: any }[]
= () =>
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and type specified with square braces 2",
source: `import { fn } from "package";
export const getStaticPaths: () => { params: any }[] =
() =>
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export const getStaticPaths: () => { params: any }[] =
() =>
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and type specified with square braces 3",
source: `import { fn } from "package";
export const getStaticPaths: () => { params: any }[] = ()
=>
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export const getStaticPaths: () => { params: any }[] = ()
=>
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and type specified with square braces 4",
source: `import { fn } from "package";
export const getStaticPaths: () => { params: any }[] = () =>
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export const getStaticPaths: () => { params: any }[] = () =>
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with curly brace on next line and definition specified by anonymous function with destructured parameter",
source: `import { fn } from "package";
export const getStaticPaths = function({ paginate })
{
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export const getStaticPaths = function({ paginate })
{
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with comments",
source: `import { fn } from "package";
export async function getStaticPaths() {
// This works!
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export async function getStaticPaths() {
// This works!
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with semicolon",
source: `import { fn } from "package";
export async function getStaticPaths() {
const content = Astro.fetchContent('**/*.md');
}; const b = await fetch()`,
want: `export async function getStaticPaths() {
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "getStaticPaths with RegExp escape",
source: `// cool
export async function getStaticPaths() {
const pattern = /\.md$/g.test('value');
}
import a from "a";`,
want: `export async function getStaticPaths() {
const pattern = /\.md$/g.test('value');
}`,
},
{
name: "getStaticPaths with divider",
source: `export async function getStaticPaths() {
const pattern = a / b;
}`,
want: `export async function getStaticPaths() {
const pattern = a / b;
}`,
},
{
name: "getStaticPaths with divider and following content",
source: `export async function getStaticPaths() {
const value = 1 / 2;
}
// comment
import { b } from "b";
const { a } = Astro.props;`,
want: `export async function getStaticPaths() {
const value = 1 / 2;
}`,
},
{
name: "getStaticPaths with regex and following content",
source: `// comment
export async function getStaticPaths() {
const value = /2/g;
}
import { b } from "b";
const { a } = Astro.props;`,
want: `export async function getStaticPaths() {
const value = /2/g;
}`,
},
{
name: "getStaticPaths with TypeScript type",
source: `import { fn } from "package";
export async function getStaticPaths({
paginate
}: {
paginate: any
}) {
const content = Astro.fetchContent('**/*.md');
}
const b = await fetch()`,
want: `export async function getStaticPaths({
paginate
}: {
paginate: any
}) {
const content = Astro.fetchContent('**/*.md');
}`,
},
{
name: "export interface",
source: `import { a } from "a";
export interface Props {
open?: boolean;
}`,
want: `export interface Props {
open?: boolean;
}`,
},
{
name: "export multiple",
source: `import { a } from "a";
export interface Props {
open?: boolean;
}
export const foo = "bar"`,
want: `export interface Props {
open?: boolean;
}
export const foo = "bar"`,
},
{
name: "export multiple with content after",
source: `import { a } from "a";
export interface Props {
open?: boolean;
}
export const baz = "bing"
// beep boop`,
want: `export interface Props {
open?: boolean;
}
export const baz = "bing"`,
},
{
name: "export three",
source: `import { a } from "a";
export interface Props {}
export const a = "b"
export const c = "d"`,
want: `export interface Props {}
export const a = "b"
export const c = "d"`,
},
{
name: "export with comments",
source: `import { a } from "a";
// comment
export interface Props {}
export const a = "b"
export const c = "d"`,
want: `export interface Props {}
export const a = "b"
export const c = "d"`,
},
{
name: "export local reference (runtime error)",
source: `import { a } from "a";
export interface Props {}
const value = await fetch("something")
export const data = { value }
`,
want: `export interface Props {}
export const data = { value }`,
},
{
name: "export passthrough",
source: `export * from "./local-data.json";
export { default as A } from "./_types"
export B from "./_types"
export type C from "./_types"`,
want: `export * from "./local-data.json";
export { default as A } from "./_types"
export B from "./_types"
export type C from "./_types"`,
},
{
name: "multi-line export",
source: `export interface Props
{
foo: 'bar';
}`,
want: `export interface Props
{
foo: 'bar';
}`,
},
{
name: "multi-line type export",
source: `export type Props =
{
foo: 'bar';
}`,
want: `export type Props =
{
foo: 'bar';
}`,
},
{
name: "multi-line type export with multiple exports",
source: `export type Theme = 'light' | 'dark';
export type Props =
{
theme: Theme;
};
export interface Foo {
bar: string;
}
export type FooAndBar1 = 'Foo' &
'Bar';
export type FooAndBar2 = 'Foo'
& 'Bar';
export type FooOrBar = 'Foo'
| 'Bar';`,
want: `export type Theme = 'light' | 'dark';
export type Props =
{
theme: Theme;
}
export interface Foo {
bar: string;
}
export type FooAndBar1 = 'Foo' &
'Bar';
export type FooAndBar2 = 'Foo'
& 'Bar';
export type FooOrBar = 'Foo'
| 'Bar';`,
},
{
name: "Picture",
source: `// @ts-ignore
import loader from 'virtual:image-loader';
import { getPicture } from '../src/get-picture.js';
import type { ImageAttributes, ImageMetadata, OutputFormat, PictureAttributes, TransformOptions } from '../src/types.js';
export interface LocalImageProps extends Omit, Omit, Omit {
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
sizes: HTMLImageElement['sizes'];
widths: number[];
formats?: OutputFormat[];
}
export interface RemoteImageProps extends Omit, TransformOptions, Omit {
src: string;
sizes: HTMLImageElement['sizes'];
widths: number[];
aspectRatio: TransformOptions['aspectRatio'];
formats?: OutputFormat[];
}
export type Props = LocalImageProps | RemoteImageProps;
const { src, sizes, widths, aspectRatio, formats = ['avif', 'webp'], loading = 'lazy', decoding = 'async', ...attrs } = Astro.props as Props;
const { image, sources } = await getPicture({ loader, src, widths, formats, aspectRatio });
`,
want: `export interface LocalImageProps extends Omit, Omit, Omit {
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
sizes: HTMLImageElement['sizes'];
widths: number[];
formats?: OutputFormat[];
}
export interface RemoteImageProps extends Omit, TransformOptions, Omit {
src: string;
sizes: HTMLImageElement['sizes'];
widths: number[];
aspectRatio: TransformOptions['aspectRatio'];
formats?: OutputFormat[];
}
export type Props = LocalImageProps | RemoteImageProps;`,
},
{
name: "Image",
source: `// @ts-ignore
import loader from 'virtual:image-loader';
import { getImage } from '../src/index.js';
import type { ImageAttributes, ImageMetadata, TransformOptions, OutputFormat } from '../src/types.js';
const { loading = "lazy", decoding = "async", ...props } = Astro.props as Props;
const attrs = await getImage(loader, props);
// Moved after Astro.props for test
export interface LocalImageProps extends Omit, Omit {
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
}
export interface RemoteImageProps extends TransformOptions, ImageAttributes {
src: string;
format: OutputFormat;
width: number;
height: number;
}
export type Props = LocalImageProps | RemoteImageProps;
`,
want: `export interface LocalImageProps extends Omit, Omit {
src: ImageMetadata | Promise<{ default: ImageMetadata }>;
}
export interface RemoteImageProps extends TransformOptions, ImageAttributes {
src: string;
format: OutputFormat;
width: number;
height: number;
}
export type Props = LocalImageProps | RemoteImageProps;`,
},
{
name: "comments",
source: `//
export const foo = 0
/*
*/`,
want: `export const foo = 0`,
},
}
for _, tt := range tests {
if tt.only {
tests = make([]testcase, 0)
tests = append(tests, tt)
break
}
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := HoistExports([]byte(tt.source))
got := []byte{}
for _, imp := range result.Hoisted {
got = append(got, bytes.TrimSpace(imp)...)
got = append(got, '\n')
}
// compare to expected string, show diff if mismatch
if diff := test_utils.ANSIDiff(strings.TrimSpace(tt.want), strings.TrimSpace(string(got))); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}
}
type keytestcase struct {
name string
source string
want []string
only bool
}
func TestGetObjectKeys(t *testing.T) {
tests := []keytestcase{
{
name: "basic",
source: `{ value }`,
want: []string{"value"},
},
{
name: "shorhand",
source: `{ value, foo, bar, baz, bing }`,
want: []string{"value", "foo", "bar", "baz", "bing"},
},
{
name: "literal",
source: `{ value: 0 }`,
want: []string{"value"},
},
{
name: "multiple",
source: `{ a: 0, b: 1, c: 2 }`,
want: []string{"a", "b", "c"},
},
{
name: "objects",
source: `{ a: { a1: 0 }, b: { b1: { b2: 0 }}, c: { c1: { c2: { c3: 0 }}} }`,
want: []string{"a", "b", "c"},
},
{
name: "regexp",
source: `{ a: /hello/g, b: 0 }`,
want: []string{"a", "b"},
},
{
name: "array",
source: `{ a: [0, 1, 2], b: ["one", "two", "three"], c: 0 }`,
want: []string{"a", "b", "c"},
},
{
name: "valid strings",
source: `{ "lowercase": true, "camelCase": true, "PascalCase": true, "snake_case": true, "__private": true, ["computed"]: true, }`,
// Note that quotes are dropped
want: []string{`lowercase`, `camelCase`, `PascalCase`, `snake_case`, `__private`, `computed`},
},
{
name: "invalid strings",
source: `{ "dash-case": true, "with.dot": true, "with space": true }`,
want: []string{`"dash-case": dashCase`, `"with.dot": withDot`, `"with space": withSpace`},
},
}
for _, tt := range tests {
if tt.only {
tests = make([]keytestcase, 0)
tests = append(tests, tt)
break
}
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
keys := GetObjectKeys([]byte(tt.source))
output := make([]string, 0)
for _, key := range keys {
output = append(output, string(key))
}
got, _ := json.Marshal(output)
want, _ := json.Marshal(tt.want)
// compare to expected string, show diff if mismatch
if diff := test_utils.ANSIDiff(string(want), string(got)); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}
}
// propsTestCase represents a test case for GetPropsType
type propsTestCase struct {
name string
source string
want Props
}
// makeProps is a helper to create Props structs concisely
func makeProps(ident string, statement string, generics string) Props {
return Props{
Ident: ident,
Statement: statement,
Generics: generics,
}
}
// getPropsTypeTestCases returns all test cases for GetPropsType
func getPropsTypeTestCases() []propsTestCase {
const defaultType = "Record"
return []propsTestCase{
// Basic cases
{
name: "no props",
source: `const foo = "bar"`,
want: makeProps(defaultType, "", ""),
},
{
name: "interface Props",
source: `interface Props {
foo: string;
}`,
want: makeProps("Props", "", ""),
},
{
name: "type Props",
source: `type Props = {
foo: string;
}`,
want: makeProps("Props", "", ""),
},
// Generics
{
name: "Props with generics",
source: `interface Props {
foo: T;
}`,
want: makeProps("Props", "", ""),
},
// Issue #927: 'as' prop name handling
{
name: "destructuring with 'as' prop name without type assertion - issue #927",
source: `interface Props {
as?: string;
href?: string;
}
const { as: Component, href } = Astro.props;`,
want: makeProps("Props", "", ""),
},
{
name: "destructuring with 'as' prop name with type assertion",
source: `interface Props {
as?: string;
href?: string;
}
const { as: Component, href } = Astro.props as Props;`,
want: makeProps("Props", "", ""),
},
}
}
// checks if two Props are equal and reports errors
func assertPropsEqual(t *testing.T, got, want Props, source string) {
t.Helper()
if got.Ident != want.Ident {
t.Errorf("Ident mismatch:\n got: %q\n want: %q", got.Ident, want.Ident)
t.Logf("Source:\n%s", source)
}
if got.Statement != want.Statement {
t.Errorf("Statement mismatch:\n got: %q\n want: %q", got.Statement, want.Statement)
}
if got.Generics != want.Generics {
t.Errorf("Generics mismatch:\n got: %q\n want: %q", got.Generics, want.Generics)
}
}
func TestGetPropsType(t *testing.T) {
tests := getPropsTypeTestCases()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := GetPropsType([]byte(tt.source))
assertPropsEqual(t, got, tt.want, tt.source)
})
}
}
================================================
FILE: internal/js_scanner/testdata/fuzz/FuzzHoistImport/ec55358ab2929fbf4deab52587664e42682f0a6ea201a325c5c33f9d18c50456
================================================
go test fuzz v1
string("import\"\nimport \"\";")
================================================
FILE: internal/loc/diagnostics.go
================================================
package loc
type DiagnosticCode int
const (
ERROR DiagnosticCode = 1000
ERROR_UNTERMINATED_JS_COMMENT DiagnosticCode = 1001
ERROR_FRAGMENT_SHORTHAND_ATTRS DiagnosticCode = 1002
ERROR_UNMATCHED_IMPORT DiagnosticCode = 1003
ERROR_UNSUPPORTED_SLOT_ATTRIBUTE DiagnosticCode = 1004
ERROR_UNTERMINATED_STRING DiagnosticCode = 1005
ERROR_MISSING_FRONTMATTER_FENCE DiagnosticCode = 1006
WARNING DiagnosticCode = 2000
WARNING_UNTERMINATED_HTML_COMMENT DiagnosticCode = 2001
WARNING_UNCLOSED_HTML_TAG DiagnosticCode = 2002
WARNING_DEPRECATED_DIRECTIVE DiagnosticCode = 2003
WARNING_IGNORED_DIRECTIVE DiagnosticCode = 2004
WARNING_UNSUPPORTED_EXPRESSION DiagnosticCode = 2005
WARNING_SET_WITH_CHILDREN DiagnosticCode = 2006
WARNING_CANNOT_DEFINE_VARS DiagnosticCode = 2007
WARNING_INVALID_SPREAD DiagnosticCode = 2008
WARNING_UNEXPECTED_CHARACTER DiagnosticCode = 2009
WARNING_CANNOT_RERUN DiagnosticCode = 2010
INFO DiagnosticCode = 3000
HINT DiagnosticCode = 4000
)
================================================
FILE: internal/loc/loc.go
================================================
package loc
type Loc struct {
// This is the 0-based index of this location from the start of the file, in bytes
Start int
}
type Range struct {
Loc Loc
Len int
}
func (r Range) End() int {
return r.Loc.Start + r.Len
}
// span is a range of bytes in a Tokenizer's buffer. The start is inclusive,
// the end is exclusive.
type Span struct {
Start, End int
}
type TSXRange struct {
Start int `js:"start"`
End int `js:"end"`
}
// A NodeType is the type of a Node.
type DiagnosticSeverity int
const (
ErrorType DiagnosticSeverity = 1
WarningType DiagnosticSeverity = 2
InformationType DiagnosticSeverity = 3
HintType DiagnosticSeverity = 4
)
type DiagnosticMessage struct {
Severity int `js:"severity"`
Code int `js:"code"`
Location *DiagnosticLocation `js:"location"`
Hint string `js:"hint"`
Text string `js:"text"`
}
type DiagnosticLocation struct {
File string `js:"file"`
Line int `js:"line"`
Column int `js:"column"`
Length int `js:"length"`
}
type ErrorWithRange struct {
Code DiagnosticCode
Text string
Hint string
Range Range
}
func (e *ErrorWithRange) Error() string {
return e.Text
}
func (e *ErrorWithRange) ToMessage(location *DiagnosticLocation) DiagnosticMessage {
return DiagnosticMessage{
Code: int(e.Code),
Text: e.Error(),
Hint: e.Hint,
Location: location,
}
}
================================================
FILE: internal/node.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
import (
"github.com/withastro/compiler/internal/loc"
"golang.org/x/net/html/atom"
)
// A NodeType is the type of a Node.
type NodeType uint32
const (
ErrorNode NodeType = iota
TextNode
DocumentNode
ElementNode
CommentNode
DoctypeNode
// RawNode nodes are not returned by the parser, but can be part of the
// Node tree passed to func Render to insert raw HTML (without escaping).
// If so, this package makes no guarantee that the rendered HTML is secure
// (from e.g. Cross Site Scripting attacks) or well-formed.
RawNode
scopeMarkerNode
// Extensions
FrontmatterNode
ExpressionNode
RenderHeadNode
)
func (t NodeType) String() string {
switch t {
case ErrorNode:
return "error"
case TextNode:
return "text"
case DocumentNode:
return "root"
case ElementNode:
return "element"
case CommentNode:
return "comment"
case DoctypeNode:
return "doctype"
case FrontmatterNode:
return "frontmatter"
case ExpressionNode:
return "expression"
default:
return ""
}
}
// Used as an Attribute Key to mark implicit nodes
const ImplicitNodeMarker = "\x00implicit"
// Section 12.2.4.3 says "The markers are inserted when entering applet,
// object, marquee, template, td, th, and caption elements, and are used
// to prevent formatting from "leaking" into applet, object, marquee,
// template, td, th, and caption elements".
var scopeMarker = Node{Type: scopeMarkerNode}
type HydratedComponentMetadata struct {
ExportName string
LocalName string
Specifier string
ResolvedPath string
}
// A Node consists of a NodeType and some Data (tag name for element nodes,
// content for text) and are part of a tree of Nodes. Element nodes may also
// have a Namespace and contain a slice of Attributes. Data is unescaped, so
// that it looks like "a 0 {
n := (*s)[i-1]
*s = (*s)[:i-1]
return n
}
return nil
}
// top returns the most recently pushed node, or nil if s is empty.
func (s *nodeStack) top() *Node {
if i := len(*s); i > 0 {
return (*s)[i-1]
}
return nil
}
// index returns the index of the top-most occurrence of n in the stack, or -1
// if n is not present.
func (s *nodeStack) index(n *Node) int {
for i := len(*s) - 1; i >= 0; i-- {
if (*s)[i] == n {
return i
}
}
return -1
}
// contains returns whether a is within s.
func (s *nodeStack) contains(a atom.Atom) bool {
for _, n := range *s {
if n.DataAtom == a && n.Namespace == "" {
return true
}
}
return false
}
// insert inserts a node at the given index.
func (s *nodeStack) insert(i int, n *Node) {
(*s) = append(*s, nil)
copy((*s)[i+1:], (*s)[i:])
(*s)[i] = n
}
// remove removes a node from the stack. It is a no-op if n is not present.
func (s *nodeStack) remove(n *Node) {
i := s.index(n)
if i == -1 {
return
}
copy((*s)[i:], (*s)[i+1:])
j := len(*s) - 1
(*s)[j] = nil
*s = (*s)[:j]
}
type insertionModeStack []insertionMode
func (s *insertionModeStack) pop() (im insertionMode) {
i := len(*s)
im = (*s)[i-1]
*s = (*s)[:i-1]
return im
}
func (s *insertionModeStack) top() insertionMode {
if i := len(*s); i > 0 {
return (*s)[i-1]
}
return nil
}
================================================
FILE: internal/parser.go
================================================
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
import (
"errors"
"fmt"
"io"
"strings"
"github.com/withastro/compiler/internal/handler"
"github.com/withastro/compiler/internal/loc"
a "golang.org/x/net/html/atom"
)
// A parser implements the HTML5 parsing algorithm:
// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction
type parser struct {
// tokenizer provides the tokens for the parser.
tokenizer *Tokenizer
// tok is the most recently read token.
tok Token
ltok Token
// Self-closing tags like are treated as start tags, except that
// hasSelfClosingToken is set while they are being processed.
hasSelfClosingToken bool
// flag to signal that frontmatter has been added
// if we don't have frontmatter and we enter a tag, we add empty frontmatter
frontmatterState FrontmatterState
// doc is the document root element.
doc *Node
// fm is the document's frontmatter node
fm *Node
// The stack of open elements (section 12.2.4.2) and active formatting
// elements (section 12.2.4.3).
oe, afe nodeStack
// Element pointers (section 12.2.4.4).
head, form *Node
// Other parsing state flags (section 12.2.4.5).
scripting, framesetOK bool
// The stack of template insertion modes
templateStack insertionModeStack
// im is the current insertion mode.
im insertionMode
// originalIM is the insertion mode to go back to after completing a text
// or inTableText insertion mode.
originalIM insertionMode
exitLiteralIM func() bool
// fosterParenting is whether new elements should be inserted according to
// the foster parenting rules (section 12.2.6.1).
fosterParenting bool
// quirks is whether the parser is operating in "quirks mode."
quirks bool
// fragment is whether the parser is parsing an HTML fragment.
fragment bool
// literal is whether the parser should handle exceptions literally.
literal bool
// context is the context element when parsing an HTML fragment
// (section 12.4).
context *Node
handler *handler.Handler
}
func (p *parser) top() *Node {
if n := p.oe.top(); n != nil {
return n
}
return p.doc
}
// Stop tags for use in popUntil. These come from section 12.2.4.2.
var (
defaultScopeStopTags = map[string][]a.Atom{
"": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template},
"math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext},
"svg": {a.Desc, a.ForeignObject, a.Title},
}
)
type scope int
const (
defaultScope scope = iota
listItemScope
buttonScope
tableScope
tableRowScope
tableBodyScope
selectScope
)
// popUntil pops the stack of open elements at the highest element whose tag
// is in matchTags, provided there is no higher element in the scope's stop
// tags (as defined in section 12.2.4.2). It returns whether or not there was
// such an element. If there was not, popUntil leaves the stack unchanged.
//
// For example, the set of stop tags for table scope is: "html", "table". If
// the stack was:
// ["html", "body", "font", "table", "b", "i", "u"]
// then popUntil(tableScope, "font") would return false, but
// popUntil(tableScope, "i") would return true and the stack would become:
// ["html", "body", "font", "table", "b"]
//
// If an element's tag is in both the stop tags and matchTags, then the stack
// will be popped and the function returns true (provided, of course, there was
// no higher element in the stack that was also in the stop tags). For example,
// popUntil(tableScope, "table") returns true and leaves:
// ["html", "body", "font"]
func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool {
if i := p.indexOfElementInScope(s, matchTags...); i != -1 {
p.oe = p.oe[:i]
return true
}
return false
}
// indexOfElementInScope returns the index in p.oe of the highest element whose
// tag is in matchTags that is in scope. If no matching element is in scope, it
// returns -1.
func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
for i := len(p.oe) - 1; i >= 0; i-- {
tagAtom := p.oe[i].DataAtom
if p.oe[i].Namespace == "" {
for _, t := range matchTags {
if t == tagAtom {
return i
}
}
switch s {
case defaultScope:
// No-op.
case listItemScope:
if tagAtom == a.Ol || tagAtom == a.Ul {
return -1
}
case buttonScope:
if tagAtom == a.Button {
return -1
}
case tableScope:
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
return -1
}
case selectScope:
if tagAtom != a.Optgroup && tagAtom != a.Option {
return -1
}
default:
panic("unreachable")
}
}
switch s {
case defaultScope, listItemScope, buttonScope:
for _, t := range defaultScopeStopTags[p.oe[i].Namespace] {
if t == tagAtom {
return -1
}
}
}
}
return -1
}
// elementInScope is like popUntil, except that it doesn't modify the stack of
// open elements.
func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool {
return p.indexOfElementInScope(s, matchTags...) != -1
}
// clearStackToContext pops elements off the stack of open elements until a
// scope-defined element is found.
func (p *parser) clearStackToContext(s scope) {
for i := len(p.oe) - 1; i >= 0; i-- {
tagAtom := p.oe[i].DataAtom
switch s {
case tableScope:
if tagAtom == a.Html || tagAtom == a.Table || tagAtom == a.Template {
p.oe = p.oe[:i+1]
return
}
case tableRowScope:
if tagAtom == a.Html || tagAtom == a.Tr || tagAtom == a.Template {
p.oe = p.oe[:i+1]
return
}
case tableBodyScope:
if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead || tagAtom == a.Template {
p.oe = p.oe[:i+1]
return
}
default:
panic("unreachable")
}
}
}
// parseGenericRawTextElements implements the generic raw text element parsing
// algorithm defined in 12.2.6.2.
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-elements-that-contain-only-text
// TODO: Since both RAWTEXT and RCDATA states are treated as tokenizer's part
// officially, need to make tokenizer consider both states.
func (p *parser) parseGenericRawTextElement() {
p.addElement()
p.originalIM = p.im
p.im = textIM
}
func (p *parser) generateLoc() []loc.Loc {
locs := make([]loc.Loc, 0, 2)
locs = append(locs, p.tok.Loc)
switch p.tok.Type {
case TextToken:
locs = append(locs, loc.Loc{Start: p.tok.Loc.Start + len(p.tok.Data)})
case CommentToken:
locs = append(locs, loc.Loc{Start: p.tok.Loc.Start + len(p.tok.Data) + 3})
}
return locs
}
func (p *parser) addLoc() {
n := p.oe.top()
if n != nil {
n.Loc = append(n.Loc, p.tok.Loc)
}
}
// generateImpliedEndTags pops nodes off the stack of open elements as long as
// the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc.
// If exceptions are specified, nodes with that name will not be popped off.
func (p *parser) generateImpliedEndTags(exceptions ...string) {
var i int
loop:
for i = len(p.oe) - 1; i >= 0; i-- {
n := p.oe[i]
if n.Type != ElementNode {
break
}
switch n.DataAtom {
case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc:
for _, except := range exceptions {
if n.Data == except {
break loop
}
}
continue
}
break
}
p.oe = p.oe[:i+1]
}
// addChild adds a child node n to the top element, and pushes n onto the stack
// of open elements if it is an element node.
func (p *parser) addChild(n *Node) {
if p.shouldFosterParent() {
p.fosterParent(n)
} else {
p.top().AppendChild(n)
}
if n.Type == ElementNode {
p.oe = append(p.oe, n)
}
}
// shouldFosterParent returns whether the next node to be added should be
// foster parented.
func (p *parser) shouldFosterParent() bool {
if p.fosterParenting {
switch p.top().DataAtom {
case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
return true
}
}
return false
}
// fosterParent adds a child node according to the foster parenting rules.
// Section 12.2.6.1, "foster parenting".
func (p *parser) fosterParent(n *Node) {
var table, parent, prev, template *Node
var i int
for i = len(p.oe) - 1; i >= 0; i-- {
if p.oe[i].DataAtom == a.Table {
table = p.oe[i]
break
}
}
var j int
for j = len(p.oe) - 1; j >= 0; j-- {
if p.oe[j].DataAtom == a.Template {
template = p.oe[j]
break
}
}
if template != nil && (table == nil || j > i) {
template.AppendChild(n)
return
}
if table == nil {
// The foster parent is the html element.
parent = p.oe[0]
} else {
parent = table.Parent
}
if parent == nil {
parent = p.oe[i-1]
}
if table != nil {
prev = table.PrevSibling
} else {
prev = parent.LastChild
}
if prev != nil && prev.Type == TextNode && n.Type == TextNode {
prev.Data += n.Data
return
}
parent.InsertBefore(n, table)
}
// addText adds text to the preceding node if it is a text node, or else it
// calls addChild with a new text node.
func (p *parser) addText(text string) {
if text == "" {
return
}
if p.shouldFosterParent() {
p.fosterParent(&Node{
Type: TextNode,
Data: text,
Loc: p.generateLoc(),
})
return
}
t := p.top()
if n := t.LastChild; n != nil && n.Type == TextNode {
n.Data += text
return
}
p.addChild(&Node{
Type: TextNode,
Data: text,
Loc: p.generateLoc(),
})
}
func (p *parser) addFrontmatter(empty bool) {
if p.frontmatterState == FrontmatterInitial {
if p.doc.FirstChild != nil {
p.fm = &Node{
Type: FrontmatterNode,
Loc: p.generateLoc(),
}
p.doc.InsertBefore(p.fm, p.doc.FirstChild)
} else {
p.fm = &Node{
Type: FrontmatterNode,
Loc: p.generateLoc(),
}
p.doc.AppendChild(p.fm)
}
if empty {
p.frontmatterState = FrontmatterClosed
p.fm.Attr = append(p.fm.Attr, Attribute{Key: ImplicitNodeMarker, Type: EmptyAttribute})
} else {
p.frontmatterState = FrontmatterOpen
p.oe = append(p.oe, p.fm)
}
}
}
// addExpression adds a child expression based on the current token.
func (p *parser) addExpression() {
p.addChild(&Node{
Type: ElementNode,
DataAtom: a.Template,
Data: "astro:expression",
Attr: make([]Attribute, 0),
Expression: true,
Component: false,
CustomElement: false,
HandledScript: false,
Loc: p.generateLoc(),
Namespace: p.top().Namespace,
})
}
func isFragment(data string) bool {
return len(data) == 0 || data == "Fragment"
}
func isSlot(data string) bool {
return data == "slot"
}
func isComponent(data string) bool {
if strings.Contains(data, ".") {
return true
}
return !isFragment(data) && data[0] >= 'A' && data[0] <= 'Z'
}
func isCustomElement(data string) bool {
return strings.Contains(data, "-")
}
func (p *parser) isInsideHead() bool {
n := p.oe.top()
for n != nil {
if n.DataAtom == a.Head {
return true
}
n = n.Parent
}
return false
}
// addElement adds a child element based on the current token.
func (p *parser) addElement() {
p.addChild(&Node{
Type: ElementNode,
DataAtom: p.tok.DataAtom,
Data: p.tok.Data,
Attr: p.tok.Attr,
Fragment: isFragment(p.tok.Data),
Component: isComponent(p.tok.Data),
CustomElement: isCustomElement(p.tok.Data),
HandledScript: false,
Loc: p.generateLoc(),
})
}
// Section 12.2.4.3.
func (p *parser) addFormattingElement() {
tagAtom, attr := p.tok.DataAtom, p.tok.Attr
p.addElement()
// Implement the Noah's Ark clause, but with three per family instead of two.
identicalElements := 0
findIdenticalElements:
for i := len(p.afe) - 1; i >= 0; i-- {
n := p.afe[i]
if n.Type == scopeMarkerNode {
break
}
if n.Type != ElementNode {
continue
}
if n.Namespace != "" {
continue
}
if n.DataAtom != tagAtom {
continue
}
if len(n.Attr) != len(attr) {
continue
}
compareAttributes:
for _, t0 := range n.Attr {
for _, t1 := range attr {
if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val {
// Found a match for this attribute, continue with the next attribute.
continue compareAttributes
}
}
// If we get here, there is no attribute that matches a.
// Therefore the element is not identical to the new one.
continue findIdenticalElements
}
identicalElements++
if identicalElements >= 3 {
p.afe.remove(n)
}
}
p.afe = append(p.afe, p.top())
}
// Section 12.2.4.3.
func (p *parser) clearActiveFormattingElements() {
for {
if n := p.afe.pop(); len(p.afe) == 0 || n.Type == scopeMarkerNode {
return
}
}
}
// Section 12.2.4.3.
func (p *parser) reconstructActiveFormattingElements() {
n := p.afe.top()
if n == nil {
return
}
if n.Type == scopeMarkerNode || p.oe.index(n) != -1 {
return
}
i := len(p.afe) - 1
for n.Type != scopeMarkerNode && p.oe.index(n) == -1 {
if i == 0 {
i = -1
break
}
i--
n = p.afe[i]
}
for {
i++
clone := p.afe[i].clone()
p.addChild(clone)
p.afe[i] = clone
if i == len(p.afe)-1 {
break
}
}
}
// Section 12.2.5.
func (p *parser) acknowledgeSelfClosingTag() {
p.hasSelfClosingToken = false
}
// An insertion mode (section 12.2.4.1) is the state transition function from
// a particular state in the HTML5 parser's state machine. It updates the
// parser's fields depending on parser.tok (where ErrorToken means EOF).
// It returns whether the token was consumed.
type insertionMode func(*parser) bool
// setOriginalIM sets the insertion mode to return to after completing a text or
// inTableText insertion mode.
// Section 12.2.4.1, "using the rules for".
func (p *parser) setOriginalIM() {
if p.originalIM != nil {
panic("html: bad parser state: originalIM was set twice")
}
p.originalIM = p.im
}
// Section 12.2.4.1, "reset the insertion mode".
func (p *parser) resetInsertionMode() {
for i := len(p.oe) - 1; i >= 0; i-- {
n := p.oe[i]
last := i == 0
if last && p.context != nil {
n = p.context
}
switch n.DataAtom {
case a.Select:
if !last {
for ancestor, first := n, p.oe[0]; ancestor != first; {
ancestor = p.oe[p.oe.index(ancestor)-1]
switch ancestor.DataAtom {
case a.Template:
p.im = inSelectIM
return
case a.Table:
p.im = inSelectInTableIM
return
}
}
}
p.im = inSelectIM
case a.Td, a.Th:
// TODO: remove this divergence from the HTML5 spec.
//
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
p.im = inCellIM
case a.Tr:
p.im = inRowIM
case a.Tbody, a.Thead, a.Tfoot:
p.im = inTableBodyIM
case a.Caption:
p.im = inCaptionIM
case a.Colgroup:
p.im = inColumnGroupIM
case a.Table:
p.im = inTableIM
case a.Template:
// TODO: remove this divergence from the HTML5 spec.
if n.Namespace != "" {
continue
}
p.im = p.templateStack.top()
case a.Head:
// TODO: remove this divergence from the HTML5 spec.
//
// See https://bugs.chromium.org/p/chromium/issues/detail?id=829668
p.im = inHeadIM
case a.Body:
p.im = inBodyIM
case a.Frameset:
p.im = inFramesetIM
case a.Html:
if p.head == nil {
p.im = beforeHeadIM
} else {
p.im = afterHeadIM
}
default:
if last {
p.im = inBodyIM
return
}
continue
}
return
}
}
const whitespace = " \t\r\n\f"
// Section 12.2.6.4.1.
func initialIM(p *parser) bool {
switch p.tok.Type {
case FrontmatterFenceToken:
p.setOriginalIM()
p.im = frontmatterIM
return false
case TextToken:
p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)
if len(p.tok.Data) == 0 {
// It was all whitespace, so ignore it.
return true
}
case CommentToken:
p.doc.AppendChild(&Node{
Type: CommentNode,
Data: p.tok.Data,
Loc: p.generateLoc(),
})
return true
case DoctypeToken:
n, quirks := parseDoctype(p.tok.Data)
p.doc.AppendChild(n)
p.quirks = quirks
p.im = beforeHTMLIM
return true
}
if p.frontmatterState == FrontmatterInitial {
p.addFrontmatter(true)
}
p.quirks = true
p.im = beforeHTMLIM
return false
}
// Section 12.2.6.4.2.
func beforeHTMLIM(p *parser) bool {
switch p.tok.Type {
case DoctypeToken:
// Ignore the token.
return true
case TextToken:
p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace)
if len(p.tok.Data) == 0 {
// It was all whitespace, so ignore it.
return true
}
case StartTagToken:
switch p.tok.DataAtom {
case a.Html:
p.addElement()
p.im = beforeHeadIM
return true
case a.Script:
p.addElement()
if p.originalIM == nil {
p.setOriginalIM()
}
p.im = textIM
if p.hasSelfClosingToken {
p.addLoc()
p.oe.pop()
p.acknowledgeSelfClosingTag()
}
return true
}
if isComponent(p.tok.Data) {
p.addElement()
p.im = inBodyIM
if p.hasSelfClosingToken {
p.oe.pop()
p.acknowledgeSelfClosingTag()
}
return true
}
if p.literal {
p.im = inLiteralIM
p.originalIM = beforeHTMLIM
return false
}
case EndTagToken:
switch p.tok.DataAtom {
case a.Script:
p.oe.pop()
return true
case a.Head, a.Body, a.Html, a.Br:
p.parseImpliedToken(StartTagToken, a.Html, a.Html.String())
return false
default:
// Ignore the token.
return true
}
case CommentToken:
p.doc.AppendChild(&Node{
Type: CommentNode,
Data: p.tok.Data,
Loc: p.generateLoc(),
})
return true
}
p.parseImpliedToken(StartTagToken, a.Html, a.Html.String())
return false
}
// Section 12.2.6.4.3.
func beforeHeadIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
p.addText(p.tok.Data)
return true
case StartTagToken:
switch p.tok.DataAtom {
case a.Slot:
p.addElement()
if p.hasSelfClosingToken {
p.addLoc()
p.oe.pop()
p.acknowledgeSelfClosingTag()
}
return true
case a.Head:
p.addElement()
p.head = p.top()
p.im = inHeadIM
return true
case a.Html:
return inBodyIM(p)
}
case EndTagToken:
switch p.tok.DataAtom {
case a.Head, a.Body, a.Html, a.Br:
p.parseImpliedToken(StartTagToken, a.Head, a.Head.String())
return false
default:
// Ignore the token.
return true
}
case CommentToken:
p.addChild(&Node{
Type: CommentNode,
Data: p.tok.Data,
Loc: p.generateLoc(),
})
return true
case DoctypeToken:
// Ignore the token.
return true
case StartExpressionToken:
p.parseImpliedToken(StartTagToken, a.Head, a.Head.String())
p.addExpression()
p.afe = append(p.afe, &scopeMarker)
p.setOriginalIM()
p.im = inExpressionIM
return true
}
p.parseImpliedToken(StartTagToken, a.Head, a.Head.String())
return false
}
// Section 12.2.6.4.4.
func inHeadIM(p *parser) bool {
switch p.tok.Type {
case TextToken:
s := strings.TrimLeft(p.tok.Data, whitespace)
if len(s) < len(p.tok.Data) {
// Add the initial whitespace to the current node.
p.addText(p.tok.Data[:len(p.tok.Data)-len(s)])
if s == "" {
return true
}
p.tok.Data = s
return textIM(p)
} else if p.oe.top() != nil && (isComponent(p.oe.top().Data) || isFragment((p.oe.top().Data))) {
p.addText(p.tok.Data)
return true
}
case StartTagToken:
// Allow components in Head
if isComponent(p.tok.Data) || isFragment(p.tok.Data) {
p.im = inLiteralIM
p.originalIM = inHeadIM
p.exitLiteralIM = getExitLiteralFunc(p)
return false
}
switch p.tok.DataAtom {
case a.Html:
return inBodyIM(p)
case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta:
p.addElement()
p.oe.pop()
p.acknowledgeSelfClosingTag()
return true
case a.Slot:
p.addElement()
if p.hasSelfClosingToken {
p.addLoc()
p.oe.pop()
p.acknowledgeSelfClosingTag()
}
return true
case a.Noscript:
p.addElement()
p.im = inHeadNoscriptIM
// Don't let the tokenizer go into raw text mode when scripting is disabled.
p.tokenizer.NextIsNotRawText()
return true
case a.Script, a.Title:
p.addElement()
if p.originalIM == nil {
p.setOriginalIM()
}
p.im = textIM
if p.hasSelfClosingToken {
p.addLoc()
p.oe.pop()
p.acknowledgeSelfClosingTag()
}
return true
case a.Noframes, a.Style:
p.parseGenericRawTextElement()
if p.hasSelfClosingToken {
p.addLoc()
p.oe.pop()
p.acknowledgeSelfClosingTag()
}
return true
case a.Head:
// Ignore the token, but copy attributes and remove implicit marker
// if an explicit tag is encountered (fixes issue #1124)
if p.head != nil {
copyAttributes(p.head, p.tok)
removeImplicitMarker(p.head)
}
return true
case a.Template:
// TODO: remove this divergence from the HTML5 spec.
//
// We don't handle all of the corner cases when mixing foreign
// content (i.e.
);
})
}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Astro = $$createAstro('https://astro.build');
const Astro = $$Astro;
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const Astro = $$result.createAstro($$props, $$slots);
Astro.self = $$Component;
return $$render`${$$renderComponent($$result,'Layout',Layout,{"title":"Welcome to Astro."},{"default": () => $$render`
${$$maybeRenderHead($$result)}
}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"a": () => $$render`${true && $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const items = ['red', 'yellow', 'blue'];
return $$render`${$$maybeRenderHead($$result)}
{
() => {
let generate = (input) => {
let a = () => { return; };
let b = () => { return; };
let c = () => { return; };
};
}
}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${
() => {
let generate = (input) => {
let a = () => { return; };
let b = () => { return; };
let c = () => { return; };
};
}
}
${$$renderComponent($$result,'Footer',Footer,{})}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/import.meta.snap
================================================
[TestPrinter/import.meta - 1]
## Input
```
/-/-/-/
const components = import.meta.glob("../components/*.astro", {
import: 'default'
});
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const components = import.meta.glob("../components/*.astro", {
import: 'default'
});
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/import_assertions.snap
================================================
[TestPrinter/import_assertions - 1]
## Input
```
/-/-/-/
import data from "test" assert { type: 'json' };
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import data from "test" assert { type: 'json' };
import * as $$module1 from 'test' assert {type:'json'};
export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {type:'json'} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/import_order.snap
================================================
[TestPrinter/import_order - 1]
## Input
```
/-/-/-/
let testWord = "Test"
// comment
import data from "test";
/-/-/-/
{data}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import data from "test";
import * as $$module1 from 'test';
export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
let testWord = "Test"
// comment
return $$render`${$$maybeRenderHead($$result)}
${data}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/import_to_identifier_named_assert.snap
================================================
[TestPrinter/import_to_identifier_named_assert - 1]
## Input
```
/-/-/-/
import assert from 'test';
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import assert from 'test';
import * as $$module1 from 'test';
export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/includes_comments_for_expression_attribute.snap
================================================
[TestPrinter/includes_comments_for_expression_attribute - 1]
## Input
```
Hello
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
Hello
${$$renderComponent($$result,'Component',Component,{"id":(/* comment 1 */ id /* comment 2 */)})}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/is_raw.snap
================================================
[TestPrinter/is:raw - 1]
## Input
```
<% awesome %>
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}<% awesome %>`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/jsx_comment_between_doctype_and_html.snap
================================================
[TestPrinter/jsx_comment_between_doctype_and_html - 1]
## Input
```
{/* Comment */}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`
${$$renderHead($$result)}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/map_basic.snap
================================================
[TestPrinter/map_basic - 1]
## Input
```
/-/-/-/
const items = [0, 1, 2];
/-/-/-/
{items.map(item => {
return
{item}
;
})}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const items = [0, 1, 2];
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const groups = [[0, 1, 2], [3, 4, 5]];
return $$render`${$$maybeRenderHead($$result)}
${groups.map(items => {
return $$render`
${
items.map(item => {
return $$render`
${item}
`;
})
}
`
})}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/map_with_component.snap
================================================
[TestPrinter/map_with_component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$renderComponent($$result,'Hello',Hello,{})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/map_without_component.snap
================================================
[TestPrinter/map_without_component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/maybeRenderHead_not_printed_for_hoisted_scripts.snap
================================================
[TestPrinter/maybeRenderHead_not_printed_for_hoisted_scripts - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Page = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderScript($$result,"/projects/app/src/pages/page.astro?astro&type=script&index=0&lang.ts")}${$$renderComponent($$result,'Layout',Layout,{})}`;
}, '/projects/app/src/pages/page.astro', undefined);
export default $$Page;
```
---
================================================
FILE: internal/printer/__printer_js__/multibyte_character___script.snap
================================================
[TestPrinter/multibyte_character_+_script - 1]
## Input
```
ツ
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log('foo')` }] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderScript($$result,"?astro&type=script&index=0&lang.ts")}${$$maybeRenderHead($$result)}ツ`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/multibyte_character___style.snap
================================================
[TestPrinter/multibyte_character_+_style - 1]
## Input
```
ツ
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}ツ`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/multibyte_characters.snap
================================================
[TestPrinter/multibyte_characters - 1]
## Input
```
/-/-/-/
/-/-/-/
こんにちは
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
こんにちは
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/multiline_class_attribute_on_component.snap
================================================
[TestPrinter/multiline_class_attribute_on_component - 1]
## Input
```
content
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{"class":"some-class\n another-class\n third-class"},{"default": () => $$render`content`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/multiple_define_vars_on_style.snap
================================================
[TestPrinter/multiple_define:vars_on_style - 1]
## Input
```
foo
bar
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const $$definedVars = $$defineStyleVars([{color:'green'},{color:'red'}]);
return $$render`${$$maybeRenderHead($$result)}
foo
bar
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/namespace_is_preserved_when_inside_an_expression.snap
================================================
[TestPrinter/namespace_is_preserved_when_inside_an_expression - 1]
## Input
```
{}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$render``}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/nested_expressions.snap
================================================
[TestPrinter/nested_expressions - 1]
## Input
```
{(previous || next) && }
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Astro = $$createAstro('https://astro.build');
const Astro = $$Astro;
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const Astro = $$result.createAstro($$props, $$slots);
Astro.self = $$Component;
return $$render`${$$maybeRenderHead($$result)}${(previous || next) && $$render``}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/nested_expressions_II.snap
================================================
[TestPrinter/nested_expressions_II - 1]
## Input
```
{(previous || next) && }
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Astro = $$createAstro('https://astro.build');
const Astro = $$Astro;
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const Astro = $$result.createAstro($$props, $$slots);
Astro.self = $$Component;
return $$render`${$$maybeRenderHead($$result)}${(previous || next) && $$render``}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/nested_expressions_III.snap
================================================
[TestPrinter/nested_expressions_III - 1]
## Input
```
{x.map((x) => x ?
{true ? {x} : null}
:
{false ? null : {x}}
)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
{() => { if (value > 0.25) { return Default } else if (value > 0.5) { return Another } else if (value > 0.75) { return Other } return Yet Other }}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
{()=>{ if (true) { return ;} if (true) { return ;}}}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${()=>{ if (true) { return $$render``;} if (true) { return $$render``;}}}
{() => { if (value > 0.25) { return ;} else if (value > 0.5) { return ;} else if (value > 0.75) { return ;} return
Yaaay
;}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${() => { if (value > 0.25) { return $$render` `;} else if (value > 0.5) { return $$render``;} else if (value > 0.75) { return $$render``;} return $$render`
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const meta = { title: 'My App' };
return $$render`
${
meta && $$render`${meta.title}`
}
${$$renderHead($$result)}
My App
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/nested_template_literal_expression.snap
================================================
[TestPrinter/nested_template_literal_expression - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
[TestPrinter/nested_template_literal_expression#01 - 1]
## Input
```
{Object.keys(importedAuthors).map(author =>
hello
)}
{Object.keys(importedAuthors).map(author =>
{author}
)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`
${$$maybeRenderHead($$result)}
${Object.keys(importedAuthors).map(author => $$render`
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
Hello, world! This is a buggy formula: f:X→R2x
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/noscript_component.snap
================================================
[TestPrinter/noscript_component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`
${$$renderHead($$result)}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/noscript_deep_styles.snap
================================================
[TestPrinter/noscript_deep_styles - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/noscript_only.snap
================================================
[TestPrinter/noscript_only - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/noscript_styles.snap
================================================
[TestPrinter/noscript_styles - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/orphan_slot.snap
================================================
[TestPrinter/orphan_slot - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderSlot($$result,$$slots["default"])}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/passes_escaped_filename_into_createComponent_if_it_contains_single_quotes.snap
================================================
[TestPrinter/passes_escaped_filename_into_createComponent_if_it_contains_single_quotes - 1]
## Input
```
test
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/projects/app/src/pages/page-with-\'-quotes.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$PageWithQuotes = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Page = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
test
`;
}, '/projects/app/src/pages/page.astro', undefined);
export default $$Page;
```
---
================================================
FILE: internal/printer/__printer_js__/preserve_is_inline_slot.snap
================================================
[TestPrinter/preserve_is:inline_slot - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/preserve_is_inline_slot_II.snap
================================================
[TestPrinter/preserve_is:inline_slot_II - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script.snap
================================================
[TestPrinter/script - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log("Hello");` }] });
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
================================================
FILE: internal/printer/__printer_js__/script_before_elements.snap
================================================
[TestPrinter/script_before_elements - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `Here` }] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderScript($$result,"?astro&type=script&index=0&lang.ts")}${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script_define_vars_I.snap
================================================
[TestPrinter/script_define:vars_I - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script_define_vars_II.snap
================================================
[TestPrinter/script_define:vars_II - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script_external.snap
================================================
[TestPrinter/script_external - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'external', src: './hello.js' }] });
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
================================================
FILE: internal/printer/__printer_js__/script_external_in_expression.snap
================================================
[TestPrinter/script_external_in_expression - 1]
## Input
```
{}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'external', src: './hello.js' }] });
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$render`${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`}`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
================================================
FILE: internal/printer/__printer_js__/script_hoist_with_frontmatter.snap
================================================
[TestPrinter/script_hoist_with_frontmatter - 1]
## Input
```
/-/-/-/
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log("Hello");` }] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderScript($$result,"?astro&type=script&index=0&lang.ts")}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script_hoist_without_frontmatter.snap
================================================
[TestPrinter/script_hoist_without_frontmatter - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log("Hello");` }] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${$$renderScript($$result,"?astro&type=script&index=0&lang.ts")}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script_in__head_.snap
================================================
[TestPrinter/script_in_ - 1]
## Input
```
/-/-/-/
import Widget from '../components/Widget.astro';
import Widget2 from '../components/Widget2.astro';
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import Widget from '../components/Widget.astro';
import Widget2 from '../components/Widget2.astro';
import * as $$module1 from '../components/Widget.astro';
import * as $$module2 from '../components/Widget2.astro';
export 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: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`
${$$renderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script_in_expression.snap
================================================
[TestPrinter/script_in_expression - 1]
## Input
```
{true && }
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log("hello")` }] });
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${true && $$render`${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`}`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
================================================
FILE: internal/printer/__printer_js__/script_inline.snap
================================================
[TestPrinter/script_inline - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/script_mixed_handled_and_inline.snap
================================================
[TestPrinter/script_mixed_handled_and_inline - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata("/src/pages/index.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [{ type: 'inline', value: `console.log("Hello");` }] });
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$renderScript($$result,"/src/pages/index.astro?astro&type=script&index=0&lang.ts")}`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
================================================
FILE: internal/printer/__printer_js__/script_multiple.snap
================================================
[TestPrinter/script_multiple - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export 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");` }] });
const $$Index = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$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")}`;
}, '/src/pages/index.astro', undefined);
export default $$Index;
```
---
================================================
FILE: internal/printer/__printer_js__/scriptinline.snap
================================================
[TestPrinter/scriptinline - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/select_in_form.snap
================================================
[TestPrinter/select_in_form - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/select_map_expression.snap
================================================
[TestPrinter/select_map_expression - 1]
## Input
```
Hello world!
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
Hello world!
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/select_nested_option.snap
================================================
[TestPrinter/select_nested_option - 1]
## Input
```
/-/-/-/
const value = 'test';
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const value = 'test';
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/select_option_expression.snap
================================================
[TestPrinter/select_option_expression - 1]
## Input
```
/-/-/-/
const value = 'test';
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const value = 'test';
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/selectedcontent_element_in_customizable_select.snap
================================================
[TestPrinter/selectedcontent_element_in_customizable_select - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/selectedcontent_self-closing_element.snap
================================================
[TestPrinter/selectedcontent_self-closing_element - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/self-closing_td.snap
================================================
[TestPrinter/self-closing_td - 1]
## Input
```
{data.map(row =>
{row.map(cell =>
)}
)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${data.map(row => $$render`
${row.map(cell => $$render`
${$$unescapeHTML(cell)}
`)}
`)}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html.snap
================================================
[TestPrinter/set:html - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$unescapeHTML(content)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_and_set_text.snap
================================================
[TestPrinter/set:html_and_set:text - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$unescapeHTML(content)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Component.snap
================================================
[TestPrinter/set:html_on_Component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${$$unescapeHTML(content)}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Component_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_Component_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${"content"}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Component_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_Component_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${`${content}`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Component_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_Component_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${`content`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Fragment.snap
================================================
[TestPrinter/set:html_on_Fragment - 1]
## Input
```
<i>This should NOT be italic</i>"} />
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render`${$$unescapeHTML("
<i>This should NOT be italic</i>
")}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Fragment_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_Fragment_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render`${"
This should NOT be italic
"}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Fragment_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_Fragment_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render`${`${content}`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_Fragment_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_Fragment_with_template_literal_attribute_without_variable - 1]
## Input
```
<i>This should NOT be italic</i>` />
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Fragment',Fragment,{},{"default": () => $$render`${`
This should NOT be italic
`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_custom-element.snap
================================================
[TestPrinter/set:html_on_custom-element - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`${$$unescapeHTML(content)}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_custom-element_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_custom-element_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`${"content"}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_custom-element_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_custom-element_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`${`${content}`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_custom-element_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_custom-element_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`${`content`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_empty_tag.snap
================================================
[TestPrinter/set:html_on_empty_tag - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$unescapeHTML(content)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_empty_tag_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_empty_tag_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${"content"}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_empty_tag_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_empty_tag_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`${content}`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_empty_tag_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_empty_tag_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`content`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_script.snap
================================================
[TestPrinter/set:html_on_script - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_script_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_script_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_script_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_script_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_script_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_script_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_self-closing_tag.snap
================================================
[TestPrinter/set:html_on_self-closing_tag - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$unescapeHTML(content)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_self-closing_tag_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_self-closing_tag_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${"content"}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_self-closing_tag_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_self-closing_tag_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`${content}`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_self-closing_tag_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_self-closing_tag_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`content`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_style.snap
================================================
[TestPrinter/set:html_on_style - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_style_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_style_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_style_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_style_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_style_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_style_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_children.snap
================================================
[TestPrinter/set:html_on_tag_with_children - 1]
## Input
```
!!!
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$unescapeHTML(content)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_children_and_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_tag_with_children_and_quoted_attribute - 1]
## Input
```
!!!
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${"content"}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_children_and_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_tag_with_children_and_template_literal_attribute_with_variable - 1]
## Input
```
!!!
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`${content}`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_children_and_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_tag_with_children_and_template_literal_attribute_without_variable - 1]
## Input
```
!!!
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`content`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace.snap
================================================
[TestPrinter/set:html_on_tag_with_empty_whitespace - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$unescapeHTML(content)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace_and_quoted_attribute.snap
================================================
[TestPrinter/set:html_on_tag_with_empty_whitespace_and_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${"content"}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace_and_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_on_tag_with_empty_whitespace_and_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`${content}`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_on_tag_with_empty_whitespace_and_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_on_tag_with_empty_whitespace_and_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`content`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_with_other_attributes.snap
================================================
[TestPrinter/set:html_with_other_attributes - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$unescapeHTML(content)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_with_quoted_attribute.snap
================================================
[TestPrinter/set:html_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${"content"}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_with_quoted_attribute_and_other_attributes.snap
================================================
[TestPrinter/set:html_with_quoted_attribute_and_other_attributes - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${"content"}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:html_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`${content}`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_with_template_literal_attribute_with_variable_and_other_attributes.snap
================================================
[TestPrinter/set:html_with_template_literal_attribute_with_variable_and_other_attributes - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`${content}`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:html_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`content`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_html_with_template_literal_attribute_without_variable_and_other_attributes.snap
================================================
[TestPrinter/set:html_with_template_literal_attribute_without_variable_and_other_attributes - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`content`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text.snap
================================================
[TestPrinter/set:text - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${content}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_Component.snap
================================================
[TestPrinter/set:text_on_Component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${content}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_Component_with_quoted_attribute.snap
================================================
[TestPrinter/set:text_on_Component_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`content`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_Component_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:text_on_Component_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${`${content}`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_Component_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:text_on_Component_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${`content`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_custom-element.snap
================================================
[TestPrinter/set:text_on_custom-element - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`${content}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_custom-element_with_quoted_attribute.snap
================================================
[TestPrinter/set:text_on_custom-element_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`content`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_custom-element_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:text_on_custom-element_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`${`${content}`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_on_custom-element_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:text_on_custom-element_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'custom-element','custom-element',{},{"default": () => $$render`${`content`}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_with_quoted_attribute.snap
================================================
[TestPrinter/set:text_with_quoted_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}content`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_with_template_literal_attribute_with_variable.snap
================================================
[TestPrinter/set:text_with_template_literal_attribute_with_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`${content}`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/set_text_with_template_literal_attribute_without_variable.snap
================================================
[TestPrinter/set:text_with_template_literal_attribute_without_variable - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${`content`}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/sibling_expressions.snap
================================================
[TestPrinter/sibling_expressions - 1]
## Input
```
{true ? (
Row 1
) : null}
{true ? (
Row 2
) : null}
{true ? (
Row 3
) : null}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${link ? $$render`${link}` : $$render`
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Base',Base,{"title":"Home"},{"default": () => $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}${$$renderSlot($$result,$$slots["default"],$$render`
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderSlot($$result,$$slots["test"],$$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${$$renderSlot($$result,$$slots["test"],$$render`
Fallback
`)}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/slot_with_quoted_attributes.snap
================================================
[TestPrinter/slot_with_quoted_attributes - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"\"name\"": () => $$render`${$$maybeRenderHead($$result)}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/slots__basic_.snap
================================================
[TestPrinter/slots_(basic) - 1]
## Input
```
/-/-/-/
import Component from "test";
/-/-/-/
Default
Named
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import Component from "test";
import * as $$module1 from 'test';
export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`
${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import Component from 'test';
import * as $$module1 from 'test';
export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const name = 'named';
return $$render`${$$renderComponent($$result,'Component',Component,{},{[name]: () => $$render`${$$maybeRenderHead($$result)}
)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{"data":(data)},{"default": () => $$render`${items.map(item => $$render`${$$maybeRenderHead($$result)}
${item}
`)}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/slots__named_only_.snap
================================================
[TestPrinter/slots_(named_only) - 1]
## Input
```
ABC
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Slotted',Slotted,{},{"a": () => $$render`${$$maybeRenderHead($$result)}A`,"b": () => $$render`B`,"c": () => $$render`C`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/slots__no_comments_.snap
================================================
[TestPrinter/slots_(no_comments) - 1]
## Input
```
/-/-/-/
import Component from 'test';
/-/-/-/
Default
Named
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import Component from 'test';
import * as $$module1 from 'test';
export const $$metadata = $$createMetadata(import.meta.url, { modules: [{ module: $$module1, specifier: 'test', assert: {} }], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`
${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/solidus_in_template_literal_expression.snap
================================================
[TestPrinter/solidus_in_template_literal_expression - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/spread_with_double_quotation_marks.snap
================================================
[TestPrinter/spread_with_double_quotation_marks - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/spread_with_style_but_no_explicit_class.snap
================================================
[TestPrinter/spread_with_style_but_no_explicit_class - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Astro = $$createAstro('https://astro.build');
const Astro = $$Astro;
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const Astro = $$result.createAstro($$props, $$slots);
Astro.self = $$Component;
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/spread_without_style_or_class.snap
================================================
[TestPrinter/spread_without_style_or_class - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Astro = $$createAstro('https://astro.build');
const Astro = $$Astro;
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const Astro = $$result.createAstro($$props, $$slots);
Astro.self = $$Component;
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/styles__no_frontmatter_.snap
================================================
[TestPrinter/styles_(no_frontmatter) - 1]
## Input
```
Page Title
I’m a page
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`
${$$maybeRenderHead($$result)}
Page Title
I’m a page
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/svg_expressions.snap
================================================
[TestPrinter/svg_expressions - 1]
## Input
```
/-/-/-/
const title = 'icon';
/-/-/-/
{title ?? null}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const title = 'icon';
return $$render`${$$maybeRenderHead($$result)}${title ?? null}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/table.snap
================================================
[TestPrinter/table - 1]
## Input
```
{[0,1,2].map(x => (
{x}
))}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const items = ["Dog", "Cat", "Platipus"];
return $$render`${$$maybeRenderHead($$result)}
Hello
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const content = "lol";
return $$render`
${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const items = ["Dog", "Cat", "Platipus"];
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const items = ["Dog", "Cat", "Platipus"];
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${data.map(row => $$render`
${row.map(cell => $$render`
${cell}
`)}
`)}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/template_literal_attribute_on_component.snap
================================================
[TestPrinter/template_literal_attribute_on_component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{"class":`red`})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/template_literal_attribute_with_variable_on_component.snap
================================================
[TestPrinter/template_literal_attribute_with_variable_on_component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{"class":`${color}`})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/ternary_component.snap
================================================
[TestPrinter/ternary_component - 1]
## Input
```
{special ?
Special
:
Not special
}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${special ? $$render`${$$renderComponent($$result,'ChildDiv',ChildDiv,{},{"default": () => $$render`${$$maybeRenderHead($$result)}
}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},$$mergeSlots({},Math.random() > 0.5 ? {"a": () => $$render`${$$maybeRenderHead($$result)}
A
`} : {"b": () => $$render`
B
`}))}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/text_after_title_expression.snap
================================================
[TestPrinter/text_after_title_expression - 1]
## Input
```
a {expr} b
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`a ${expr} b`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/text_after_title_expressions.snap
================================================
[TestPrinter/text_after_title_expressions - 1]
## Input
```
a {expr} b {expr} c
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`a ${expr} b ${expr} c`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/text_only.snap
================================================
[TestPrinter/text_only - 1]
## Input
```
Foo
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`Foo`;
}, undefined, undefined);
export default $$Component;
```
---
[TestPrinter/text_only#01 - 1]
## Input
```
Hello!
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`Hello!`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/textarea.snap
================================================
[TestPrinter/textarea - 1]
## Input
```
/-/-/-/
const value = 'test';
/-/-/-/
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
const value = 'test';
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/textarea_in_form.snap
================================================
[TestPrinter/textarea_in_form - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{},{"default": () => $$render`${$$maybeRenderHead($$result)}`,})}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/textarea_inside_expression.snap
================================================
[TestPrinter/textarea_inside_expression - 1]
## Input
```
{bool && } {!bool && }
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${bool && $$render`${$$maybeRenderHead($$result)}`} ${!bool && $$render``}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/th_expressions.snap
================================================
[TestPrinter/th_expressions - 1]
## Input
```
{title}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
col 1
col 2
${foo}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/trailing_expression.snap
================================================
[TestPrinter/trailing_expression - 1]
## Input
```
{}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{})}${(void 0)}`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/transition_animate_on_Component.snap
================================================
[TestPrinter/transition:animate_on_Component - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import "transitions.css";
export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Page = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'Component',Component,{"class":"bar","data-astro-transition-scope":($$renderTransition($$result, "wkm5vset", "morph", ""))})}`;
}, '/projects/app/src/pages/page.astro', 'self');
export default $$Page;
```
---
================================================
FILE: internal/printer/__printer_js__/transition_animate_with_an_expression.snap
================================================
[TestPrinter/transition:animate_with_an_expression - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import "transitions.css";
export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Page = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, '/projects/app/src/pages/page.astro', 'self');
export default $$Page;
```
---
================================================
FILE: internal/printer/__printer_js__/transition_name_with_an_expression.snap
================================================
[TestPrinter/transition:name_with_an_expression - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import "transitions.css";
export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Page = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, '/projects/app/src/pages/page.astro', 'self');
export default $$Page;
```
---
================================================
FILE: internal/printer/__printer_js__/transition_name_with_an_template_literal.snap
================================================
[TestPrinter/transition:name_with_an_template_literal - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import "transitions.css";
export const $$metadata = $$createMetadata("/projects/app/src/pages/page.astro", { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Page = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, '/projects/app/src/pages/page.astro', 'self');
export default $$Page;
```
---
================================================
FILE: internal/printer/__printer_js__/transition_persist-props_converted_to_a_data_attribute.snap
================================================
[TestPrinter/transition:persist-props_converted_to_a_data_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import "transitions.css";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$renderComponent($$result,'my-island','my-island',{"data-astro-transition-persist-props":"false","data-astro-transition-persist":($$createTransitionScope($$result, "otghnj5u"))})}`;
}, undefined, 'self');
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/transition_persist_converted_to_a_data_attribute.snap
================================================
[TestPrinter/transition:persist_converted_to_a_data_attribute - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import "transitions.css";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, 'self');
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/transition_persist_uses_transition_name_if_defined.snap
================================================
[TestPrinter/transition:persist_uses_transition:name_if_defined - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import "transitions.css";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}`;
}, undefined, 'self');
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/type_import.snap
================================================
[TestPrinter/type_import - 1]
## Input
```
/-/-/-/
import type data from "test"
/-/-/-/
{data}
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
import type data from "test"
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`${$$maybeRenderHead($$result)}
${data}
`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/unusual_line_terminator_I.snap
================================================
[TestPrinter/unusual_line_terminator_I - 1]
## Input
```
Pre-set & Time-limited \u2028holiday campaigns
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`Pre-set & Time-limited \\u2028holiday campaigns`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/unusual_line_terminator_II.snap
================================================
[TestPrinter/unusual_line_terminator_II - 1]
## Input
```
Pre-set & Time-limited holiday campaigns
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render`Pre-set & Time-limited holiday campaigns`;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_js__/user-defined__implicit__is_printed.snap
================================================
[TestPrinter/user-defined_`implicit`_is_printed - 1]
## Input
```
```
## Output
```js
import {
Fragment,
render as $$render,
createAstro as $$createAstro,
createComponent as $$createComponent,
renderComponent as $$renderComponent,
renderHead as $$renderHead,
maybeRenderHead as $$maybeRenderHead,
unescapeHTML as $$unescapeHTML,
renderSlot as $$renderSlot,
mergeSlots as $$mergeSlots,
addAttribute as $$addAttribute,
spreadAttributes as $$spreadAttributes,
defineStyleVars as $$defineStyleVars,
defineScriptVars as $$defineScriptVars,
renderTransition as $$renderTransition,
createTransitionScope as $$createTransitionScope,
renderScript as $$renderScript,
createMetadata as $$createMetadata
} from "http://localhost:3000/";
export const $$metadata = $$createMetadata(import.meta.url, { modules: [], hydratedComponents: [], clientOnlyComponents: [], hydrationDirectives: new Set([]), hoisted: [] });
const $$Component = $$createComponent(($$result, $$props, $$slots) => {
return $$render``;
}, undefined, undefined);
export default $$Component;
```
---
================================================
FILE: internal/printer/__printer_json__/Comment.snap
================================================
[TestPrintToJSON/Comment - 1]
## Input
```
```
## Output
```json
{"type":"root","children":[{"type":"comment","value":"hello"}]}
```
---
================================================
FILE: internal/printer/__printer_json__/Comment_preserves_whitespace.snap
================================================
[TestPrintToJSON/Comment_preserves_whitespace - 1]
## Input
```
```
## Output
```json
{"type":"root","children":[{"type":"comment","value":" hello "}]}
```
---
================================================
FILE: internal/printer/__printer_json__/Component.snap
================================================
[TestPrintToJSON/Component - 1]
## Input
```
```
## Output
```json
{"type":"root","children":[{"type":"component","name":"Component","attributes":[],"children":[]}]}
```
---
================================================
FILE: internal/printer/__printer_json__/Doctype.snap
================================================
[TestPrintToJSON/Doctype - 1]
## Input
```
```
## Output
```json
{"type":"root","children":[{"type":"doctype","value":"html"}]}
```
---
================================================
FILE: internal/printer/__printer_json__/Fragment_Literal.snap
================================================
[TestPrintToJSON/Fragment_Literal - 1]
## Input
```
World
```
## Output
```json
{"type":"root","children":[{"type":"fragment","name":"Fragment","attributes":[],"children":[{"type":"text","value":"World"}]}]}
```
---
================================================
FILE: internal/printer/__printer_json__/Fragment_Shorthand.snap
================================================
[TestPrintToJSON/Fragment_Shorthand - 1]
## Input
```
<>Hello>
```
## Output
```json
{"type":"root","children":[{"type":"fragment","name":"","attributes":[],"children":[{"type":"text","value":"Hello"}]}]}
```
---
================================================
FILE: internal/printer/__printer_json__/Frontmatter.snap
================================================
[TestPrintToJSON/Frontmatter - 1]
## Input
```
/-/-/-/
const a = "hey"
/-/-/-/
{a}
```
## Output
```json
{"type":"root","children":[{"type":"frontmatter","value":"\nconst a = \"hey\"\n"},{"type":"element","name":"div","attributes":[],"children":[{"type":"expression","children":[{"type":"text","value":"a"}]}]}]}
```
---
================================================
FILE: internal/printer/__printer_json__/JSON_escape.snap
================================================
[TestPrintToJSON/JSON_escape - 1]
## Input
```
/-/-/-/
const a = "\n"
const b = "\""
const c = '\''
/-/-/-/
{a + b + c}
```
## Output
```json
{"type":"root","children":[{"type":"frontmatter","value":"\nconst a = \"\\n\"\nconst b = \"\\\"\"\nconst c = '\\''\n"},{"type":"expression","children":[{"type":"text","value":"a + b + c"}]}]}
```
---
================================================
FILE: internal/printer/__printer_json__/Preserve_namespaces.snap
================================================
[TestPrintToJSON/Preserve_namespaces - 1]
## Input
```
```
## Output
```json
{"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":[]}]}]}
```
---
================================================
FILE: internal/printer/__printer_json__/basic.snap
================================================
[TestPrintToJSON/basic - 1]
## Input
```
```
## Output
```json
{"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":[]}]}]}
```
---
================================================
FILE: internal/printer/print-css.go
================================================
package printer
import (
"strings"
. "github.com/withastro/compiler/internal"
"github.com/withastro/compiler/internal/sourcemap"
"github.com/withastro/compiler/internal/transform"
)
type PrintCSSResult struct {
Output [][]byte
SourceMapChunk sourcemap.Chunk
}
func PrintCSS(sourcetext string, doc *Node, opts transform.TransformOptions) PrintCSSResult {
p := &printer{
opts: opts,
builder: sourcemap.MakeChunkBuilder(nil, sourcemap.GenerateLineOffsetTables(sourcetext, len(strings.Split(sourcetext, "\n")))),
}
result := PrintCSSResult{
SourceMapChunk: p.builder.GenerateChunk(p.output),
}
if len(doc.Styles) > 0 {
for _, style := range doc.Styles {
if style.FirstChild != nil && strings.TrimSpace(style.FirstChild.Data) != "" {
p.addSourceMapping(style.Loc[0])
p.print(strings.TrimSpace(style.FirstChild.Data))
result.Output = append(result.Output, p.output)
p.output = []byte{}
p.addNilSourceMapping()
}
}
}
return result
}
================================================
FILE: internal/printer/print-to-js.go
================================================
// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package printer
import (
"bytes"
"fmt"
"sort"
"strings"
"unicode"
. "github.com/withastro/compiler/internal"
"github.com/withastro/compiler/internal/handler"
"github.com/withastro/compiler/internal/helpers"
"github.com/withastro/compiler/internal/js_scanner"
"github.com/withastro/compiler/internal/loc"
"github.com/withastro/compiler/internal/sourcemap"
"github.com/withastro/compiler/internal/transform"
"golang.org/x/net/html/atom"
)
// Render renders the parse tree n to the given writer.
//
// Rendering is done on a 'best effort' basis: calling Parse on the output of
// Render will always result in something similar to the original tree, but it
// is not necessarily an exact clone unless the original tree was 'well-formed'.
// 'Well-formed' is not easily specified; the HTML5 specification is
// complicated.
//
// Calling Parse on arbitrary input typically results in a 'well-formed' parse
// tree. However, it is possible for Parse to yield a 'badly-formed' parse tree.
// For example, in a 'well-formed' parse tree, no element is a child of
// another element: parsing "" results in two sibling elements.
// Similarly, in a 'well-formed' parse tree, no element is a child of a
//
`,
},
{
name: "Empty attribute expression",
source: "",
},
{
name: "is:raw",
source: "<% awesome %>",
},
{
name: "Component is:raw",
source: "{<% awesome %>}",
},
{
name: "set:html",
source: "",
},
{
name: "set:html with quoted attribute",
source: ``,
},
{
name: "set:html with template literal attribute without variable",
source: ``,
},
{
name: "set:html with template literal attribute with variable",
source: ``,
},
{
name: "set:text",
source: "",
},
{
name: "set:text with quoted attribute",
source: ``,
},
{
name: "set:text with template literal attribute without variable",
source: ``,
},
{
name: "set:text with template literal attribute with variable",
source: ``,
},
{
name: "set:html on Component",
source: ``,
},
{
name: "set:html on Component with quoted attribute",
source: ``,
},
{
name: "set:html on Component with template literal attribute without variable",
source: ``,
},
{
name: "set:html on Component with template literal attribute with variable",
source: ``,
},
{
name: "set:text on Component",
source: "",
},
{
name: "set:text on Component with quoted attribute",
source: ``,
},
{
name: "set:text on Component with template literal attribute without variable",
source: ``,
},
{
name: "set:text on Component with template literal attribute with variable",
source: ``,
},
{
name: "set:html on custom-element",
source: "",
},
{
name: "set:html on custom-element with quoted attribute",
source: ``,
},
{
name: "set:html on custom-element with template literal attribute without variable",
source: ``,
},
{
name: "set:html on custom-element with template literal attribute with variable",
source: ``,
},
{
name: "set:text on custom-element",
source: "",
},
{
name: "set:text on custom-element with quoted attribute",
source: ``,
},
{
name: "set:text on custom-element with template literal attribute without variable",
source: ``,
},
{
name: "set:text on custom-element with template literal attribute with variable",
source: ``,
},
{
name: "set:html on self-closing tag",
source: "",
},
{
name: "set:html on self-closing tag with quoted attribute",
source: ``,
},
{
name: "set:html on self-closing tag with template literal attribute without variable",
source: ``,
},
{
name: "set:html on self-closing tag with template literal attribute with variable",
source: ``,
},
{
name: "set:html with other attributes",
source: "",
},
{
name: "set:html with quoted attribute and other attributes",
source: ``,
},
{
name: "set:html with template literal attribute without variable and other attributes",
source: ``,
},
{
name: "set:html with template literal attribute with variable and other attributes",
source: ``,
},
{
name: "set:html on empty tag",
source: "",
},
{
name: "set:html on empty tag with quoted attribute",
source: ``,
},
{
name: "set:html on empty tag with template literal attribute without variable",
source: ``,
},
{
name: "set:html on empty tag with template literal attribute with variable",
source: ``,
},
{
// If both "set:*" directives are passed, we only respect the first one
name: "set:html and set:text",
source: "",
},
//
{
name: "set:html on tag with children",
source: "!!!",
},
{
name: "set:html on tag with children and quoted attribute",
source: `!!!`,
},
{
name: "set:html on tag with children and template literal attribute without variable",
source: `!!!`,
},
{
name: "set:html on tag with children and template literal attribute with variable",
source: `!!!`,
},
{
name: "set:html on tag with empty whitespace",
source: "",
},
{
name: "set:html on tag with empty whitespace and quoted attribute",
source: ``,
},
{
name: "set:html on tag with empty whitespace and template literal attribute without variable",
source: ``,
},
{
name: "set:html on tag with empty whitespace and template literal attribute with variable",
source: ``,
},
{
name: "set:html on script",
source: "",
},
{
name: "set:html on script with quoted attribute",
source: ``,
},
{
name: "set:html on script with template literal attribute without variable",
source: ``,
},
{
name: "set:html on script with template literal attribute with variable",
source: ``,
},
{
name: "set:html on style",
source: "",
},
{
name: "set:html on style with quoted attribute",
source: ``,
},
{
name: "set:html on style with template literal attribute without variable",
source: ``,
},
{
name: "set:html on style with template literal attribute with variable",
source: ``,
},
{
name: "set:html on Fragment",
source: "<i>This should NOT be italic</i>\"} />",
},
{
name: "set:html on Fragment with quoted attribute",
source: "<i>This should NOT be italic</i>\" />",
},
{
name: "set:html on Fragment with template literal attribute without variable",
source: "<i>This should NOT be italic</i>` />",
},
{
name: "set:html on Fragment with template literal attribute with variable",
source: ``,
},
{
name: "template literal attribute on component",
source: ``,
},
{
name: "template literal attribute with variable on component",
source: ``,
},
{
name: "define:vars on style",
source: "
testing
",
},
{
name: "define:vars on style tag with style shorthand attribute on element",
source: "
testing
",
},
{
name: "define:vars on style tag with style expression attribute on element",
source: "
testing
",
},
{
name: "define:vars on style tag with style empty attribute on element",
source: "
testing
",
},
{
name: "define:vars on style tag with style quoted attribute on element",
source: "
testing
",
},
{
name: "define:vars on style tag with style template literal attribute on element",
source: "
testing
",
},
{
name: "multiple define:vars on style",
source: "
}",
},
{
name: "define:vars on script with StaticExpression turned on",
// 1. An inline script with is:inline - right
// 2. A hoisted script - wrong, shown up in scripts.add
// 3. A define:vars hoisted script
// 4. A define:vars inline script
source: ``,
},
{
name: "define:vars on a module script with imports",
// Should not wrap with { } scope.
source: ``,
},
{
name: "comments removed from attribute list",
source: `
`,
},
{
name: "JSON escape",
source: `---
const a = "\n"
const b = "\""
const c = '\''
---
{a + b + c}`,
},
{
name: "Preserve namespaces",
source: ``,
},
{
name: "style before html",
source: `
Hello world!
`,
},
{
name: "style after html",
source: `
Hello world!
`,
},
{
name: "style after empty html",
source: ``,
},
{
name: "style after html with component in head",
source: ``,
},
{
name: "style after html with component in head and body",
source: ``,
},
{
name: "style after body with component in head and body",
source: ``,
},
{
name: "style in html",
source: `
Hello world!
`,
},
{
name: "style in body",
source: `
Hello world!
`,
},
{
name: "element with unterminated double quote attribute",
source: ` 0 {
step := count / 2
i := index + step
mapping := mappings[i]
if mapping.GeneratedLine < line || (mapping.GeneratedLine == line && mapping.GeneratedColumn <= column) {
index = i + 1
count -= step + 1
} else {
count = step
}
}
// Handle search failure
if index > 0 {
mapping := &mappings[index-1]
// Match the behavior of the popular "source-map" library from Mozilla
if mapping.GeneratedLine == line {
return mapping
}
}
return nil
}
var base64 = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the continuation
// bit. The continuation bit tells us whether there are more digits in this
// value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
func EncodeVLQ(value int) []byte {
var vlq int
if value < 0 {
vlq = ((-value) << 1) | 1
} else {
vlq = value << 1
}
// Handle the common case up front without allocations
if (vlq >> 5) == 0 {
digit := vlq & 31
return base64[digit : digit+1]
}
encoded := []byte{}
for {
digit := vlq & 31
vlq >>= 5
// If there are still more digits in this value, we must make sure the
// continuation bit is marked
if vlq != 0 {
digit |= 32
}
encoded = append(encoded, base64[digit])
if vlq == 0 {
break
}
}
return encoded
}
func DecodeVLQ(encoded []byte, start int) (int, int) {
shift := 0
vlq := 0
// Scan over the input
for {
index := bytes.IndexByte(base64, encoded[start])
if index < 0 {
break
}
// Decode a single byte
vlq |= (index & 31) << shift
start++
shift += 5
// Stop if there's no continuation bit
if (index & 32) == 0 {
break
}
}
// Recover the value
value := vlq >> 1
if (vlq & 1) != 0 {
value = -value
}
return value, start
}
func DecodeVLQUTF16(encoded []uint16) (int, int, bool) {
n := len(encoded)
if n == 0 {
return 0, 0, false
}
// Scan over the input
current := 0
shift := 0
vlq := 0
for {
if current >= n {
return 0, 0, false
}
index := bytes.IndexByte(base64, byte(encoded[current]))
if index < 0 {
return 0, 0, false
}
// Decode a single byte
vlq |= (index & 31) << shift
current++
shift += 5
// Stop if there's no continuation bit
if (index & 32) == 0 {
break
}
}
// Recover the value
var value = vlq >> 1
if (vlq & 1) != 0 {
value = -value
}
return value, current, true
}
type LineColumnOffset struct {
Lines int
Columns int
}
func (a LineColumnOffset) ComesBefore(b LineColumnOffset) bool {
return a.Lines < b.Lines || (a.Lines == b.Lines && a.Columns < b.Columns)
}
func (a *LineColumnOffset) Add(b LineColumnOffset) {
if b.Lines == 0 {
a.Columns += b.Columns
} else {
a.Lines += b.Lines
a.Columns = b.Columns
}
}
func (offset *LineColumnOffset) AdvanceBytes(bytes []byte) {
columns := offset.Columns
for len(bytes) > 0 {
c, width := utf8.DecodeRune(bytes)
bytes = bytes[width:]
switch c {
case '\r', '\n', '\u2028', '\u2029':
// Handle Windows-specific "\r\n" newlines
if c == '\r' && len(bytes) > 0 && bytes[0] == '\n' {
columns++
continue
}
offset.Lines++
columns = 0
default:
// Mozilla's "source-map" library counts columns using UTF-16 code units
if c <= 0xFFFF {
columns++
} else {
columns += 2
}
}
}
offset.Columns = columns
}
func (offset *LineColumnOffset) AdvanceString(text string) {
columns := offset.Columns
for i, c := range text {
switch c {
case '\r', '\n', '\u2028', '\u2029':
// Handle Windows-specific "\r\n" newlines
if c == '\r' && i+1 < len(text) && text[i+1] == '\n' {
columns++
continue
}
offset.Lines++
columns = 0
default:
// Mozilla's "source-map" library counts columns using UTF-16 code units
if c <= 0xFFFF {
columns++
} else {
columns += 2
}
}
}
offset.Columns = columns
}
type SourceMapPieces struct {
Prefix []byte
Mappings []byte
Suffix []byte
}
func (pieces SourceMapPieces) HasContent() bool {
return len(pieces.Prefix)+len(pieces.Mappings)+len(pieces.Suffix) > 0
}
type SourceMapShift struct {
Before LineColumnOffset
After LineColumnOffset
}
func (pieces SourceMapPieces) Finalize(shifts []SourceMapShift) []byte {
// An optimized path for when there are no shifts
if len(shifts) == 1 {
bytes := pieces.Prefix
minCap := len(bytes) + len(pieces.Mappings) + len(pieces.Suffix)
if cap(bytes) < minCap {
bytes = append(make([]byte, 0, minCap), bytes...)
}
bytes = append(bytes, pieces.Mappings...)
bytes = append(bytes, pieces.Suffix...)
return bytes
}
startOfRun := 0
current := 0
generated := LineColumnOffset{}
prevShiftColumnDelta := 0
j := helpers.Joiner{}
// Start the source map
j.AddBytes(pieces.Prefix)
// This assumes that a) all mappings are valid and b) all mappings are ordered
// by increasing generated position. This should be the case for all mappings
// generated by esbuild, which should be the only mappings we process here.
for current < len(pieces.Mappings) {
// Handle a line break
if pieces.Mappings[current] == ';' {
generated.Lines++
generated.Columns = 0
prevShiftColumnDelta = 0
current++
continue
}
potentialEndOfRun := current
// Read the generated column
generatedColumnDelta, next := DecodeVLQ(pieces.Mappings, current)
generated.Columns += generatedColumnDelta
current = next
potentialStartOfRun := current
// Skip over the original position information
_, current = DecodeVLQ(pieces.Mappings, current) // The original source
_, current = DecodeVLQ(pieces.Mappings, current) // The original line
_, current = DecodeVLQ(pieces.Mappings, current) // The original column
// Skip a trailing comma
if current < len(pieces.Mappings) && pieces.Mappings[current] == ',' {
current++
}
// Detect crossing shift boundaries
didCrossBoundary := false
for len(shifts) > 1 && shifts[1].Before.ComesBefore(generated) {
shifts = shifts[1:]
didCrossBoundary = true
}
if !didCrossBoundary {
continue
}
// This shift isn't relevant if the next mapping after this shift is on a
// following line. In that case, don't split and keep scanning instead.
shift := shifts[0]
if shift.After.Lines != generated.Lines {
continue
}
// Add all previous mappings in a single run for efficiency. Since source
// mappings are relative, no data needs to be modified inside this run.
j.AddBytes(pieces.Mappings[startOfRun:potentialEndOfRun])
// Then modify the first mapping across the shift boundary with the updated
// generated column value. It's simplest to only support column shifts. This
// is reasonable because import paths should not contain newlines.
if shift.Before.Lines != shift.After.Lines {
panic("Unexpected line change when shifting source maps")
}
shiftColumnDelta := shift.After.Columns - shift.Before.Columns
j.AddBytes(EncodeVLQ(generatedColumnDelta + shiftColumnDelta - prevShiftColumnDelta))
prevShiftColumnDelta = shiftColumnDelta
// Finally, start the next run after the end of this generated column offset
startOfRun = potentialStartOfRun
}
// Finish the source map
j.AddBytes(pieces.Mappings[startOfRun:])
j.AddBytes(pieces.Suffix)
return j.Done()
}
// Coordinates in source maps are stored using relative offsets for size
// reasons. When joining together chunks of a source map that were emitted
// in parallel for different parts of a file, we need to fix up the first
// segment of each chunk to be relative to the end of the previous chunk.
type SourceMapState struct {
// This isn't stored in the source map. It's only used by the bundler to join
// source map chunks together correctly.
GeneratedLine int
// These are stored in the source map in VLQ format.
GeneratedColumn int
SourceIndex int
OriginalLine int
OriginalColumn int
}
// Source map chunks are computed in parallel for speed. Each chunk is relative
// to the zero state instead of being relative to the end state of the previous
// chunk, since it's impossible to know the end state of the previous chunk in
// a parallel computation.
//
// After all chunks are computed, they are joined together in a second pass.
// This rewrites the first mapping in each chunk to be relative to the end
// state of the previous chunk.
func AppendSourceMapChunk(j *helpers.Joiner, prevEndState SourceMapState, startState SourceMapState, sourceMap []byte) {
// Handle line breaks in between this mapping and the previous one
if startState.GeneratedLine != 0 {
j.AddBytes(bytes.Repeat([]byte{';'}, startState.GeneratedLine))
prevEndState.GeneratedColumn = 0
}
// Skip past any leading semicolons, which indicate line breaks
semicolons := 0
for sourceMap[semicolons] == ';' {
semicolons++
}
if semicolons > 0 {
j.AddBytes(sourceMap[:semicolons])
sourceMap = sourceMap[semicolons:]
prevEndState.GeneratedColumn = 0
startState.GeneratedColumn = 0
}
// Strip off the first mapping from the buffer. The first mapping should be
// for the start of the original file (the printer always generates one for
// the start of the file).
generatedColumn, i := DecodeVLQ(sourceMap, 0)
sourceIndex, i := DecodeVLQ(sourceMap, i)
originalLine, i := DecodeVLQ(sourceMap, i)
originalColumn, i := DecodeVLQ(sourceMap, i)
sourceMap = sourceMap[i:]
// Rewrite the first mapping to be relative to the end state of the previous
// chunk. We now know what the end state is because we're in the second pass
// where all chunks have already been generated.
startState.SourceIndex += sourceIndex
startState.GeneratedColumn += generatedColumn
startState.OriginalLine += originalLine
startState.OriginalColumn += originalColumn
j.AddBytes(appendMappingToBuffer(nil, j.LastByte(), prevEndState, startState))
// Then append everything after that without modification.
j.AddBytes(sourceMap)
}
func appendMappingToBuffer(buffer []byte, lastByte byte, prevState SourceMapState, currentState SourceMapState) []byte {
// Put commas in between mappings
if lastByte != 0 && lastByte != ';' && lastByte != '"' {
buffer = append(buffer, ',')
}
// Record the generated column (the line is recorded using ';' elsewhere)
buffer = append(buffer, EncodeVLQ(currentState.GeneratedColumn-prevState.GeneratedColumn)...)
prevState.GeneratedColumn = currentState.GeneratedColumn
// Record the generated source
buffer = append(buffer, EncodeVLQ(currentState.SourceIndex-prevState.SourceIndex)...)
prevState.SourceIndex = currentState.SourceIndex
// Record the original line
buffer = append(buffer, EncodeVLQ(currentState.OriginalLine-prevState.OriginalLine)...)
prevState.OriginalLine = currentState.OriginalLine
// Record the original column
buffer = append(buffer, EncodeVLQ(currentState.OriginalColumn-prevState.OriginalColumn)...)
prevState.OriginalColumn = currentState.OriginalColumn
return buffer
}
type LineOffsetTable struct {
byteOffsetToStartOfLine int
// The source map specification is very loose and does not specify what
// column numbers actually mean. The popular "source-map" library from Mozilla
// appears to interpret them as counts of UTF-16 code units, so we generate
// those too for compatibility.
//
// We keep mapping tables around to accelerate conversion from byte offsets
// to UTF-16 code unit counts. However, this mapping takes up a lot of memory
// and generates a lot of garbage. Since most JavaScript is ASCII and the
// mapping for ASCII is 1:1, we avoid creating a table for ASCII-only lines
// as an optimization.
byteOffsetToFirstNonASCII int
columnsForNonASCII []int
utf16LineLength int
}
func GenerateLineOffsetTables(contents string, approximateLineCount int) []LineOffsetTable {
var ColumnsForNonASCII []int
ByteOffsetToFirstNonASCII := int(0)
lineByteOffset := 0
columnByteOffset := 0
column := int(0)
// Preallocate the top-level table using the approximate line count from the lexer
lineOffsetTables := make([]LineOffsetTable, 0, approximateLineCount)
for i, c := range contents {
// Mark the start of the next line
if column == 0 {
lineByteOffset = i
}
// Start the mapping if this character is non-ASCII
if c > 0x7F && ColumnsForNonASCII == nil {
columnByteOffset = i - lineByteOffset
ByteOffsetToFirstNonASCII = int(columnByteOffset)
ColumnsForNonASCII = []int{}
}
// Update the per-byte column offsets
if ColumnsForNonASCII != nil {
for lineBytesSoFar := i - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {
ColumnsForNonASCII = append(ColumnsForNonASCII, column)
}
}
switch c {
case '\r', '\n', '\u2028', '\u2029':
// Handle Windows-specific "\r\n" newlines
if c == '\r' && i+1 < len(contents) && contents[i+1] == '\n' {
column++
continue
}
if c <= 0xFFFF {
column++
} else {
column += 2
}
lineOffsetTables = append(lineOffsetTables, LineOffsetTable{
byteOffsetToStartOfLine: int(lineByteOffset),
byteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,
columnsForNonASCII: ColumnsForNonASCII,
utf16LineLength: column,
})
columnByteOffset = 0
ByteOffsetToFirstNonASCII = 0
ColumnsForNonASCII = nil
column = 0
default:
// Mozilla's "source-map" library counts columns using UTF-16 code units
if c <= 0xFFFF {
column++
} else {
column += 2
}
}
}
// Mark the start of the next line
if column == 0 {
lineByteOffset = len(contents)
}
// Do one last update for the column at the end of the file
if ColumnsForNonASCII != nil {
for lineBytesSoFar := len(contents) - lineByteOffset; columnByteOffset <= lineBytesSoFar; columnByteOffset++ {
ColumnsForNonASCII = append(ColumnsForNonASCII, column)
}
}
lineOffsetTables = append(lineOffsetTables, LineOffsetTable{
byteOffsetToStartOfLine: int(lineByteOffset),
byteOffsetToFirstNonASCII: ByteOffsetToFirstNonASCII,
columnsForNonASCII: ColumnsForNonASCII,
utf16LineLength: column,
})
return lineOffsetTables
}
type Chunk struct {
Buffer []byte
// This end state will be used to rewrite the start of the following source
// map chunk so that the delta-encoded VLQ numbers are preserved.
EndState SourceMapState
// There probably isn't a source mapping at the end of the file (nor should
// there be) but if we're appending another source map chunk after this one,
// we'll need to know how many characters were in the last line we generated.
FinalGeneratedColumn int
ShouldIgnore bool
}
type ChunkBuilder struct {
inputSourceMap *SourceMap
sourceMap []byte
prevLoc loc.Loc
prevState SourceMapState
lastGeneratedUpdate int
generatedColumn int
hasPrevState bool
lineOffsetTables []LineOffsetTable
// This is a workaround for a bug in the popular "source-map" library:
// https://github.com/mozilla/source-map/issues/261. The library will
// sometimes return null when querying a source map unless every line
// starts with a mapping at column zero.
//
// The workaround is to replicate the previous mapping if a line ends
// up not starting with a mapping. This is done lazily because we want
// to avoid replicating the previous mapping if we don't need to.
lineStartsWithMapping bool
coverLinesWithoutMappings bool
}
func MakeChunkBuilder(inputSourceMap *SourceMap, lineOffsetTables []LineOffsetTable) ChunkBuilder {
return ChunkBuilder{
inputSourceMap: inputSourceMap,
prevLoc: loc.Loc{Start: -1},
lineOffsetTables: lineOffsetTables,
// We automatically repeat the previous source mapping if we ever generate
// a line that doesn't start with a mapping. This helps give files more
// complete mapping coverage without gaps.
//
// However, we probably shouldn't do this if the input file has a nested
// source map that we will be remapping through. We have no idea what state
// that source map is in and it could be pretty scrambled.
//
// I've seen cases where blindly repeating the last mapping for subsequent
// lines gives very strange and unhelpful results with source maps from
// other tools.
coverLinesWithoutMappings: inputSourceMap == nil,
}
}
func (b *ChunkBuilder) GetLineAndColumnForLocation(location loc.Loc) []int {
b.prevLoc = location
// Binary search to find the line
lineOffsetTables := b.lineOffsetTables
count := len(lineOffsetTables)
originalLine := 0
for count > 0 {
step := count / 2
i := originalLine + step
if len(lineOffsetTables) > i && lineOffsetTables[i].byteOffsetToStartOfLine <= location.Start {
originalLine = i + 1
count = count - step - 1
} else {
count = step
}
}
originalLine--
// Use the line to compute the column
line := &lineOffsetTables[originalLine]
originalColumn := int(location.Start - line.byteOffsetToStartOfLine)
if line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) {
newColumn := originalColumn - int(line.byteOffsetToFirstNonASCII)
if len(line.columnsForNonASCII) > newColumn {
originalColumn = int(line.columnsForNonASCII[newColumn])
}
}
// 1-based line, 1-based column
return []int{originalLine + 1, originalColumn + 1}
}
func (b *ChunkBuilder) OffsetAt(location loc.Loc) int {
lineAndColumn := b.GetLineAndColumnForLocation(location)
line := lineAndColumn[0] - 1
column := lineAndColumn[1] - 1
// Collect the length of every line before this one
offset := 0
for i := 0; i < line; i++ {
currentLine := b.lineOffsetTables[i]
offset += currentLine.utf16LineLength
}
// Add the column within this line
return offset + column
}
func (b *ChunkBuilder) AddSourceMapping(location loc.Loc, output []byte) {
if location == b.prevLoc {
return
}
b.prevLoc = location
if location.Start < 0 {
b.appendMapping(SourceMapState{
GeneratedLine: b.prevState.GeneratedLine,
GeneratedColumn: b.generatedColumn,
SourceIndex: 0,
OriginalLine: 0,
OriginalColumn: 0,
})
// This line now has a mapping on it, so don't insert another one
b.lineStartsWithMapping = true
return
}
// Binary search to find the line
lineOffsetTables := b.lineOffsetTables
count := len(lineOffsetTables)
originalLine := 0
for count > 0 {
step := count / 2
i := originalLine + step
if i > -1 && lineOffsetTables[i].byteOffsetToStartOfLine <= location.Start {
originalLine = i + 1
count = count - step - 1
} else {
count = step
}
}
originalLine--
// Use the line to compute the column
line := &lineOffsetTables[originalLine]
originalColumn := int(location.Start - line.byteOffsetToStartOfLine)
if line.columnsForNonASCII != nil && originalColumn >= int(line.byteOffsetToFirstNonASCII) {
if len(line.columnsForNonASCII) > originalColumn-int(line.byteOffsetToFirstNonASCII) {
originalColumn = int(line.columnsForNonASCII[originalColumn-int(line.byteOffsetToFirstNonASCII)])
}
}
b.updateGeneratedLineAndColumn(output)
// If this line doesn't start with a mapping and we're about to add a mapping
// that's not at the start, insert a mapping first so the line starts with one.
if b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.generatedColumn > 0 && b.hasPrevState {
b.appendMappingWithoutRemapping(SourceMapState{
GeneratedLine: b.prevState.GeneratedLine,
GeneratedColumn: 0,
SourceIndex: b.prevState.SourceIndex,
OriginalLine: b.prevState.OriginalLine,
OriginalColumn: b.prevState.OriginalColumn,
})
}
b.appendMapping(SourceMapState{
GeneratedLine: b.prevState.GeneratedLine,
GeneratedColumn: b.generatedColumn,
OriginalLine: originalLine,
OriginalColumn: originalColumn,
})
// This line now has a mapping on it, so don't insert another one
b.lineStartsWithMapping = true
}
func (b *ChunkBuilder) GenerateChunk(output []byte) Chunk {
b.updateGeneratedLineAndColumn(output)
shouldIgnore := true
for _, c := range b.sourceMap {
if c != ';' {
shouldIgnore = false
break
}
}
return Chunk{
Buffer: b.sourceMap,
EndState: b.prevState,
FinalGeneratedColumn: b.generatedColumn,
ShouldIgnore: shouldIgnore,
}
}
// Scan over the printed text since the last source mapping and update the
// generated line and column numbers
func (b *ChunkBuilder) updateGeneratedLineAndColumn(output []byte) {
for i, c := range string(output[b.lastGeneratedUpdate:]) {
switch c {
case '\r', '\n', '\u2028', '\u2029':
// Handle Windows-specific "\r\n" newlines
if c == '\r' {
newlineCheck := b.lastGeneratedUpdate + i + 1
if newlineCheck < len(output) && output[newlineCheck] == '\n' {
continue
}
}
// If we're about to move to the next line and the previous line didn't have
// any mappings, add a mapping at the start of the previous line.
if b.coverLinesWithoutMappings && !b.lineStartsWithMapping && b.hasPrevState {
b.appendMappingWithoutRemapping(SourceMapState{
GeneratedLine: b.prevState.GeneratedLine,
GeneratedColumn: 0,
SourceIndex: b.prevState.SourceIndex,
OriginalLine: b.prevState.OriginalLine,
OriginalColumn: b.prevState.OriginalColumn,
})
}
b.prevState.GeneratedLine++
b.prevState.GeneratedColumn = 0
b.generatedColumn = 0
b.sourceMap = append(b.sourceMap, ';')
// This new line doesn't have a mapping yet
b.lineStartsWithMapping = false
default:
// Mozilla's "source-map" library counts columns using UTF-16 code units
if c <= 0xFFFF {
b.generatedColumn++
} else {
b.generatedColumn += 2
}
}
}
b.lastGeneratedUpdate = len(output)
}
func (b *ChunkBuilder) appendMapping(currentState SourceMapState) {
// If the input file had a source map, map all the way back to the original
if b.inputSourceMap != nil {
mapping := b.inputSourceMap.Find(
int(currentState.OriginalLine),
int(currentState.OriginalColumn))
// Some locations won't have a mapping
if mapping == nil {
return
}
currentState.SourceIndex = int(mapping.SourceIndex)
currentState.OriginalLine = int(mapping.OriginalLine)
currentState.OriginalColumn = int(mapping.OriginalColumn)
}
b.appendMappingWithoutRemapping(currentState)
}
func (b *ChunkBuilder) appendMappingWithoutRemapping(currentState SourceMapState) {
var lastByte byte
if len(b.sourceMap) != 0 {
lastByte = b.sourceMap[len(b.sourceMap)-1]
}
b.sourceMap = appendMappingToBuffer(b.sourceMap, lastByte, b.prevState, currentState)
b.prevState = currentState
b.hasPrevState = true
}
================================================
FILE: internal/t/t.go
================================================
package t
type ParseOptions struct {
Filename string
Position bool
}
================================================
FILE: internal/test_utils/test_utils.go
================================================
package test_utils
import (
"fmt"
"strings"
"testing"
"github.com/gkampitakis/go-snaps/snaps"
"github.com/google/go-cmp/cmp"
"github.com/lithammer/dedent"
)
func RemoveNewlines(input string) string {
return strings.ReplaceAll(input, "\n", "")
}
func Dedent(input string) string {
return dedent.Dedent( // removes any leading whitespace
strings.ReplaceAll( // compress linebreaks to 1 or 2 lines max
strings.TrimLeft(
strings.TrimRight(input, " \n\r"), // remove any trailing whitespace
" \t\r\n"), // remove leading whitespace
"\n\n\n", "\n\n"),
)
}
func ANSIDiff(x, y interface{}, opts ...cmp.Option) string {
escapeCode := func(code int) string {
return fmt.Sprintf("\x1b[%dm", code)
}
diff := cmp.Diff(x, y, opts...)
if diff == "" {
return ""
}
ss := strings.Split(diff, "\n")
for i, s := range ss {
switch {
case strings.HasPrefix(s, "-"):
ss[i] = escapeCode(31) + s + escapeCode(0)
case strings.HasPrefix(s, "+"):
ss[i] = escapeCode(32) + s + escapeCode(0)
}
}
return strings.Join(ss, "\n")
}
// Removes unsupported characters from the test case name, because it will be used as name for the snapshot
func RedactTestName(testCaseName string) string {
snapshotName := strings.ReplaceAll(testCaseName, "#", "_")
snapshotName = strings.ReplaceAll(snapshotName, "<", "_")
snapshotName = strings.ReplaceAll(snapshotName, ">", "_")
snapshotName = strings.ReplaceAll(snapshotName, ")", "_")
snapshotName = strings.ReplaceAll(snapshotName, "(", "_")
snapshotName = strings.ReplaceAll(snapshotName, ":", "_")
snapshotName = strings.ReplaceAll(snapshotName, " ", "_")
snapshotName = strings.ReplaceAll(snapshotName, "#", "_")
snapshotName = strings.ReplaceAll(snapshotName, "'", "_")
snapshotName = strings.ReplaceAll(snapshotName, "\"", "_")
snapshotName = strings.ReplaceAll(snapshotName, "@", "_")
snapshotName = strings.ReplaceAll(snapshotName, "`", "_")
snapshotName = strings.ReplaceAll(snapshotName, "+", "_")
return snapshotName
}
type OutputKind int
const (
JsOutput = iota
JsonOutput
CssOutput
HtmlOutput
JsxOutput
)
var outputKind = map[OutputKind]string{
JsOutput: "js",
JsonOutput: "json",
CssOutput: "css",
HtmlOutput: "html",
JsxOutput: "jsx",
}
type SnapshotOptions struct {
// The testing instances
Testing *testing.T
// The name of the test case
TestCaseName string
// The initial source code that needs to be tested
Input string
// The final output
Output string
// The kind of **markdown block** that the output will be wrapped
Kind OutputKind
// The folder name that the snapshots will be stored
FolderName string
}
// It creates a snapshot for the given test case, the snapshot will include the input and the output of the test case
func MakeSnapshot(options *SnapshotOptions) {
t := options.Testing
testCaseName := options.TestCaseName
input := options.Input
output := options.Output
kind := options.Kind
folderName := "__snapshots__"
if options.FolderName != "" {
folderName = options.FolderName
}
snapshotName := RedactTestName(testCaseName)
s := snaps.WithConfig(
snaps.Filename(snapshotName),
snaps.Dir(folderName),
)
snapshot := "## Input\n\n```\n"
snapshot += Dedent(input)
snapshot += "\n```\n\n## Output\n\n"
snapshot += "```" + outputKind[kind] + "\n"
snapshot += Dedent(output)
snapshot += "\n```"
s.MatchSnapshot(t, snapshot)
}
================================================
FILE: internal/token.go
================================================
// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package astro
import (
"bytes"
"errors"
"fmt"
"io"
"strconv"
"strings"
"unicode"
"github.com/withastro/compiler/internal/handler"
"github.com/withastro/compiler/internal/loc"
"golang.org/x/net/html/atom"
)
// A TokenType is the type of a Token.
type TokenType uint32
const (
// ErrorToken means that an error occurred during tokenization.
ErrorToken TokenType = iota
// TextToken means a text node.
TextToken
// A StartTagToken looks like .
StartTagToken
// An EndTagToken looks like .
EndTagToken
// A SelfClosingTagToken tag looks like .
SelfClosingTagToken
// A CommentToken looks like .
CommentToken
// A DoctypeToken looks like
DoctypeToken
// ASTRO EXTENSIONS
// A FenceToken is the opening or closing --- of Frontmatter
FrontmatterFenceToken
// A StartExpressionToken looks like { and can contain
StartExpressionToken
// An EndExpressionToken looks like }
EndExpressionToken
)
// FrontmatterState tracks the open/closed state of Frontmatter.
type FrontmatterState uint32
const (
FrontmatterInitial FrontmatterState = iota
FrontmatterOpen
FrontmatterClosed
)
// AttributeType is the type of an Attribute
type AttributeType uint32
func (t AttributeType) String() string {
switch t {
case QuotedAttribute:
return "quoted"
case EmptyAttribute:
return "empty"
case ExpressionAttribute:
return "expression"
case SpreadAttribute:
return "spread"
case ShorthandAttribute:
return "shorthand"
case TemplateLiteralAttribute:
return "template-literal"
}
return "Invalid(" + strconv.Itoa(int(t)) + ")"
}
const (
QuotedAttribute AttributeType = iota
EmptyAttribute
ExpressionAttribute
SpreadAttribute
ShorthandAttribute
TemplateLiteralAttribute
)
// ErrBufferExceeded means that the buffering limit was exceeded.
var ErrBufferExceeded = errors.New("max buffer exceeded")
// String returns a string representation of the TokenType.
func (t TokenType) String() string {
switch t {
case ErrorToken:
return "Error"
case TextToken:
return "Text"
case StartTagToken:
return "StartTag"
case EndTagToken:
return "EndTag"
case SelfClosingTagToken:
return "SelfClosingTag"
case CommentToken:
return "Comment"
case DoctypeToken:
return "Doctype"
case FrontmatterFenceToken:
return "FrontmatterFence"
case StartExpressionToken:
return "StartExpression"
case EndExpressionToken:
return "EndExpression"
}
return "Invalid(" + strconv.Itoa(int(t)) + ")"
}
func (fm FrontmatterState) String() string {
switch fm {
case FrontmatterInitial:
return "Initial"
case FrontmatterOpen:
return "Open"
case FrontmatterClosed:
return "Closed"
}
return "Invalid(" + strconv.Itoa(int(fm)) + ")"
}
// An Attribute is an attribute namespace-key-value triple. Namespace is
// non-empty for foreign attributes like xlink, Key is alphabetic (and hence
// does not contain escapable characters like '&', '<' or '>'), and Val is
// unescaped (it looks like "a"
case EndTagToken:
return "" + t.tagString() + ">"
case SelfClosingTagToken:
return "<" + t.tagString() + "/>"
case CommentToken:
return ""
case DoctypeToken:
return ""
case FrontmatterFenceToken:
return "---"
case StartExpressionToken:
return "{"
case EndExpressionToken:
return "}"
}
return "Invalid(" + strconv.Itoa(int(t.Type)) + ")"
}
// A Tokenizer returns a stream of HTML Tokens.
type Tokenizer struct {
// r is the source of the HTML text.
r io.Reader
// tt is the TokenType of the current token.
tt TokenType
prevToken Token
fm FrontmatterState
// err is the first error encountered during tokenization. It is possible
// for tt != Error && err != nil to hold: this means that Next returned a
// valid token but the subsequent Next call will return an error token.
// For example, if the HTML text input was just "plain", then the first
// Next call would set z.err to io.EOF but return a TextToken, and all
// subsequent Next calls would return an ErrorToken.
// err is never reset. Once it becomes non-nil, it stays non-nil.
err error
// buf[raw.Start:raw.End] holds the raw bytes of the current token.
// buf[raw.End:] is buffered input that will yield future tokens.
raw loc.Span
buf []byte
// buf[data.Start:data.End] holds the raw bytes of the current token's data:
// a text token's text, a tag token's tag name, etc.
data loc.Span
// pendingAttr is the attribute key and value currently being tokenized.
// When complete, pendingAttr is pushed onto attr. nAttrReturned is
// incremented on each call to TagAttr.
pendingAttr [2]loc.Span
pendingAttrType AttributeType
attr [][2]loc.Span
attrTypes []AttributeType
attrExpressionStack int
attrTemplateLiteralStack []int
nAttrReturned int
dashCount int
// expressionStack is an array of counters tracking opening and closing
// braces in nested expressions
expressionStack []int
expressionElementStack [][]string
openBraceIsExpressionStart bool
// rawTag is the "script" in "" that closes the next token. If
// non-empty, the subsequent call to Next will return a raw or RCDATA text
// token: one that treats "
" as text instead of an element.
// rawTag's contents are lower-cased.
rawTag string
// noExpressionTag is the "math" in "