├── svelte ├── src │ ├── vite-env.d.ts │ ├── main.ts │ └── lib │ │ ├── count.ts │ │ ├── Button.svelte │ │ ├── dir │ │ └── Button.svelte │ │ ├── SlotText.svelte │ │ ├── Nested.svelte │ │ ├── BoxOne.svelte │ │ ├── ModeBox.svelte │ │ ├── BoxTwo.svelte │ │ ├── BoxThree.svelte │ │ └── TrelloClone.svelte ├── svelte.config.js ├── tsconfig.node.json ├── .gitignore ├── README.md ├── tsconfig.json ├── package.json ├── vite.config.ts ├── vite.config.ssr.ts ├── clean-copy-custom-plugin.ts ├── iife-custom-plugin.ts └── package-lock.json ├── cmd ├── web │ ├── efs.go │ ├── page.templ │ ├── home.templ │ ├── nav.templ │ ├── nested.templ │ ├── htmx_handler.go │ ├── base.templ │ ├── htmx.templ │ ├── trello_clone.templ │ ├── modes.templ │ ├── assets │ │ └── css │ │ │ └── input.css │ ├── no-svelte.templ │ └── trello_handler.go └── api │ └── main.go ├── go.mod ├── tailwind.config.js ├── internal ├── sveltempl │ ├── v8.go │ └── component.templ └── codegen │ └── svelte_types.go ├── .gitignore ├── go.sum ├── .air.toml ├── Makefile └── README.md /svelte/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /cmd/web/efs.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import "embed" 4 | 5 | //go:embed "assets" 6 | var Files embed.FS 7 | -------------------------------------------------------------------------------- /svelte/src/main.ts: -------------------------------------------------------------------------------- 1 | const modules = import.meta.glob("./lib/**/*.svelte"); 2 | Object.keys(modules).forEach((path) => modules[path]()); 3 | -------------------------------------------------------------------------------- /svelte/src/lib/count.ts: -------------------------------------------------------------------------------- 1 | import { writable, type Writable } from "svelte/store"; 2 | 3 | export const count: Writable = writable(42); 4 | -------------------------------------------------------------------------------- /svelte/src/lib/Button.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module sveltempl 2 | 3 | go 1.22.0 4 | 5 | require ( 6 | github.com/a-h/templ v0.2.747 7 | rogchap.com/v8go v0.9.0 8 | ) 9 | 10 | require github.com/google/uuid v1.6.0 // indirect 11 | -------------------------------------------------------------------------------- /svelte/src/lib/dir/Button.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /svelte/src/lib/SlotText.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
6 | {text} 7 | 8 |
9 | -------------------------------------------------------------------------------- /svelte/src/lib/Nested.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' 2 | 3 | export default { 4 | // Consult https://svelte.dev/docs#compile-time-svelte-preprocess 5 | // for more information about preprocessors 6 | preprocess: vitePreprocess(), 7 | } 8 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | "./cmd/web/**/*.html", 5 | "./cmd/web/**/*.templ", 6 | "./svelte/src/**/*.svelte", 7 | ], 8 | theme: { 9 | extend: {}, 10 | }, 11 | plugins: [], 12 | }; 13 | -------------------------------------------------------------------------------- /cmd/web/page.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | templ Page() { 4 | @Base() { 5 |

Page

6 | @Nav() 7 |
8 |
9 | @Svelte("lib/BoxTwo", nil) 10 |
11 |
12 | @Svelte("lib/BoxThree", nil) 13 |
14 |
15 | } 16 | } 17 | -------------------------------------------------------------------------------- /svelte/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", 5 | "skipLibCheck": true, 6 | "module": "ESNext", 7 | "moduleResolution": "bundler", 8 | "strict": true 9 | }, 10 | "include": ["vite.config.ts", "./*.ts"] 11 | } 12 | -------------------------------------------------------------------------------- /internal/sveltempl/v8.go: -------------------------------------------------------------------------------- 1 | package sveltempl 2 | 3 | import ( 4 | "context" 5 | 6 | "rogchap.com/v8go" 7 | ) 8 | 9 | type ContextKey string 10 | var V8ContextKey ContextKey = "v8" 11 | 12 | func GetV8Context(ctx context.Context) *v8go.Isolate { 13 | if iso, ok := ctx.Value(V8ContextKey).(*v8go.Isolate); ok { 14 | return iso 15 | } 16 | return nil 17 | } 18 | -------------------------------------------------------------------------------- /svelte/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | /dist 12 | /dist-ssr 13 | /dist-ssr-go 14 | *.local 15 | 16 | # Editor directories and files 17 | .vscode/* 18 | !.vscode/extensions.json 19 | .idea 20 | .DS_Store 21 | *.suo 22 | *.ntvs* 23 | *.njsproj 24 | *.sln 25 | *.sw? 26 | -------------------------------------------------------------------------------- /cmd/web/home.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | templ Home() { 4 | @Base() { 5 |

Home

6 | @Nav() 7 |
8 |
9 | @Svelte("lib/BoxOne", []byte(homeProps())) 10 |
11 |
12 | @Svelte("lib/BoxTwo", nil) 13 |
14 |
15 | } 16 | } 17 | 18 | func homeProps() []byte { 19 | return []byte(`{"name": "isomorphic props!"}`) 20 | } 21 | -------------------------------------------------------------------------------- /cmd/web/nav.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | templ Nav() { 4 | 13 | } 14 | -------------------------------------------------------------------------------- /svelte/README.md: -------------------------------------------------------------------------------- 1 | # The svelte side of SvelTempl 2 | 3 | > The following commands are for reference only. The Make tasks will call these internally, so you don't need to call them explicitly during dev or build. You'll only need to install dependencies with `npm install`. 4 | 5 | 6 | Dev mode: 7 | ``` 8 | npm run dev 9 | ``` 10 | 11 | Build: 12 | ``` 13 | npm run build 14 | ``` 15 | 16 | Only build for Go SSR: 17 | ``` 18 | npm run build:ssr-go 19 | ``` 20 | -------------------------------------------------------------------------------- /cmd/web/nested.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | templ Nested() { 4 | @Base() { 5 |

Nested Svelte Components

6 | @Nav() 7 |
8 |

Nested within Svelte

9 | @Svelte("lib/Nested", nil) 10 |
11 |

12 | Different components with the same name under different paths 13 |

14 |
15 |
16 | @Svelte("lib/Button", nil) 17 |
18 |
19 | @Svelte("lib/dir/Button", nil) 20 |
21 |
22 | } 23 | } 24 | -------------------------------------------------------------------------------- /svelte/src/lib/BoxOne.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |

13 | Box {name} 14 | 15 | [{server ? "server" : "hydrated"}] 16 | 17 |

18 |

I render global state from a store.

19 |

The global count is {$count}

20 | 21 | 22 | 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Svelte built files 2 | /cmd/web/assets/svelte 3 | 4 | # Tailwind built files 5 | output.css 6 | 7 | # Binaries for programs and plugins 8 | *.exe 9 | *.exe~ 10 | *.dll 11 | *.so 12 | *.dylib 13 | 14 | # Test binary, built with "go test -c" 15 | *.test 16 | 17 | # Output of the go coverage tool, specifically when used with LiteIDE 18 | *.out 19 | 20 | # Dependency directories (remove the comment below to include it) 21 | # vendor/ 22 | 23 | # Go workspace file 24 | go.work 25 | tmp/ 26 | 27 | # IDE specific files 28 | .vscode 29 | .idea 30 | 31 | # .env file 32 | .env 33 | 34 | # Project build 35 | main 36 | *templ.go 37 | -------------------------------------------------------------------------------- /svelte/src/lib/ModeBox.svelte: -------------------------------------------------------------------------------- 1 | 13 | 14 |
21 | {text} 22 |
23 | 24 | 31 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/a-h/templ v0.2.747 h1:D0dQ2lxC3W7Dxl6fxQ/1zZHBQslSkTSvl5FxP/CfdKg= 2 | github.com/a-h/templ v0.2.747/go.mod h1:69ObQIbrcuwPCU32ohNaWce3Cb7qM5GMiqN1K+2yop4= 3 | github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= 4 | github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= 5 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 6 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 7 | rogchap.com/v8go v0.9.0 h1:wYbUCO4h6fjTamziHrzyrPnpFNuzPpjZY+nfmZjNaew= 8 | rogchap.com/v8go v0.9.0/go.mod h1:MxgP3pL2MW4dpme/72QRs8sgNMmM0pRc8DPhcuLWPAs= 9 | -------------------------------------------------------------------------------- /svelte/src/lib/BoxTwo.svelte: -------------------------------------------------------------------------------- 1 | 11 | 12 |

13 | Box Two 14 | 15 | [{server ? "server" : "hydrated"}] 16 | 17 |

18 | 19 |

I render local state as well as global state from a store

20 | 21 |

The count is {count}

22 | 23 | 24 | 25 |
26 |

Global count:

27 | 28 |
{$globalCount}
29 |
30 | -------------------------------------------------------------------------------- /cmd/web/htmx_handler.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "math/rand" 5 | "net/http" 6 | 7 | "github.com/a-h/templ" 8 | ) 9 | 10 | func HTMXHandler(w http.ResponseWriter, r *http.Request) { 11 | if r.Method == "POST" { 12 | templ.Handler(getRandomComponent()).ServeHTTP(w, r) 13 | } else { 14 | templ.Handler(HTMX()).ServeHTTP(w, r) 15 | } 16 | } 17 | 18 | func getRandomComponent() templ.Component { 19 | components := []templ.Component{ 20 | Svelte("lib/BoxOne", nil), 21 | Svelte("lib/BoxTwo", nil), 22 | Svelte("lib/BoxThree", nil), 23 | Svelte("lib/ModeBox", []byte(`{"text": "I got picked randomly!"}`)), 24 | } 25 | 26 | return components[rand.Intn(len(components))] 27 | } 28 | -------------------------------------------------------------------------------- /svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/svelte/tsconfig.json", 3 | "compilerOptions": { 4 | "target": "ESNext", 5 | "useDefineForClassFields": true, 6 | "module": "ESNext", 7 | "resolveJsonModule": true, 8 | /** 9 | * Typecheck JS in `.svelte` and `.js` files by default. 10 | * Disable checkJs if you'd like to use dynamic types in JS. 11 | * Note that setting allowJs false does not prevent the use 12 | * of JS in `.svelte` files. 13 | */ 14 | "allowJs": true, 15 | "checkJs": true, 16 | "isolatedModules": true, 17 | "moduleDetection": "force", 18 | "strict": true 19 | }, 20 | "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], 21 | "references": [{ "path": "./tsconfig.node.json" }] 22 | } 23 | -------------------------------------------------------------------------------- /cmd/web/base.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import "sveltempl/internal/sveltempl" 4 | 5 | type Options = sveltempl.Options 6 | 7 | templ Svelte(componentName string, componentProps []byte, opts ...Options) { 8 | @sveltempl.Component(componentName, componentProps, opts...) 9 | } 10 | 11 | templ Base() { 12 | 13 | 14 | 15 | 16 | SvelTemple - POC 17 | 18 | 19 | 20 | 21 |
22 | { children... } 23 |
24 | 25 | 26 | } 27 | -------------------------------------------------------------------------------- /cmd/api/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "sveltempl/cmd/web" 7 | 8 | "github.com/a-h/templ" 9 | ) 10 | 11 | func main() { 12 | http.Handle("/", templ.Handler(web.Home())) 13 | http.Handle("/page", templ.Handler(web.Page())) 14 | http.Handle("/no-svelte", templ.Handler(web.NoSvelte())) 15 | http.Handle("/trello-clone", templ.Handler(web.TrelloClone())) 16 | http.HandleFunc("/htmx", web.HTMXHandler) 17 | http.Handle("/modes", templ.Handler(web.Modes())) 18 | http.Handle("/nested", templ.Handler(web.Nested())) 19 | http.HandleFunc("/api/updateBoard", web.TrelloHandler) 20 | 21 | fileServer := http.FileServer(http.FS(web.Files)) 22 | http.Handle("/assets/", fileServer) 23 | 24 | fmt.Println("Listening on :8080") 25 | http.ListenAndServe(":8080", nil) 26 | } 27 | -------------------------------------------------------------------------------- /svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "go-svelte-islands", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build:client": "vite build --config vite.config.ts", 9 | "build:ssr": "vite build --config vite.config.ssr.ts", 10 | "build": "npm run build:client && npm run build:ssr", 11 | "preview": "vite preview", 12 | "check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json" 13 | }, 14 | "devDependencies": { 15 | "@sveltejs/vite-plugin-svelte": "^3.1.1", 16 | "@tsconfig/svelte": "^5.0.4", 17 | "@types/node": "^20.14.11", 18 | "svelte": "^4.2.18", 19 | "svelte-check": "^3.8.4", 20 | "tslib": "^2.6.3", 21 | "typescript": "^5.2.2", 22 | "vite": "^5.3.4" 23 | }, 24 | "dependencies": { 25 | "svelte-dnd-action": "^0.9.49" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /svelte/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { svelte } from "@sveltejs/vite-plugin-svelte"; 2 | import { resolve } from "path"; 3 | import { defineConfig } from "vite"; 4 | import cleanCopy from "./clean-copy-custom-plugin"; 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | svelte({ 9 | emitCss: false, 10 | }), 11 | cleanCopy("../cmd/web/assets/svelte"), 12 | ], 13 | build: { 14 | rollupOptions: { 15 | input: "./src/main.ts", 16 | output: { 17 | dir: "dist", 18 | format: "es", 19 | chunkFileNames: ({ facadeModuleId }) => { 20 | if (facadeModuleId) { 21 | const name = facadeModuleId 22 | .replace(resolve(__dirname, "src") + "/", "") 23 | .replace(".svelte", ""); 24 | return `${name}-[hash].js`; 25 | } else { 26 | return `[name]-[hash].js`; 27 | } 28 | }, 29 | }, 30 | }, 31 | }, 32 | }); 33 | -------------------------------------------------------------------------------- /.air.toml: -------------------------------------------------------------------------------- 1 | root = "." 2 | testdata_dir = "testdata" 3 | tmp_dir = "tmp" 4 | 5 | [build] 6 | args_bin = [] 7 | bin = "./main" 8 | cmd = "make build" 9 | delay = 1000 10 | exclude_dir = ["assets", "tmp", "vendor", "testdata", "svelte/node_modules"] 11 | exclude_file = [] 12 | exclude_regex = ["_test.go", ".*_templ.go"] 13 | exclude_unchanged = false 14 | follow_symlink = false 15 | full_bin = "" 16 | include_dir = [] 17 | include_ext = ["go", "tpl", "tmpl", "html", "templ"] 18 | include_file = [] 19 | kill_delay = "0s" 20 | log = "build-errors.log" 21 | poll = false 22 | poll_interval = 0 23 | post_cmd = [] 24 | pre_cmd = [] 25 | rerun = false 26 | rerun_delay = 500 27 | send_interrupt = false 28 | stop_on_error = false 29 | 30 | [color] 31 | app = "" 32 | build = "yellow" 33 | main = "magenta" 34 | runner = "green" 35 | watcher = "cyan" 36 | 37 | [log] 38 | main_only = false 39 | time = false 40 | 41 | [misc] 42 | clean_on_exit = false 43 | 44 | [screen] 45 | clear_on_rebuild = false 46 | keep_scroll = true 47 | -------------------------------------------------------------------------------- /cmd/web/htmx.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | templ HTMX() { 4 | @Base() { 5 |

HTMX Example

6 | @Nav() 7 |
8 |

Sveltempl works OOTB with HTMX, because each server-rendered component instance includes its own inline es module which imports the code-split compiled client component script -- We don't need to monitor changes or run event-driven code to hydrate any new components that come in asynchronously, hydration just works, automatically.

9 |

10 | * Technically though, we've already demonstrated this because the entire site navigation is clientside using HTMX hx-boost attribute. 11 |

12 |
13 |
14 | @button("Click to fetch a random component (SSR'd and hydrated)") 15 |
16 |
17 | } 18 | } 19 | 20 | templ button(text string) { 21 | 22 | } 23 | -------------------------------------------------------------------------------- /cmd/web/trello_clone.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import "encoding/json" 4 | 5 | func props() []byte { 6 | props := map[string]interface{}{ 7 | "board": GlobalBoard, 8 | } 9 | 10 | boardJSON, _ := json.Marshal(props) 11 | 12 | return boardJSON 13 | } 14 | 15 | templ TrelloClone() { 16 | @Base() { 17 |

sveltempl

18 | @Nav() 19 |
20 |

Try dragging items or whole columns. Svelte makes achieving this type of UI easy.

21 |

22 | Sveltempl, on the other hand, makes server rendering and sharing state between client and server easy. Your front-end Svelte code will be identical to what it would be in an SPA or traditional "Islands" setup, just without the pesky network/api code! 23 |

24 |

25 | Go ahead, Giv'er a refresh! How about a private tab or another browser? 26 |

27 |
28 | @Svelte("lib/TrelloClone", props()) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /svelte/src/lib/BoxThree.svelte: -------------------------------------------------------------------------------- 1 | 25 | 26 |

27 | Box Three 28 | 29 | [{server ? "server" : "hydrated"}] 30 | 31 |

32 |

The following is dynamic content

33 | 34 | {#if !mounted} 35 |

Component Not Mounted

36 | {:else} 37 |

Component Mounted

38 | {/if} 39 | 40 | {#await getTlock()} 41 |

fetching...

42 | {:then tlock} 43 |
44 |
45 |       {JSON.stringify(tlock, null, 2)}
46 |     
47 |
48 | {/await} 49 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Simple Makefile for a Go project 2 | 3 | # Build the application 4 | all: build 5 | 6 | build: 7 | @echo "Building..." 8 | @templ generate 9 | @cd svelte && npm run build && cd ../ 10 | @npx tailwindcss -i cmd/web/assets/css/input.css -o cmd/web/assets/css/output.css 11 | @go build -o main cmd/api/main.go 12 | 13 | # Run the application 14 | run: 15 | @go run cmd/api/main.go 16 | 17 | 18 | 19 | # Test the application 20 | test: 21 | @echo "Testing..." 22 | @go test ./tests -v 23 | 24 | 25 | 26 | # Clean the binary 27 | clean: 28 | @echo "Cleaning..." 29 | @rm -f main 30 | 31 | # Live Reload 32 | watch: 33 | @if command -v air > /dev/null; then \ 34 | (trap 'kill 0' EXIT; \ 35 | (cd svelte && npm run dev) & \ 36 | SVELTEMPL_HMR=1 air); \ 37 | echo "Watching...";\ 38 | else \ 39 | read -p "Go's 'air' is not installed on your machine. Do you want to install it? [Y/n] " choice; \ 40 | if [ "$$choice" != "n" ] && [ "$$choice" != "N" ]; then \ 41 | go install github.com/air-verse/air@latest; \ 42 | (trap 'kill 0' EXIT; \ 43 | (cd svelte && npm run dev) & \ 44 | SVELTEMPL_HMR=1 air); \ 45 | echo "Watching...";\ 46 | else \ 47 | echo "You chose not to install air. Exiting..."; \ 48 | exit 1; \ 49 | fi; \ 50 | fi 51 | 52 | .PHONY: all build run test clean watch 53 | -------------------------------------------------------------------------------- /cmd/web/modes.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | templ Modes() { 4 | @Base() { 5 |

Rendering Modes

6 | @Nav() 7 |
8 |
9 |

By default, Svelte components are rendered on the server and hydrated on the client.

10 |

To render only on the client (perhaps becuase you are using a 3rd party library that uses browser globals in its initialization script, and therefor cannot be SSR'd) you can just pass in mode: "csr".

11 |

To server-render something without hyrdration, just don't call a Svelte component from your Go Templ component

12 |

13 | *Tip: Try loading this page with Javascript disabled and compare the rendered output. 14 |

15 |
16 |
17 |
18 | // shamelessly copy the svelte class in here (you wouldn't do this in prod) 19 |
20 | SSR Only 21 |
22 |
23 |
24 | @Svelte("lib/ModeBox", []byte(`{"text": "SSR + Hydration"}`)) 25 |
26 |
27 | @Svelte("lib/ModeBox", []byte(`{"text": "CSR Only"}`), Options{"mode": "csr"}) 28 |
29 |
30 |
31 | } 32 | } 33 | -------------------------------------------------------------------------------- /svelte/vite.config.ssr.ts: -------------------------------------------------------------------------------- 1 | import { svelte } from "@sveltejs/vite-plugin-svelte"; 2 | import { readdirSync, statSync } from "fs"; 3 | import { join, resolve } from "path"; 4 | import { defineConfig } from "vite"; 5 | import iifeBundle from "./iife-custom-plugin"; 6 | 7 | function getAllSvelteComponents(dir: string, fileList: string[] = []) { 8 | const files = readdirSync(dir); 9 | files.forEach((file) => { 10 | const filePath = join(dir, file); 11 | if (statSync(filePath).isDirectory()) { 12 | getAllSvelteComponents(filePath, fileList); 13 | } else if (filePath.endsWith(".svelte")) { 14 | fileList.push(filePath); 15 | } 16 | }); 17 | return fileList; 18 | } 19 | 20 | // Find all Svelte components in the src directory 21 | const srcDir = resolve(__dirname, "src"); 22 | const componentFiles = getAllSvelteComponents(srcDir); 23 | 24 | const input = componentFiles.reduce((acc, file) => { 25 | const name = file.replace(srcDir, "").replace(".svelte", "").replace("/", ""); 26 | acc[name] = resolve(__dirname, file); 27 | return acc; 28 | }, {} as Record); 29 | 30 | export default defineConfig({ 31 | plugins: [ 32 | svelte(), 33 | iifeBundle({ 34 | outputDir: "dist-ssr-go", 35 | inputDir: "dist-ssr", 36 | }), 37 | ], 38 | build: { 39 | ssr: true, 40 | rollupOptions: { 41 | input, 42 | output: { 43 | dir: "dist-ssr", 44 | }, 45 | }, 46 | }, 47 | }); 48 | -------------------------------------------------------------------------------- /svelte/clean-copy-custom-plugin.ts: -------------------------------------------------------------------------------- 1 | import fs, { statSync } from "fs"; 2 | import path, { join } from "path"; 3 | 4 | // Custom plugin to clean and copy files 5 | export default function cleanCopy(relativePath: string) { 6 | // Directory to be cleaned and copied to 7 | const targetDir = path.resolve(__dirname, relativePath); 8 | return { 9 | name: "clean-and-copy-plugin", 10 | writeBundle() { 11 | // Clean the target directory 12 | fs.rmSync(targetDir, { recursive: true, force: true }); 13 | console.log(`Emptied ${targetDir}`); 14 | 15 | // Ensure the target directory exists 16 | fs.mkdirSync(targetDir, { recursive: true }); 17 | 18 | // Copy files 19 | const srcDir = path.resolve(__dirname, "./dist"); 20 | const fileList = getFilePathsRecursive(srcDir); 21 | 22 | fileList.forEach((file) => { 23 | const destFile = file.replace(srcDir, targetDir); 24 | const destDir = path.dirname(destFile); 25 | 26 | // Ensure the destination directory exists 27 | fs.mkdirSync(destDir, { recursive: true }); 28 | 29 | fs.copyFileSync(file, destFile); 30 | console.log(`Copied ${file} to ${destFile}`); 31 | }); 32 | }, 33 | }; 34 | } 35 | 36 | function getFilePathsRecursive(inputDir: string): string[] { 37 | return fs.readdirSync(inputDir).flatMap((file) => { 38 | const filePath = join(inputDir, file); 39 | if (statSync(filePath).isDirectory()) { 40 | return getFilePathsRecursive(filePath); 41 | } else { 42 | return filePath; 43 | } 44 | }); 45 | } 46 | -------------------------------------------------------------------------------- /internal/codegen/svelte_types.go: -------------------------------------------------------------------------------- 1 | package codegen 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | ) 10 | 11 | // TODO make type-safe in a way that provides IDE completions 12 | type components map[string]string 13 | 14 | var ComponentMap = populateComponentMap("cmd/web/assets/svelte/") 15 | 16 | // populateComponentMap recursively traverses the given directory and populates the component map 17 | func populateComponentMap(dir string) components { 18 | compMap := make(components) 19 | err := traverseDirectory(dir, compMap) 20 | if err != nil { 21 | log.Fatalf("Failed to populate component map: %v", err) 22 | } 23 | return compMap 24 | } 25 | 26 | func traverseDirectory(dir string, compMap components) error { 27 | files, err := os.ReadDir(dir) 28 | if err != nil { 29 | return fmt.Errorf("failed to read directory %s: %v", dir, err) 30 | } 31 | 32 | for _, file := range files { 33 | filePath := filepath.Join(dir, file.Name()) 34 | 35 | if file.IsDir() { 36 | // Recursively traverse subdirectories 37 | if err := traverseDirectory(filePath, compMap); err != nil { 38 | return err 39 | } 40 | } else { 41 | filename := file.Name() 42 | parts := strings.SplitN(filename, "-", 2) 43 | if len(parts) == 2 { 44 | key := parts[0] 45 | value := filePath 46 | 47 | // Extract the relative path 48 | relPath, _ := filepath.Rel("cmd/web/assets/svelte", dir) 49 | if relPath != "." { 50 | key = filepath.Join(relPath, key) 51 | } 52 | 53 | compMap[key] = strings.TrimPrefix(value, "cmd/web") 54 | } else { 55 | fmt.Printf("Skipping file with unexpected name format: %s\n", filename) 56 | } 57 | } 58 | } 59 | 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /cmd/web/assets/css/input.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .boxes { 6 | display: flex; 7 | gap: 20px; 8 | margin-top: 20px; 9 | } 10 | .box { 11 | border: 1px solid #6b6b6b; 12 | padding: 20px; 13 | } 14 | .boxes .box { 15 | flex-basis: 50%; 16 | } 17 | .server { 18 | background-color: steelblue; 19 | color: white; 20 | font-weight: 700; 21 | } 22 | .hydrated { 23 | background-color: orchid; 24 | color: white; 25 | font-weight: 700; 26 | } 27 | 28 | :root { 29 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 30 | line-height: 1.5; 31 | font-weight: 400; 32 | 33 | color-scheme: light dark; 34 | color: rgba(255, 255, 255, 0.87); 35 | background-color: #242424; 36 | 37 | font-synthesis: none; 38 | text-rendering: optimizeLegibility; 39 | -webkit-font-smoothing: antialiased; 40 | -moz-osx-font-smoothing: grayscale; 41 | } 42 | 43 | a { 44 | font-weight: 500; 45 | color: #646cff; 46 | text-decoration: inherit; 47 | } 48 | a:hover { 49 | color: #535bf2; 50 | } 51 | 52 | body { 53 | margin: 0; 54 | display: flex; 55 | min-width: 320px; 56 | min-height: 100vh; 57 | } 58 | 59 | h1 { 60 | font-size: 3.2em; 61 | line-height: 1.1; 62 | } 63 | 64 | .card { 65 | padding: 2em; 66 | } 67 | 68 | #app { 69 | max-width: 1280px; 70 | margin: 0 auto; 71 | padding: 2rem; 72 | text-align: center; 73 | } 74 | 75 | button { 76 | border-radius: 8px; 77 | border: 1px solid transparent; 78 | padding: 0.6em 1.2em; 79 | font-size: 1em; 80 | font-weight: 500; 81 | font-family: inherit; 82 | background-color: #1a1a1a; 83 | cursor: pointer; 84 | transition: border-color 0.25s; 85 | } 86 | button:hover { 87 | border-color: #646cff; 88 | } 89 | button:focus, 90 | button:focus-visible { 91 | outline: 4px auto -webkit-focus-ring-color; 92 | } 93 | -------------------------------------------------------------------------------- /cmd/web/no-svelte.templ: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | templ NoSvelte() { 4 | @Base() { 5 |

No Svelte

6 | @Nav() 7 |
8 |
9 |

just server stuff

10 |

Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis necessitatibus dolor provident placeat veniam aperiam sunt, consectetur nostrum corrupti tempore aliquid aut maiores velit officia deserunt facilis vel praesentium sint ducimus exercitationem perspiciatis illum soluta earum. Facere consequuntur officiis ducimus molestiae reiciendis. Nulla voluptas tempore atque quod, maiores quisquam assumenda adipisci commodi impedit cum officia saepe fuga! Aperiam aliquid enim commodi ex eligendi impedit pariatur inventore, ullam sapiente consequuntur cumque! Suscipit ipsam doloribus quod. Quos sint ipsam dolorum aperiam eligendi placeat rerum voluptatem culpa repellendus? Non, quia ipsam aperiam laborum, nulla, ad perferendis illo quaerat quas mollitia obcaecati sint eos!

11 |
12 |
13 |

just server stuff

14 |

Lorem ipsum dolor sit amet consectetur adipisicing elit. Omnis necessitatibus dolor provident placeat veniam aperiam sunt, consectetur nostrum corrupti tempore aliquid aut maiores velit officia deserunt facilis vel praesentium sint ducimus exercitationem perspiciatis illum soluta earum. Facere consequuntur officiis ducimus molestiae reiciendis. Nulla voluptas tempore atque quod, maiores quisquam assumenda adipisci commodi impedit cum officia saepe fuga! Aperiam aliquid enim commodi ex eligendi impedit pariatur inventore, ullam sapiente consequuntur cumque! Suscipit ipsam doloribus quod. Quos sint ipsam dolorum aperiam eligendi placeat rerum voluptatem culpa repellendus? Non, quia ipsam aperiam laborum, nulla, ad perferendis illo quaerat quas mollitia obcaecati sint eos!

15 |
16 |
17 | } 18 | } 19 | -------------------------------------------------------------------------------- /svelte/iife-custom-plugin.ts: -------------------------------------------------------------------------------- 1 | import { readdirSync, statSync } from "fs"; 2 | import fs from "fs/promises"; 3 | import path, { join } from "path"; 4 | import { rollup } from "rollup"; 5 | import { Plugin } from "vite"; 6 | 7 | type Options = { 8 | outputDir?: string; 9 | inputDir?: string; 10 | }; 11 | 12 | export default function iifeBundle(options: Options = {}): Plugin { 13 | const { outputDir = "dist-ssr-go", inputDir = "dist-ssr" } = options; 14 | 15 | return { 16 | name: "sveltempl-iife-bundle", 17 | apply: "build", 18 | async writeBundle() { 19 | // Clear the output directory 20 | await fs.rm(outputDir, { recursive: true, force: true }); 21 | await fs.mkdir(outputDir, { recursive: true }); 22 | 23 | const fileList = getFilePathsRecursive(inputDir).filter((file) => 24 | file.endsWith(".js") 25 | ); 26 | 27 | for (const file of fileList) { 28 | if (file.includes("/assets/")) continue; 29 | 30 | const name = path.basename(file, ".js"); 31 | 32 | const bundle = await rollup({ 33 | input: file, 34 | onwarn: (warning, warn) => { 35 | if (warning.code === "CIRCULAR_DEPENDENCY") return; 36 | warn(warning); 37 | }, 38 | }); 39 | 40 | await bundle.write({ 41 | file: file.replace(inputDir, outputDir), 42 | format: "iife", 43 | name, 44 | sourcemap: false, 45 | }); 46 | 47 | await bundle.close(); 48 | } 49 | 50 | console.log(`IIFE bundles generated in ${outputDir}`); 51 | }, 52 | }; 53 | } 54 | 55 | function getFilePathsRecursive(inputDir: string): string[] { 56 | return readdirSync(inputDir).flatMap((file) => { 57 | const filePath = join(inputDir, file); 58 | if (statSync(filePath).isDirectory()) { 59 | return getFilePathsRecursive(filePath); 60 | } else { 61 | return filePath; 62 | } 63 | }); 64 | } 65 | -------------------------------------------------------------------------------- /cmd/web/trello_handler.go: -------------------------------------------------------------------------------- 1 | package web 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "net/http" 7 | ) 8 | 9 | func TrelloHandler(w http.ResponseWriter, r *http.Request) { 10 | // Read the body 11 | body, err := io.ReadAll(r.Body) 12 | if err != nil { 13 | http.Error(w, "Error reading request body", http.StatusBadRequest) 14 | return 15 | } 16 | defer r.Body.Close() 17 | 18 | // Unmarshal the JSON into a Board struct 19 | var newBoard Board 20 | err = json.Unmarshal(body, &newBoard) 21 | if err != nil { 22 | http.Error(w, "Error unmarshaling JSON", http.StatusBadRequest) 23 | return 24 | } 25 | 26 | // Mutate the global board with the new board 27 | updateBoard(newBoard, &GlobalBoard) 28 | 29 | w.Header().Set("Content-Type", "application/json") 30 | json.NewEncoder(w).Encode(map[string]string{"status": "success", "message": "Board updated successfully"}) 31 | } 32 | 33 | type Board []Col 34 | 35 | type Col struct { 36 | ID int `json:"id"` 37 | Name string `json:"name"` 38 | Items []Item `json:"items"` 39 | } 40 | 41 | type Item struct { 42 | ID int `json:"id"` 43 | Name string `json:"name"` 44 | Color string `json:"color"` 45 | } 46 | 47 | var colors = []string{"#75ADC7", "#85C49B", "#E0B386", "#D48D98", "#FFF099"} 48 | 49 | var GlobalBoard = Board{ 50 | { 51 | ID: 1, 52 | Name: "TODO", 53 | Items: []Item{ 54 | {ID: 41, Name: "item41", Color: colors[0]}, 55 | {ID: 42, Name: "item42", Color: colors[1]}, 56 | {ID: 43, Name: "item43", Color: colors[2]}, 57 | {ID: 44, Name: "item44", Color: colors[3]}, 58 | {ID: 45, Name: "item45", Color: colors[4]}, 59 | {ID: 46, Name: "item46", Color: colors[0]}, 60 | {ID: 47, Name: "item47", Color: colors[1]}, 61 | {ID: 48, Name: "item48", Color: colors[2]}, 62 | {ID: 49, Name: "item49", Color: colors[3]}, 63 | }, 64 | }, 65 | { 66 | ID: 2, 67 | Name: "DOING", 68 | Items: []Item{}, 69 | }, 70 | { 71 | ID: 3, 72 | Name: "DONE", 73 | Items: []Item{}, 74 | }, 75 | } 76 | 77 | func updateBoard(nb Board, ob *Board) { 78 | *ob = nb 79 | } 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introducing *sveltempl* - SSR + Hydration for Svelte components in Go / Templ 2 | 3 | >❗This project is in a pre-alpha state under active development, but feel free to take it for a spin and let me know what you think! 4 | 5 | The goal of this project is to provide a seamless integration of Go and Svelte for the best of both worlds, with a focus on both developer and end user experience. The design of **sveltempl** is inspired by "Islands of Interactivity" but goes further by server-rendering those islands in a V8 runtime embedded in the Golang web server. If that sounds slow and resource intensive, rest assured it is not! (Numbers and architectural details to be provided with v1 release). When the web server starts, it fires up a long-running v8 isolate as a singleton, while each call to javascript to server-render a svelte component gets its own instantly-available context in the isolate. 6 | 7 | To work effectively with **sveltempl**, start by building out your routing and logic in Go and your pages/views in Templ (with HTMX _strongly encouraged_). When you need rich clientside interactivity or need to manage complex client state, reaching for a Svelte component tree is as simple as calling `@Svelte("MyComponent", myProps)` in your template. **sveltempl** will code-split and seamlessly inject your Svelte component(s) on both sides of the network bridge, so that the resulting page or htmx partial remains as lean and SEO-friendly as possible. Only the exact fancy clientside code you need _right now_, and no more, will be dynamically fetched and injected without any layout shift or FOUT. 8 | 9 | All the Svelte APIs you know and love are available: global stores, reactive delarations, scoped styles, motion primitives, etc... You can have your cake and eat it too 🍰 _(just pay for it with a few ms)_. 10 | 11 | >Demo the examples in this repo online at [sveltempl.tlock.dev](https://sveltempl.tlock.dev) 12 | > 13 | >_**Note:** My server, like me, is located in Japan 🎌, so keep that in mind._ 14 | 15 | 16 | **Note**: In the future, this repo will house the **sveltempl** Go library package and an accompanying Vite plugin, while an example application will be provided in a sister repo. For now, this repo combines all three and acts more as a starter template, but if you want to star or follow the project, this is the repo to do that. Semver library releases will be provided here. 17 | 18 | ## Getting Started 19 | 20 | These instructions will get you a demo application up and running for development and testing purposes. 21 | 22 | ### System Package Requirements 23 | 24 | - Lastest version of Go 25 | - Templ 26 | - Node.js (used only at build-time for Svelte) 27 | 28 | ### Svelte 29 | 30 | From the `/svelte` directory: 31 | 32 | - Install dependencies `npm install` 33 | - That's it. Dev/build commands are handled by our `make` commands in the next section. 34 | 35 | ### Go 36 | 37 | From the project root: 38 | 39 | - Install dependencies `go get` 40 | - Start a live-reloading process to recompile your build on changes `make watch`. 41 | - This will also fire up your svelte components with Hot Module Reloading. If you're only changing a svelte file, you'll instantly see that change in the browser with no recompile/reload step. 42 | - Compile a prod-ready build with `make build` and run it with `make run`. 43 | 44 | ### Niceties 45 | 46 | To really grok working with this stack, you'll want to make sure your IDE is configured with the appropriate tooling / extensions for Go, Templ, Svelte, and Tailwind. Without them, ymmv. 47 | 48 | --- 49 | 50 | **Bonus:** 51 | If you use **sveltempl** with Echo, HTMX and Tailwind, and deploy with Docker and Nginx, you can enjoy claiming you run the `GETSHTDN` stack! 52 | 53 | ``` 54 | G E T S H T D N 55 | o c e v t a o g 56 | h m e m i c i 57 | o p l x l k n 58 | l t w e x 59 | e i r 60 | n 61 | d 62 | ``` 63 | -------------------------------------------------------------------------------- /svelte/src/lib/TrelloClone.svelte: -------------------------------------------------------------------------------- 1 | 64 | 65 | 66 | 67 |
73 | {#each board as column (column.id)} 74 |
75 |
{column.name}
76 |
handleDndConsiderCards(column.id, e)} 80 | on:finalize={(e) => handleDndFinalizeCards(column.id, e)} 81 | > 82 | {#each column.items as item (item.id)} 83 |
88 | {item.name} 89 |
90 | {/each} 91 |
92 |
93 | {/each} 94 |
95 | 96 | 135 | -------------------------------------------------------------------------------- /internal/sveltempl/component.templ: -------------------------------------------------------------------------------- 1 | package sveltempl 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "github.com/google/uuid" 8 | "io" 9 | "log" 10 | "os" 11 | "path" 12 | "path/filepath" 13 | "rogchap.com/v8go" 14 | "sveltempl/internal/codegen" 15 | ) 16 | 17 | type Options map[string]any 18 | 19 | // Mutable var for storing the current id 20 | // (gets updated on each top-level component wrapper, then passed in to internals) 21 | var idGlobal string 22 | 23 | func setAndReturnUniqId() string { 24 | idGlobal = uuid.NewString() 25 | return idGlobal 26 | } 27 | 28 | templ Component(componentName string, componentProps []byte, opts ...Options) { 29 |
30 | @svelTemplComponent(GetV8Context(ctx), componentName, idGlobal, componentProps, opts...) 31 |
32 | } 33 | 34 | func svelTemplComponent(iso *v8go.Isolate, componentName string, internalId string, componentProps []byte, opts ...Options) templ.Component { 35 | var htmlOutput string 36 | var err error 37 | 38 | mode := "ssr" 39 | for _, o := range opts { 40 | if m, exists := o["mode"]; exists { 41 | if modeStr, ok := m.(string); ok { 42 | mode = modeStr 43 | } 44 | } 45 | } 46 | 47 | if mode == "ssr" { 48 | htmlOutput, err = svelTemplRenderToString(componentName, iso, componentProps) 49 | } else { 50 | htmlOutput = "" 51 | } 52 | 53 | if err != nil { 54 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error { 55 | _, err := io.WriteString(w, "

"+err.Error()+"

") 56 | return err 57 | }) 58 | } 59 | 60 | propScript := "" 61 | if componentProps != nil { 62 | propScript = `\n" 63 | } 64 | 65 | return templ.ComponentFunc(func(ctx context.Context, w io.Writer) error { 66 | _, err := io.WriteString(w, propScript+htmlOutput+hydrationScript(componentName, internalId, mode)) 67 | return err 68 | }) 69 | } 70 | 71 | // TODO most of this can be re-used, the only dynamic part is getting the Component class and target element 72 | func hydrationScript(componentName string, internalId string, mode string) string { 73 | csrPath := codegen.ComponentMap[componentName] 74 | 75 | if os.Getenv("SVELTEMPL_HMR") != "" { 76 | csrPath = "http://localhost:5173/src/" + componentName + ".svelte" 77 | } 78 | 79 | return fmt.Sprintf(` 80 | 100 | `, csrPath, componentName, internalId, mode) 101 | } 102 | 103 | // ? componentQualName includes leading path info relative to svelte/src 104 | func svelTemplRenderToString(componentQualName string, iso *v8go.Isolate, componentProps []byte) (string, error) { 105 | // Create a new Javascript context 106 | ctx := v8go.NewContext(iso) 107 | 108 | if componentQualName == "" { 109 | return "", fmt.Errorf("you must pass in a component name to render") 110 | } 111 | 112 | componentName := path.Base(componentQualName) 113 | 114 | // Construct the file path using fmt.Sprintf for string interpolation 115 | cwd, err := os.Getwd() 116 | if err != nil { 117 | log.Fatalf("Failed to get current working directory: %v", err) 118 | } 119 | componentPath := filepath.Join(cwd, "svelte/dist-ssr-go", fmt.Sprintf("%s.js", componentQualName)) 120 | 121 | // Read the JavaScript file from disk 122 | componentScript, err := os.ReadFile(componentPath) 123 | if err != nil { 124 | return "", fmt.Errorf("could not read JavaScript file %s", componentPath) 125 | } 126 | 127 | // Run the JS file which will load it into context 128 | _, err = ctx.RunScript(string(componentScript), componentPath) 129 | if err != nil { 130 | return "", fmt.Errorf("error executing JavaScript file %s", componentPath) 131 | } 132 | 133 | // Handle props 134 | var propsJson string 135 | switch { 136 | case componentProps == nil: 137 | propsJson = "{}" 138 | case !json.Valid(componentProps): 139 | return "", fmt.Errorf("props must be valid json") 140 | default: 141 | propsJson = string(componentProps) 142 | } 143 | 144 | _, err = ctx.RunScript(fmt.Sprintf(`const props = {server: true, ...JSON.parse('%s')};`, propsJson), "props.js") 145 | if err != nil { 146 | return "", fmt.Errorf("error parsing props") 147 | } 148 | 149 | // Run the component render method 150 | componentOutput, err := ctx.RunScript(fmt.Sprintf(` 151 | const { html, css: { code: css } } = %s.render(props); 152 | (html + "") 153 | `, componentName), "output.js") // return a value in JavaScript back to Go 154 | if err != nil { 155 | return "", fmt.Errorf("error executing JavaScript function") 156 | } 157 | 158 | return componentOutput.String(), nil 159 | } 160 | -------------------------------------------------------------------------------- /svelte/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "go-svelte-islands", 3 | "version": "0.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "go-svelte-islands", 9 | "version": "0.0.0", 10 | "dependencies": { 11 | "svelte-dnd-action": "^0.9.49" 12 | }, 13 | "devDependencies": { 14 | "@sveltejs/vite-plugin-svelte": "^3.1.1", 15 | "@tsconfig/svelte": "^5.0.4", 16 | "@types/node": "^20.14.11", 17 | "svelte": "^4.2.18", 18 | "svelte-check": "^3.8.4", 19 | "tslib": "^2.6.3", 20 | "typescript": "^5.2.2", 21 | "vite": "^5.3.4" 22 | } 23 | }, 24 | "node_modules/@ampproject/remapping": { 25 | "version": "2.3.0", 26 | "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", 27 | "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", 28 | "dependencies": { 29 | "@jridgewell/gen-mapping": "^0.3.5", 30 | "@jridgewell/trace-mapping": "^0.3.24" 31 | }, 32 | "engines": { 33 | "node": ">=6.0.0" 34 | } 35 | }, 36 | "node_modules/@jridgewell/gen-mapping": { 37 | "version": "0.3.5", 38 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", 39 | "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", 40 | "dependencies": { 41 | "@jridgewell/set-array": "^1.2.1", 42 | "@jridgewell/sourcemap-codec": "^1.4.10", 43 | "@jridgewell/trace-mapping": "^0.3.24" 44 | }, 45 | "engines": { 46 | "node": ">=6.0.0" 47 | } 48 | }, 49 | "node_modules/@jridgewell/resolve-uri": { 50 | "version": "3.1.2", 51 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 52 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 53 | "engines": { 54 | "node": ">=6.0.0" 55 | } 56 | }, 57 | "node_modules/@jridgewell/set-array": { 58 | "version": "1.2.1", 59 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", 60 | "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", 61 | "engines": { 62 | "node": ">=6.0.0" 63 | } 64 | }, 65 | "node_modules/@jridgewell/sourcemap-codec": { 66 | "version": "1.5.0", 67 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 68 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" 69 | }, 70 | "node_modules/@jridgewell/trace-mapping": { 71 | "version": "0.3.25", 72 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 73 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 74 | "dependencies": { 75 | "@jridgewell/resolve-uri": "^3.1.0", 76 | "@jridgewell/sourcemap-codec": "^1.4.14" 77 | } 78 | }, 79 | "node_modules/@rollup/rollup-android-arm-eabi": { 80 | "version": "4.18.1", 81 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", 82 | "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", 83 | "cpu": [ 84 | "arm" 85 | ], 86 | "dev": true, 87 | "optional": true, 88 | "os": [ 89 | "android" 90 | ] 91 | }, 92 | "node_modules/@rollup/rollup-android-arm64": { 93 | "version": "4.18.1", 94 | "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", 95 | "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", 96 | "cpu": [ 97 | "arm64" 98 | ], 99 | "dev": true, 100 | "optional": true, 101 | "os": [ 102 | "android" 103 | ] 104 | }, 105 | "node_modules/@rollup/rollup-darwin-arm64": { 106 | "version": "4.18.1", 107 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", 108 | "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", 109 | "cpu": [ 110 | "arm64" 111 | ], 112 | "dev": true, 113 | "optional": true, 114 | "os": [ 115 | "darwin" 116 | ] 117 | }, 118 | "node_modules/@rollup/rollup-darwin-x64": { 119 | "version": "4.18.1", 120 | "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", 121 | "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", 122 | "cpu": [ 123 | "x64" 124 | ], 125 | "dev": true, 126 | "optional": true, 127 | "os": [ 128 | "darwin" 129 | ] 130 | }, 131 | "node_modules/@rollup/rollup-linux-arm-gnueabihf": { 132 | "version": "4.18.1", 133 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", 134 | "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", 135 | "cpu": [ 136 | "arm" 137 | ], 138 | "dev": true, 139 | "optional": true, 140 | "os": [ 141 | "linux" 142 | ] 143 | }, 144 | "node_modules/@rollup/rollup-linux-arm-musleabihf": { 145 | "version": "4.18.1", 146 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", 147 | "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", 148 | "cpu": [ 149 | "arm" 150 | ], 151 | "dev": true, 152 | "optional": true, 153 | "os": [ 154 | "linux" 155 | ] 156 | }, 157 | "node_modules/@rollup/rollup-linux-arm64-gnu": { 158 | "version": "4.18.1", 159 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", 160 | "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", 161 | "cpu": [ 162 | "arm64" 163 | ], 164 | "dev": true, 165 | "optional": true, 166 | "os": [ 167 | "linux" 168 | ] 169 | }, 170 | "node_modules/@rollup/rollup-linux-arm64-musl": { 171 | "version": "4.18.1", 172 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", 173 | "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", 174 | "cpu": [ 175 | "arm64" 176 | ], 177 | "dev": true, 178 | "optional": true, 179 | "os": [ 180 | "linux" 181 | ] 182 | }, 183 | "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { 184 | "version": "4.18.1", 185 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", 186 | "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", 187 | "cpu": [ 188 | "ppc64" 189 | ], 190 | "dev": true, 191 | "optional": true, 192 | "os": [ 193 | "linux" 194 | ] 195 | }, 196 | "node_modules/@rollup/rollup-linux-riscv64-gnu": { 197 | "version": "4.18.1", 198 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", 199 | "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", 200 | "cpu": [ 201 | "riscv64" 202 | ], 203 | "dev": true, 204 | "optional": true, 205 | "os": [ 206 | "linux" 207 | ] 208 | }, 209 | "node_modules/@rollup/rollup-linux-s390x-gnu": { 210 | "version": "4.18.1", 211 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", 212 | "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", 213 | "cpu": [ 214 | "s390x" 215 | ], 216 | "dev": true, 217 | "optional": true, 218 | "os": [ 219 | "linux" 220 | ] 221 | }, 222 | "node_modules/@rollup/rollup-linux-x64-gnu": { 223 | "version": "4.18.1", 224 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", 225 | "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", 226 | "cpu": [ 227 | "x64" 228 | ], 229 | "dev": true, 230 | "optional": true, 231 | "os": [ 232 | "linux" 233 | ] 234 | }, 235 | "node_modules/@rollup/rollup-linux-x64-musl": { 236 | "version": "4.18.1", 237 | "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", 238 | "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", 239 | "cpu": [ 240 | "x64" 241 | ], 242 | "dev": true, 243 | "optional": true, 244 | "os": [ 245 | "linux" 246 | ] 247 | }, 248 | "node_modules/@rollup/rollup-win32-arm64-msvc": { 249 | "version": "4.18.1", 250 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", 251 | "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", 252 | "cpu": [ 253 | "arm64" 254 | ], 255 | "dev": true, 256 | "optional": true, 257 | "os": [ 258 | "win32" 259 | ] 260 | }, 261 | "node_modules/@rollup/rollup-win32-ia32-msvc": { 262 | "version": "4.18.1", 263 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", 264 | "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", 265 | "cpu": [ 266 | "ia32" 267 | ], 268 | "dev": true, 269 | "optional": true, 270 | "os": [ 271 | "win32" 272 | ] 273 | }, 274 | "node_modules/@rollup/rollup-win32-x64-msvc": { 275 | "version": "4.18.1", 276 | "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", 277 | "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", 278 | "cpu": [ 279 | "x64" 280 | ], 281 | "dev": true, 282 | "optional": true, 283 | "os": [ 284 | "win32" 285 | ] 286 | }, 287 | "node_modules/@sveltejs/vite-plugin-svelte": { 288 | "version": "3.1.1", 289 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.1.1.tgz", 290 | "integrity": "sha512-rimpFEAboBBHIlzISibg94iP09k/KYdHgVhJlcsTfn7KMBhc70jFX/GRWkRdFCc2fdnk+4+Bdfej23cMDnJS6A==", 291 | "dev": true, 292 | "dependencies": { 293 | "@sveltejs/vite-plugin-svelte-inspector": "^2.1.0", 294 | "debug": "^4.3.4", 295 | "deepmerge": "^4.3.1", 296 | "kleur": "^4.1.5", 297 | "magic-string": "^0.30.10", 298 | "svelte-hmr": "^0.16.0", 299 | "vitefu": "^0.2.5" 300 | }, 301 | "engines": { 302 | "node": "^18.0.0 || >=20" 303 | }, 304 | "peerDependencies": { 305 | "svelte": "^4.0.0 || ^5.0.0-next.0", 306 | "vite": "^5.0.0" 307 | } 308 | }, 309 | "node_modules/@sveltejs/vite-plugin-svelte-inspector": { 310 | "version": "2.1.0", 311 | "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.1.0.tgz", 312 | "integrity": "sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==", 313 | "dev": true, 314 | "dependencies": { 315 | "debug": "^4.3.4" 316 | }, 317 | "engines": { 318 | "node": "^18.0.0 || >=20" 319 | }, 320 | "peerDependencies": { 321 | "@sveltejs/vite-plugin-svelte": "^3.0.0", 322 | "svelte": "^4.0.0 || ^5.0.0-next.0", 323 | "vite": "^5.0.0" 324 | } 325 | }, 326 | "node_modules/@sveltejs/vite-plugin-svelte/node_modules/svelte-hmr": { 327 | "version": "0.16.0", 328 | "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.16.0.tgz", 329 | "integrity": "sha512-Gyc7cOS3VJzLlfj7wKS0ZnzDVdv3Pn2IuVeJPk9m2skfhcu5bq3wtIZyQGggr7/Iim5rH5cncyQft/kRLupcnA==", 330 | "dev": true, 331 | "engines": { 332 | "node": "^12.20 || ^14.13.1 || >= 16" 333 | }, 334 | "peerDependencies": { 335 | "svelte": "^3.19.0 || ^4.0.0" 336 | } 337 | }, 338 | "node_modules/@tsconfig/svelte": { 339 | "version": "5.0.4", 340 | "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-5.0.4.tgz", 341 | "integrity": "sha512-BV9NplVgLmSi4mwKzD8BD/NQ8erOY/nUE/GpgWe2ckx+wIQF5RyRirn/QsSSCPeulVpc3RA/iJt6DpfTIZps0Q==", 342 | "dev": true 343 | }, 344 | "node_modules/@types/estree": { 345 | "version": "1.0.5", 346 | "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", 347 | "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" 348 | }, 349 | "node_modules/@types/node": { 350 | "version": "20.14.11", 351 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", 352 | "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", 353 | "dev": true, 354 | "dependencies": { 355 | "undici-types": "~5.26.4" 356 | } 357 | }, 358 | "node_modules/@types/pug": { 359 | "version": "2.0.10", 360 | "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", 361 | "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", 362 | "dev": true 363 | }, 364 | "node_modules/acorn": { 365 | "version": "8.12.1", 366 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", 367 | "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", 368 | "bin": { 369 | "acorn": "bin/acorn" 370 | }, 371 | "engines": { 372 | "node": ">=0.4.0" 373 | } 374 | }, 375 | "node_modules/anymatch": { 376 | "version": "3.1.3", 377 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", 378 | "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", 379 | "dev": true, 380 | "dependencies": { 381 | "normalize-path": "^3.0.0", 382 | "picomatch": "^2.0.4" 383 | }, 384 | "engines": { 385 | "node": ">= 8" 386 | } 387 | }, 388 | "node_modules/aria-query": { 389 | "version": "5.3.0", 390 | "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", 391 | "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", 392 | "dependencies": { 393 | "dequal": "^2.0.3" 394 | } 395 | }, 396 | "node_modules/axobject-query": { 397 | "version": "4.1.0", 398 | "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", 399 | "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", 400 | "engines": { 401 | "node": ">= 0.4" 402 | } 403 | }, 404 | "node_modules/balanced-match": { 405 | "version": "1.0.2", 406 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 407 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 408 | "dev": true 409 | }, 410 | "node_modules/binary-extensions": { 411 | "version": "2.3.0", 412 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", 413 | "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", 414 | "dev": true, 415 | "engines": { 416 | "node": ">=8" 417 | }, 418 | "funding": { 419 | "url": "https://github.com/sponsors/sindresorhus" 420 | } 421 | }, 422 | "node_modules/brace-expansion": { 423 | "version": "1.1.11", 424 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 425 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 426 | "dev": true, 427 | "dependencies": { 428 | "balanced-match": "^1.0.0", 429 | "concat-map": "0.0.1" 430 | } 431 | }, 432 | "node_modules/braces": { 433 | "version": "3.0.3", 434 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", 435 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", 436 | "dev": true, 437 | "dependencies": { 438 | "fill-range": "^7.1.1" 439 | }, 440 | "engines": { 441 | "node": ">=8" 442 | } 443 | }, 444 | "node_modules/buffer-crc32": { 445 | "version": "1.0.0", 446 | "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", 447 | "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", 448 | "dev": true, 449 | "engines": { 450 | "node": ">=8.0.0" 451 | } 452 | }, 453 | "node_modules/chokidar": { 454 | "version": "3.6.0", 455 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", 456 | "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", 457 | "dev": true, 458 | "dependencies": { 459 | "anymatch": "~3.1.2", 460 | "braces": "~3.0.2", 461 | "glob-parent": "~5.1.2", 462 | "is-binary-path": "~2.1.0", 463 | "is-glob": "~4.0.1", 464 | "normalize-path": "~3.0.0", 465 | "readdirp": "~3.6.0" 466 | }, 467 | "engines": { 468 | "node": ">= 8.10.0" 469 | }, 470 | "funding": { 471 | "url": "https://paulmillr.com/funding/" 472 | }, 473 | "optionalDependencies": { 474 | "fsevents": "~2.3.2" 475 | } 476 | }, 477 | "node_modules/code-red": { 478 | "version": "1.0.4", 479 | "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", 480 | "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", 481 | "dependencies": { 482 | "@jridgewell/sourcemap-codec": "^1.4.15", 483 | "@types/estree": "^1.0.1", 484 | "acorn": "^8.10.0", 485 | "estree-walker": "^3.0.3", 486 | "periscopic": "^3.1.0" 487 | } 488 | }, 489 | "node_modules/concat-map": { 490 | "version": "0.0.1", 491 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 492 | "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", 493 | "dev": true 494 | }, 495 | "node_modules/css-tree": { 496 | "version": "2.3.1", 497 | "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", 498 | "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", 499 | "dependencies": { 500 | "mdn-data": "2.0.30", 501 | "source-map-js": "^1.0.1" 502 | }, 503 | "engines": { 504 | "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" 505 | } 506 | }, 507 | "node_modules/debug": { 508 | "version": "4.3.5", 509 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 510 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 511 | "dev": true, 512 | "dependencies": { 513 | "ms": "2.1.2" 514 | }, 515 | "engines": { 516 | "node": ">=6.0" 517 | }, 518 | "peerDependenciesMeta": { 519 | "supports-color": { 520 | "optional": true 521 | } 522 | } 523 | }, 524 | "node_modules/deepmerge": { 525 | "version": "4.3.1", 526 | "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", 527 | "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", 528 | "dev": true, 529 | "engines": { 530 | "node": ">=0.10.0" 531 | } 532 | }, 533 | "node_modules/dequal": { 534 | "version": "2.0.3", 535 | "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", 536 | "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", 537 | "engines": { 538 | "node": ">=6" 539 | } 540 | }, 541 | "node_modules/detect-indent": { 542 | "version": "6.1.0", 543 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", 544 | "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", 545 | "dev": true, 546 | "engines": { 547 | "node": ">=8" 548 | } 549 | }, 550 | "node_modules/es6-promise": { 551 | "version": "3.3.1", 552 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", 553 | "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", 554 | "dev": true 555 | }, 556 | "node_modules/estree-walker": { 557 | "version": "3.0.3", 558 | "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", 559 | "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", 560 | "dependencies": { 561 | "@types/estree": "^1.0.0" 562 | } 563 | }, 564 | "node_modules/fill-range": { 565 | "version": "7.1.1", 566 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", 567 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", 568 | "dev": true, 569 | "dependencies": { 570 | "to-regex-range": "^5.0.1" 571 | }, 572 | "engines": { 573 | "node": ">=8" 574 | } 575 | }, 576 | "node_modules/fs.realpath": { 577 | "version": "1.0.0", 578 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 579 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 580 | "dev": true 581 | }, 582 | "node_modules/fsevents": { 583 | "version": "2.3.3", 584 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", 585 | "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", 586 | "dev": true, 587 | "hasInstallScript": true, 588 | "optional": true, 589 | "os": [ 590 | "darwin" 591 | ], 592 | "engines": { 593 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 594 | } 595 | }, 596 | "node_modules/glob": { 597 | "version": "7.2.3", 598 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 599 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 600 | "deprecated": "Glob versions prior to v9 are no longer supported", 601 | "dev": true, 602 | "dependencies": { 603 | "fs.realpath": "^1.0.0", 604 | "inflight": "^1.0.4", 605 | "inherits": "2", 606 | "minimatch": "^3.1.1", 607 | "once": "^1.3.0", 608 | "path-is-absolute": "^1.0.0" 609 | }, 610 | "engines": { 611 | "node": "*" 612 | }, 613 | "funding": { 614 | "url": "https://github.com/sponsors/isaacs" 615 | } 616 | }, 617 | "node_modules/glob-parent": { 618 | "version": "5.1.2", 619 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", 620 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", 621 | "dev": true, 622 | "dependencies": { 623 | "is-glob": "^4.0.1" 624 | }, 625 | "engines": { 626 | "node": ">= 6" 627 | } 628 | }, 629 | "node_modules/graceful-fs": { 630 | "version": "4.2.11", 631 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 632 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 633 | "dev": true 634 | }, 635 | "node_modules/inflight": { 636 | "version": "1.0.6", 637 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 638 | "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", 639 | "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", 640 | "dev": true, 641 | "dependencies": { 642 | "once": "^1.3.0", 643 | "wrappy": "1" 644 | } 645 | }, 646 | "node_modules/inherits": { 647 | "version": "2.0.4", 648 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 649 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 650 | "dev": true 651 | }, 652 | "node_modules/is-binary-path": { 653 | "version": "2.1.0", 654 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 655 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 656 | "dev": true, 657 | "dependencies": { 658 | "binary-extensions": "^2.0.0" 659 | }, 660 | "engines": { 661 | "node": ">=8" 662 | } 663 | }, 664 | "node_modules/is-extglob": { 665 | "version": "2.1.1", 666 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 667 | "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", 668 | "dev": true, 669 | "engines": { 670 | "node": ">=0.10.0" 671 | } 672 | }, 673 | "node_modules/is-glob": { 674 | "version": "4.0.3", 675 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", 676 | "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", 677 | "dev": true, 678 | "dependencies": { 679 | "is-extglob": "^2.1.1" 680 | }, 681 | "engines": { 682 | "node": ">=0.10.0" 683 | } 684 | }, 685 | "node_modules/is-number": { 686 | "version": "7.0.0", 687 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 688 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 689 | "dev": true, 690 | "engines": { 691 | "node": ">=0.12.0" 692 | } 693 | }, 694 | "node_modules/is-reference": { 695 | "version": "3.0.2", 696 | "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", 697 | "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", 698 | "dependencies": { 699 | "@types/estree": "*" 700 | } 701 | }, 702 | "node_modules/kleur": { 703 | "version": "4.1.5", 704 | "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", 705 | "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", 706 | "dev": true, 707 | "engines": { 708 | "node": ">=6" 709 | } 710 | }, 711 | "node_modules/locate-character": { 712 | "version": "3.0.0", 713 | "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz", 714 | "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==" 715 | }, 716 | "node_modules/magic-string": { 717 | "version": "0.30.10", 718 | "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", 719 | "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", 720 | "dependencies": { 721 | "@jridgewell/sourcemap-codec": "^1.4.15" 722 | } 723 | }, 724 | "node_modules/mdn-data": { 725 | "version": "2.0.30", 726 | "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", 727 | "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" 728 | }, 729 | "node_modules/min-indent": { 730 | "version": "1.0.1", 731 | "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", 732 | "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", 733 | "dev": true, 734 | "engines": { 735 | "node": ">=4" 736 | } 737 | }, 738 | "node_modules/minimatch": { 739 | "version": "3.1.2", 740 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 741 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 742 | "dev": true, 743 | "dependencies": { 744 | "brace-expansion": "^1.1.7" 745 | }, 746 | "engines": { 747 | "node": "*" 748 | } 749 | }, 750 | "node_modules/minimist": { 751 | "version": "1.2.8", 752 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 753 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 754 | "dev": true, 755 | "funding": { 756 | "url": "https://github.com/sponsors/ljharb" 757 | } 758 | }, 759 | "node_modules/mkdirp": { 760 | "version": "0.5.6", 761 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", 762 | "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", 763 | "dev": true, 764 | "dependencies": { 765 | "minimist": "^1.2.6" 766 | }, 767 | "bin": { 768 | "mkdirp": "bin/cmd.js" 769 | } 770 | }, 771 | "node_modules/mri": { 772 | "version": "1.2.0", 773 | "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", 774 | "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", 775 | "dev": true, 776 | "engines": { 777 | "node": ">=4" 778 | } 779 | }, 780 | "node_modules/ms": { 781 | "version": "2.1.2", 782 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 783 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 784 | "dev": true 785 | }, 786 | "node_modules/nanoid": { 787 | "version": "3.3.7", 788 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", 789 | "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", 790 | "dev": true, 791 | "funding": [ 792 | { 793 | "type": "github", 794 | "url": "https://github.com/sponsors/ai" 795 | } 796 | ], 797 | "bin": { 798 | "nanoid": "bin/nanoid.cjs" 799 | }, 800 | "engines": { 801 | "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" 802 | } 803 | }, 804 | "node_modules/normalize-path": { 805 | "version": "3.0.0", 806 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 807 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 808 | "dev": true, 809 | "engines": { 810 | "node": ">=0.10.0" 811 | } 812 | }, 813 | "node_modules/once": { 814 | "version": "1.4.0", 815 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 816 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 817 | "dev": true, 818 | "dependencies": { 819 | "wrappy": "1" 820 | } 821 | }, 822 | "node_modules/path-is-absolute": { 823 | "version": "1.0.1", 824 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 825 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 826 | "dev": true, 827 | "engines": { 828 | "node": ">=0.10.0" 829 | } 830 | }, 831 | "node_modules/periscopic": { 832 | "version": "3.1.0", 833 | "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", 834 | "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", 835 | "dependencies": { 836 | "@types/estree": "^1.0.0", 837 | "estree-walker": "^3.0.0", 838 | "is-reference": "^3.0.0" 839 | } 840 | }, 841 | "node_modules/picocolors": { 842 | "version": "1.0.1", 843 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", 844 | "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", 845 | "dev": true 846 | }, 847 | "node_modules/picomatch": { 848 | "version": "2.3.1", 849 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", 850 | "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", 851 | "dev": true, 852 | "engines": { 853 | "node": ">=8.6" 854 | }, 855 | "funding": { 856 | "url": "https://github.com/sponsors/jonschlinkert" 857 | } 858 | }, 859 | "node_modules/postcss": { 860 | "version": "8.4.39", 861 | "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", 862 | "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", 863 | "dev": true, 864 | "funding": [ 865 | { 866 | "type": "opencollective", 867 | "url": "https://opencollective.com/postcss/" 868 | }, 869 | { 870 | "type": "tidelift", 871 | "url": "https://tidelift.com/funding/github/npm/postcss" 872 | }, 873 | { 874 | "type": "github", 875 | "url": "https://github.com/sponsors/ai" 876 | } 877 | ], 878 | "dependencies": { 879 | "nanoid": "^3.3.7", 880 | "picocolors": "^1.0.1", 881 | "source-map-js": "^1.2.0" 882 | }, 883 | "engines": { 884 | "node": "^10 || ^12 || >=14" 885 | } 886 | }, 887 | "node_modules/readdirp": { 888 | "version": "3.6.0", 889 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", 890 | "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", 891 | "dev": true, 892 | "dependencies": { 893 | "picomatch": "^2.2.1" 894 | }, 895 | "engines": { 896 | "node": ">=8.10.0" 897 | } 898 | }, 899 | "node_modules/rimraf": { 900 | "version": "2.7.1", 901 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", 902 | "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", 903 | "deprecated": "Rimraf versions prior to v4 are no longer supported", 904 | "dev": true, 905 | "dependencies": { 906 | "glob": "^7.1.3" 907 | }, 908 | "bin": { 909 | "rimraf": "bin.js" 910 | } 911 | }, 912 | "node_modules/rollup": { 913 | "version": "4.18.1", 914 | "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", 915 | "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", 916 | "dev": true, 917 | "dependencies": { 918 | "@types/estree": "1.0.5" 919 | }, 920 | "bin": { 921 | "rollup": "dist/bin/rollup" 922 | }, 923 | "engines": { 924 | "node": ">=18.0.0", 925 | "npm": ">=8.0.0" 926 | }, 927 | "optionalDependencies": { 928 | "@rollup/rollup-android-arm-eabi": "4.18.1", 929 | "@rollup/rollup-android-arm64": "4.18.1", 930 | "@rollup/rollup-darwin-arm64": "4.18.1", 931 | "@rollup/rollup-darwin-x64": "4.18.1", 932 | "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", 933 | "@rollup/rollup-linux-arm-musleabihf": "4.18.1", 934 | "@rollup/rollup-linux-arm64-gnu": "4.18.1", 935 | "@rollup/rollup-linux-arm64-musl": "4.18.1", 936 | "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", 937 | "@rollup/rollup-linux-riscv64-gnu": "4.18.1", 938 | "@rollup/rollup-linux-s390x-gnu": "4.18.1", 939 | "@rollup/rollup-linux-x64-gnu": "4.18.1", 940 | "@rollup/rollup-linux-x64-musl": "4.18.1", 941 | "@rollup/rollup-win32-arm64-msvc": "4.18.1", 942 | "@rollup/rollup-win32-ia32-msvc": "4.18.1", 943 | "@rollup/rollup-win32-x64-msvc": "4.18.1", 944 | "fsevents": "~2.3.2" 945 | } 946 | }, 947 | "node_modules/sade": { 948 | "version": "1.8.1", 949 | "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", 950 | "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", 951 | "dev": true, 952 | "dependencies": { 953 | "mri": "^1.1.0" 954 | }, 955 | "engines": { 956 | "node": ">=6" 957 | } 958 | }, 959 | "node_modules/sander": { 960 | "version": "0.5.1", 961 | "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", 962 | "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", 963 | "dev": true, 964 | "dependencies": { 965 | "es6-promise": "^3.1.2", 966 | "graceful-fs": "^4.1.3", 967 | "mkdirp": "^0.5.1", 968 | "rimraf": "^2.5.2" 969 | } 970 | }, 971 | "node_modules/sorcery": { 972 | "version": "0.11.1", 973 | "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.1.tgz", 974 | "integrity": "sha512-o7npfeJE6wi6J9l0/5LKshFzZ2rMatRiCDwYeDQaOzqdzRJwALhX7mk/A/ecg6wjMu7wdZbmXfD2S/vpOg0bdQ==", 975 | "dev": true, 976 | "dependencies": { 977 | "@jridgewell/sourcemap-codec": "^1.4.14", 978 | "buffer-crc32": "^1.0.0", 979 | "minimist": "^1.2.0", 980 | "sander": "^0.5.0" 981 | }, 982 | "bin": { 983 | "sorcery": "bin/sorcery" 984 | } 985 | }, 986 | "node_modules/source-map-js": { 987 | "version": "1.2.0", 988 | "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", 989 | "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", 990 | "engines": { 991 | "node": ">=0.10.0" 992 | } 993 | }, 994 | "node_modules/strip-indent": { 995 | "version": "3.0.0", 996 | "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", 997 | "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", 998 | "dev": true, 999 | "dependencies": { 1000 | "min-indent": "^1.0.0" 1001 | }, 1002 | "engines": { 1003 | "node": ">=8" 1004 | } 1005 | }, 1006 | "node_modules/svelte": { 1007 | "version": "4.2.18", 1008 | "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.18.tgz", 1009 | "integrity": "sha512-d0FdzYIiAePqRJEb90WlJDkjUEx42xhivxN8muUBmfZnP+tzUgz12DJ2hRJi8sIHCME7jeK1PTMgKPSfTd8JrA==", 1010 | "dependencies": { 1011 | "@ampproject/remapping": "^2.2.1", 1012 | "@jridgewell/sourcemap-codec": "^1.4.15", 1013 | "@jridgewell/trace-mapping": "^0.3.18", 1014 | "@types/estree": "^1.0.1", 1015 | "acorn": "^8.9.0", 1016 | "aria-query": "^5.3.0", 1017 | "axobject-query": "^4.0.0", 1018 | "code-red": "^1.0.3", 1019 | "css-tree": "^2.3.1", 1020 | "estree-walker": "^3.0.3", 1021 | "is-reference": "^3.0.1", 1022 | "locate-character": "^3.0.0", 1023 | "magic-string": "^0.30.4", 1024 | "periscopic": "^3.1.0" 1025 | }, 1026 | "engines": { 1027 | "node": ">=16" 1028 | } 1029 | }, 1030 | "node_modules/svelte-check": { 1031 | "version": "3.8.4", 1032 | "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.8.4.tgz", 1033 | "integrity": "sha512-61aHMkdinWyH8BkkTX9jPLYxYzaAAz/FK/VQqdr2FiCQQ/q04WCwDlpGbHff1GdrMYTmW8chlTFvRWL9k0A8vg==", 1034 | "dev": true, 1035 | "dependencies": { 1036 | "@jridgewell/trace-mapping": "^0.3.17", 1037 | "chokidar": "^3.4.1", 1038 | "picocolors": "^1.0.0", 1039 | "sade": "^1.7.4", 1040 | "svelte-preprocess": "^5.1.3", 1041 | "typescript": "^5.0.3" 1042 | }, 1043 | "bin": { 1044 | "svelte-check": "bin/svelte-check" 1045 | }, 1046 | "peerDependencies": { 1047 | "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" 1048 | } 1049 | }, 1050 | "node_modules/svelte-dnd-action": { 1051 | "version": "0.9.49", 1052 | "resolved": "https://registry.npmjs.org/svelte-dnd-action/-/svelte-dnd-action-0.9.49.tgz", 1053 | "integrity": "sha512-kAIDTSMoTZcJCqUpT8COLAkF0/NRBoJ/pIbPUra9UVRnyJljLy6dLgRuL2OojSqyNs3nToBvn5XOGaFMREwjfQ==", 1054 | "peerDependencies": { 1055 | "svelte": ">=3.23.0 || ^5.0.0-next.0" 1056 | } 1057 | }, 1058 | "node_modules/svelte-preprocess": { 1059 | "version": "5.1.4", 1060 | "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.4.tgz", 1061 | "integrity": "sha512-IvnbQ6D6Ao3Gg6ftiM5tdbR6aAETwjhHV+UKGf5bHGYR69RQvF1ho0JKPcbUON4vy4R7zom13jPjgdOWCQ5hDA==", 1062 | "dev": true, 1063 | "hasInstallScript": true, 1064 | "dependencies": { 1065 | "@types/pug": "^2.0.6", 1066 | "detect-indent": "^6.1.0", 1067 | "magic-string": "^0.30.5", 1068 | "sorcery": "^0.11.0", 1069 | "strip-indent": "^3.0.0" 1070 | }, 1071 | "engines": { 1072 | "node": ">= 16.0.0" 1073 | }, 1074 | "peerDependencies": { 1075 | "@babel/core": "^7.10.2", 1076 | "coffeescript": "^2.5.1", 1077 | "less": "^3.11.3 || ^4.0.0", 1078 | "postcss": "^7 || ^8", 1079 | "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0", 1080 | "pug": "^3.0.0", 1081 | "sass": "^1.26.8", 1082 | "stylus": "^0.55.0", 1083 | "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0", 1084 | "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0", 1085 | "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0" 1086 | }, 1087 | "peerDependenciesMeta": { 1088 | "@babel/core": { 1089 | "optional": true 1090 | }, 1091 | "coffeescript": { 1092 | "optional": true 1093 | }, 1094 | "less": { 1095 | "optional": true 1096 | }, 1097 | "postcss": { 1098 | "optional": true 1099 | }, 1100 | "postcss-load-config": { 1101 | "optional": true 1102 | }, 1103 | "pug": { 1104 | "optional": true 1105 | }, 1106 | "sass": { 1107 | "optional": true 1108 | }, 1109 | "stylus": { 1110 | "optional": true 1111 | }, 1112 | "sugarss": { 1113 | "optional": true 1114 | }, 1115 | "typescript": { 1116 | "optional": true 1117 | } 1118 | } 1119 | }, 1120 | "node_modules/to-regex-range": { 1121 | "version": "5.0.1", 1122 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1123 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1124 | "dev": true, 1125 | "dependencies": { 1126 | "is-number": "^7.0.0" 1127 | }, 1128 | "engines": { 1129 | "node": ">=8.0" 1130 | } 1131 | }, 1132 | "node_modules/tslib": { 1133 | "version": "2.6.3", 1134 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", 1135 | "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", 1136 | "dev": true 1137 | }, 1138 | "node_modules/typescript": { 1139 | "version": "5.5.3", 1140 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", 1141 | "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", 1142 | "dev": true, 1143 | "bin": { 1144 | "tsc": "bin/tsc", 1145 | "tsserver": "bin/tsserver" 1146 | }, 1147 | "engines": { 1148 | "node": ">=14.17" 1149 | } 1150 | }, 1151 | "node_modules/undici-types": { 1152 | "version": "5.26.5", 1153 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 1154 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 1155 | "dev": true 1156 | }, 1157 | "node_modules/vite": { 1158 | "version": "5.3.4", 1159 | "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", 1160 | "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", 1161 | "dev": true, 1162 | "dependencies": { 1163 | "esbuild": "^0.21.3", 1164 | "postcss": "^8.4.39", 1165 | "rollup": "^4.13.0" 1166 | }, 1167 | "bin": { 1168 | "vite": "bin/vite.js" 1169 | }, 1170 | "engines": { 1171 | "node": "^18.0.0 || >=20.0.0" 1172 | }, 1173 | "funding": { 1174 | "url": "https://github.com/vitejs/vite?sponsor=1" 1175 | }, 1176 | "optionalDependencies": { 1177 | "fsevents": "~2.3.3" 1178 | }, 1179 | "peerDependencies": { 1180 | "@types/node": "^18.0.0 || >=20.0.0", 1181 | "less": "*", 1182 | "lightningcss": "^1.21.0", 1183 | "sass": "*", 1184 | "stylus": "*", 1185 | "sugarss": "*", 1186 | "terser": "^5.4.0" 1187 | }, 1188 | "peerDependenciesMeta": { 1189 | "@types/node": { 1190 | "optional": true 1191 | }, 1192 | "less": { 1193 | "optional": true 1194 | }, 1195 | "lightningcss": { 1196 | "optional": true 1197 | }, 1198 | "sass": { 1199 | "optional": true 1200 | }, 1201 | "stylus": { 1202 | "optional": true 1203 | }, 1204 | "sugarss": { 1205 | "optional": true 1206 | }, 1207 | "terser": { 1208 | "optional": true 1209 | } 1210 | } 1211 | }, 1212 | "node_modules/vite/node_modules/@esbuild/aix-ppc64": { 1213 | "version": "0.21.5", 1214 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", 1215 | "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", 1216 | "cpu": [ 1217 | "ppc64" 1218 | ], 1219 | "dev": true, 1220 | "optional": true, 1221 | "os": [ 1222 | "aix" 1223 | ], 1224 | "engines": { 1225 | "node": ">=12" 1226 | } 1227 | }, 1228 | "node_modules/vite/node_modules/@esbuild/android-arm": { 1229 | "version": "0.21.5", 1230 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", 1231 | "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", 1232 | "cpu": [ 1233 | "arm" 1234 | ], 1235 | "dev": true, 1236 | "optional": true, 1237 | "os": [ 1238 | "android" 1239 | ], 1240 | "engines": { 1241 | "node": ">=12" 1242 | } 1243 | }, 1244 | "node_modules/vite/node_modules/@esbuild/android-arm64": { 1245 | "version": "0.21.5", 1246 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", 1247 | "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", 1248 | "cpu": [ 1249 | "arm64" 1250 | ], 1251 | "dev": true, 1252 | "optional": true, 1253 | "os": [ 1254 | "android" 1255 | ], 1256 | "engines": { 1257 | "node": ">=12" 1258 | } 1259 | }, 1260 | "node_modules/vite/node_modules/@esbuild/android-x64": { 1261 | "version": "0.21.5", 1262 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", 1263 | "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", 1264 | "cpu": [ 1265 | "x64" 1266 | ], 1267 | "dev": true, 1268 | "optional": true, 1269 | "os": [ 1270 | "android" 1271 | ], 1272 | "engines": { 1273 | "node": ">=12" 1274 | } 1275 | }, 1276 | "node_modules/vite/node_modules/@esbuild/darwin-arm64": { 1277 | "version": "0.21.5", 1278 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", 1279 | "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", 1280 | "cpu": [ 1281 | "arm64" 1282 | ], 1283 | "dev": true, 1284 | "optional": true, 1285 | "os": [ 1286 | "darwin" 1287 | ], 1288 | "engines": { 1289 | "node": ">=12" 1290 | } 1291 | }, 1292 | "node_modules/vite/node_modules/@esbuild/darwin-x64": { 1293 | "version": "0.21.5", 1294 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", 1295 | "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", 1296 | "cpu": [ 1297 | "x64" 1298 | ], 1299 | "dev": true, 1300 | "optional": true, 1301 | "os": [ 1302 | "darwin" 1303 | ], 1304 | "engines": { 1305 | "node": ">=12" 1306 | } 1307 | }, 1308 | "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { 1309 | "version": "0.21.5", 1310 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", 1311 | "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", 1312 | "cpu": [ 1313 | "arm64" 1314 | ], 1315 | "dev": true, 1316 | "optional": true, 1317 | "os": [ 1318 | "freebsd" 1319 | ], 1320 | "engines": { 1321 | "node": ">=12" 1322 | } 1323 | }, 1324 | "node_modules/vite/node_modules/@esbuild/freebsd-x64": { 1325 | "version": "0.21.5", 1326 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", 1327 | "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", 1328 | "cpu": [ 1329 | "x64" 1330 | ], 1331 | "dev": true, 1332 | "optional": true, 1333 | "os": [ 1334 | "freebsd" 1335 | ], 1336 | "engines": { 1337 | "node": ">=12" 1338 | } 1339 | }, 1340 | "node_modules/vite/node_modules/@esbuild/linux-arm": { 1341 | "version": "0.21.5", 1342 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", 1343 | "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", 1344 | "cpu": [ 1345 | "arm" 1346 | ], 1347 | "dev": true, 1348 | "optional": true, 1349 | "os": [ 1350 | "linux" 1351 | ], 1352 | "engines": { 1353 | "node": ">=12" 1354 | } 1355 | }, 1356 | "node_modules/vite/node_modules/@esbuild/linux-arm64": { 1357 | "version": "0.21.5", 1358 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", 1359 | "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", 1360 | "cpu": [ 1361 | "arm64" 1362 | ], 1363 | "dev": true, 1364 | "optional": true, 1365 | "os": [ 1366 | "linux" 1367 | ], 1368 | "engines": { 1369 | "node": ">=12" 1370 | } 1371 | }, 1372 | "node_modules/vite/node_modules/@esbuild/linux-ia32": { 1373 | "version": "0.21.5", 1374 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", 1375 | "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", 1376 | "cpu": [ 1377 | "ia32" 1378 | ], 1379 | "dev": true, 1380 | "optional": true, 1381 | "os": [ 1382 | "linux" 1383 | ], 1384 | "engines": { 1385 | "node": ">=12" 1386 | } 1387 | }, 1388 | "node_modules/vite/node_modules/@esbuild/linux-loong64": { 1389 | "version": "0.21.5", 1390 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", 1391 | "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", 1392 | "cpu": [ 1393 | "loong64" 1394 | ], 1395 | "dev": true, 1396 | "optional": true, 1397 | "os": [ 1398 | "linux" 1399 | ], 1400 | "engines": { 1401 | "node": ">=12" 1402 | } 1403 | }, 1404 | "node_modules/vite/node_modules/@esbuild/linux-mips64el": { 1405 | "version": "0.21.5", 1406 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", 1407 | "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", 1408 | "cpu": [ 1409 | "mips64el" 1410 | ], 1411 | "dev": true, 1412 | "optional": true, 1413 | "os": [ 1414 | "linux" 1415 | ], 1416 | "engines": { 1417 | "node": ">=12" 1418 | } 1419 | }, 1420 | "node_modules/vite/node_modules/@esbuild/linux-ppc64": { 1421 | "version": "0.21.5", 1422 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", 1423 | "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", 1424 | "cpu": [ 1425 | "ppc64" 1426 | ], 1427 | "dev": true, 1428 | "optional": true, 1429 | "os": [ 1430 | "linux" 1431 | ], 1432 | "engines": { 1433 | "node": ">=12" 1434 | } 1435 | }, 1436 | "node_modules/vite/node_modules/@esbuild/linux-riscv64": { 1437 | "version": "0.21.5", 1438 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", 1439 | "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", 1440 | "cpu": [ 1441 | "riscv64" 1442 | ], 1443 | "dev": true, 1444 | "optional": true, 1445 | "os": [ 1446 | "linux" 1447 | ], 1448 | "engines": { 1449 | "node": ">=12" 1450 | } 1451 | }, 1452 | "node_modules/vite/node_modules/@esbuild/linux-s390x": { 1453 | "version": "0.21.5", 1454 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", 1455 | "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", 1456 | "cpu": [ 1457 | "s390x" 1458 | ], 1459 | "dev": true, 1460 | "optional": true, 1461 | "os": [ 1462 | "linux" 1463 | ], 1464 | "engines": { 1465 | "node": ">=12" 1466 | } 1467 | }, 1468 | "node_modules/vite/node_modules/@esbuild/linux-x64": { 1469 | "version": "0.21.5", 1470 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", 1471 | "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", 1472 | "cpu": [ 1473 | "x64" 1474 | ], 1475 | "dev": true, 1476 | "optional": true, 1477 | "os": [ 1478 | "linux" 1479 | ], 1480 | "engines": { 1481 | "node": ">=12" 1482 | } 1483 | }, 1484 | "node_modules/vite/node_modules/@esbuild/netbsd-x64": { 1485 | "version": "0.21.5", 1486 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", 1487 | "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", 1488 | "cpu": [ 1489 | "x64" 1490 | ], 1491 | "dev": true, 1492 | "optional": true, 1493 | "os": [ 1494 | "netbsd" 1495 | ], 1496 | "engines": { 1497 | "node": ">=12" 1498 | } 1499 | }, 1500 | "node_modules/vite/node_modules/@esbuild/openbsd-x64": { 1501 | "version": "0.21.5", 1502 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", 1503 | "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", 1504 | "cpu": [ 1505 | "x64" 1506 | ], 1507 | "dev": true, 1508 | "optional": true, 1509 | "os": [ 1510 | "openbsd" 1511 | ], 1512 | "engines": { 1513 | "node": ">=12" 1514 | } 1515 | }, 1516 | "node_modules/vite/node_modules/@esbuild/sunos-x64": { 1517 | "version": "0.21.5", 1518 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", 1519 | "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", 1520 | "cpu": [ 1521 | "x64" 1522 | ], 1523 | "dev": true, 1524 | "optional": true, 1525 | "os": [ 1526 | "sunos" 1527 | ], 1528 | "engines": { 1529 | "node": ">=12" 1530 | } 1531 | }, 1532 | "node_modules/vite/node_modules/@esbuild/win32-arm64": { 1533 | "version": "0.21.5", 1534 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", 1535 | "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", 1536 | "cpu": [ 1537 | "arm64" 1538 | ], 1539 | "dev": true, 1540 | "optional": true, 1541 | "os": [ 1542 | "win32" 1543 | ], 1544 | "engines": { 1545 | "node": ">=12" 1546 | } 1547 | }, 1548 | "node_modules/vite/node_modules/@esbuild/win32-ia32": { 1549 | "version": "0.21.5", 1550 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", 1551 | "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", 1552 | "cpu": [ 1553 | "ia32" 1554 | ], 1555 | "dev": true, 1556 | "optional": true, 1557 | "os": [ 1558 | "win32" 1559 | ], 1560 | "engines": { 1561 | "node": ">=12" 1562 | } 1563 | }, 1564 | "node_modules/vite/node_modules/@esbuild/win32-x64": { 1565 | "version": "0.21.5", 1566 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", 1567 | "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", 1568 | "cpu": [ 1569 | "x64" 1570 | ], 1571 | "dev": true, 1572 | "optional": true, 1573 | "os": [ 1574 | "win32" 1575 | ], 1576 | "engines": { 1577 | "node": ">=12" 1578 | } 1579 | }, 1580 | "node_modules/vite/node_modules/esbuild": { 1581 | "version": "0.21.5", 1582 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", 1583 | "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", 1584 | "dev": true, 1585 | "hasInstallScript": true, 1586 | "bin": { 1587 | "esbuild": "bin/esbuild" 1588 | }, 1589 | "engines": { 1590 | "node": ">=12" 1591 | }, 1592 | "optionalDependencies": { 1593 | "@esbuild/aix-ppc64": "0.21.5", 1594 | "@esbuild/android-arm": "0.21.5", 1595 | "@esbuild/android-arm64": "0.21.5", 1596 | "@esbuild/android-x64": "0.21.5", 1597 | "@esbuild/darwin-arm64": "0.21.5", 1598 | "@esbuild/darwin-x64": "0.21.5", 1599 | "@esbuild/freebsd-arm64": "0.21.5", 1600 | "@esbuild/freebsd-x64": "0.21.5", 1601 | "@esbuild/linux-arm": "0.21.5", 1602 | "@esbuild/linux-arm64": "0.21.5", 1603 | "@esbuild/linux-ia32": "0.21.5", 1604 | "@esbuild/linux-loong64": "0.21.5", 1605 | "@esbuild/linux-mips64el": "0.21.5", 1606 | "@esbuild/linux-ppc64": "0.21.5", 1607 | "@esbuild/linux-riscv64": "0.21.5", 1608 | "@esbuild/linux-s390x": "0.21.5", 1609 | "@esbuild/linux-x64": "0.21.5", 1610 | "@esbuild/netbsd-x64": "0.21.5", 1611 | "@esbuild/openbsd-x64": "0.21.5", 1612 | "@esbuild/sunos-x64": "0.21.5", 1613 | "@esbuild/win32-arm64": "0.21.5", 1614 | "@esbuild/win32-ia32": "0.21.5", 1615 | "@esbuild/win32-x64": "0.21.5" 1616 | } 1617 | }, 1618 | "node_modules/vitefu": { 1619 | "version": "0.2.5", 1620 | "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz", 1621 | "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==", 1622 | "dev": true, 1623 | "peerDependencies": { 1624 | "vite": "^3.0.0 || ^4.0.0 || ^5.0.0" 1625 | }, 1626 | "peerDependenciesMeta": { 1627 | "vite": { 1628 | "optional": true 1629 | } 1630 | } 1631 | }, 1632 | "node_modules/wrappy": { 1633 | "version": "1.0.2", 1634 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1635 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 1636 | "dev": true 1637 | } 1638 | } 1639 | } 1640 | --------------------------------------------------------------------------------