aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoog <157747121+doogongithub@users.noreply.github.com>2024-02-21 22:07:27 -0500
committerDoog <157747121+doogongithub@users.noreply.github.com>2024-02-21 22:07:27 -0500
commit3eafb413a48cde60dea8a7355ee621c6acca952f (patch)
tree044bb4ef57033a33024a3a3ffe6ff64f9a00dc9c
parentfac21fa0a72d4a7f1a01ccd44e3acf9c90fd95bd (diff)
first commit
-rw-r--r--api/go.mod32
-rw-r--r--api/go.sum80
-rw-r--r--api/main.go99
-rw-r--r--db/scripts/water_init.sql42
-rw-r--r--db/water.sqlite3bin0 -> 40960 bytes
-rw-r--r--fe/.gitignore24
-rw-r--r--fe/.vscode/extensions.json3
-rw-r--r--fe/README.md47
-rw-r--r--fe/index.html13
-rw-r--r--fe/package-lock.json1772
-rw-r--r--fe/package.json21
-rw-r--r--fe/public/vite.svg1
-rw-r--r--fe/src/App.svelte167
-rw-r--r--fe/src/app.css111
-rw-r--r--fe/src/assets/svelte.svg1
-rw-r--r--fe/src/lib/Card.svelte22
-rw-r--r--fe/src/lib/Counter.svelte10
-rw-r--r--fe/src/lib/Table.svelte41
-rw-r--r--fe/src/lib/errors.ts7
-rw-r--r--fe/src/lib/utils.ts9
-rw-r--r--fe/src/main.ts8
-rw-r--r--fe/src/vite-env.d.ts2
-rw-r--r--fe/svelte.config.js7
-rw-r--r--fe/tsconfig.json20
-rw-r--r--fe/tsconfig.node.json10
-rw-r--r--fe/vite.config.ts7
26 files changed, 2556 insertions, 0 deletions
diff --git a/api/go.mod b/api/go.mod
new file mode 100644
index 0000000..02f7c09
--- /dev/null
+++ b/api/go.mod
@@ -0,0 +1,32 @@
1module water/api
2
3go 1.18
4
5require (
6 github.com/bytedance/sonic v1.11.0 // indirect
7 github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
8 github.com/chenzhuoyu/iasm v0.9.1 // indirect
9 github.com/gabriel-vasile/mimetype v1.4.3 // indirect
10 github.com/gin-contrib/sse v0.1.0 // indirect
11 github.com/gin-gonic/gin v1.9.1 // indirect
12 github.com/go-playground/locales v0.14.1 // indirect
13 github.com/go-playground/universal-translator v0.18.1 // indirect
14 github.com/go-playground/validator/v10 v10.18.0 // indirect
15 github.com/goccy/go-json v0.10.2 // indirect
16 github.com/json-iterator/go v1.1.12 // indirect
17 github.com/klauspost/cpuid/v2 v2.2.6 // indirect
18 github.com/leodido/go-urn v1.4.0 // indirect
19 github.com/mattn/go-isatty v0.0.20 // indirect
20 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
21 github.com/modern-go/reflect2 v1.0.2 // indirect
22 github.com/pelletier/go-toml/v2 v2.1.1 // indirect
23 github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
24 github.com/ugorji/go/codec v1.2.12 // indirect
25 golang.org/x/arch v0.7.0 // indirect
26 golang.org/x/crypto v0.19.0 // indirect
27 golang.org/x/net v0.21.0 // indirect
28 golang.org/x/sys v0.17.0 // indirect
29 golang.org/x/text v0.14.0 // indirect
30 google.golang.org/protobuf v1.32.0 // indirect
31 gopkg.in/yaml.v3 v3.0.1 // indirect
32)
diff --git a/api/go.sum b/api/go.sum
new file mode 100644
index 0000000..eff6af1
--- /dev/null
+++ b/api/go.sum
@@ -0,0 +1,80 @@
1github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
2github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
3github.com/bytedance/sonic v1.11.0 h1:FwNNv6Vu4z2Onf1++LNzxB/QhitD8wuTdpZzMTGITWo=
4github.com/bytedance/sonic v1.11.0/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
5github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
6github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
7github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
8github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
9github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
10github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
11github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
12github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
14github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
15github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
16github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
17github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
18github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
19github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
20github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
21github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
22github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
23github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
24github.com/go-playground/validator/v10 v10.18.0 h1:BvolUXjp4zuvkZ5YN5t7ebzbhlUtPsPm2S9NAZ5nl9U=
25github.com/go-playground/validator/v10 v10.18.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
26github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
27github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
28github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
29github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
30github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
31github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
32github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
33github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
34github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
35github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
36github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
37github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
38github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
39github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
40github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
41github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
42github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
43github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
44github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
45github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
46github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
47github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
48github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
49github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
50github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
51github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
52github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
53github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
54github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
55github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
56github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
57github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
58github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
59github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
60golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
61golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
62golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
63golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
64golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
65golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
66golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
67golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
68golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
69golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
70golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
71golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
72golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
73google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
74google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
75gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
76gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
77gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
78gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
79nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
80rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
diff --git a/api/main.go b/api/main.go
new file mode 100644
index 0000000..ebae5d1
--- /dev/null
+++ b/api/main.go
@@ -0,0 +1,99 @@
1package main
2
3import (
4 "net/http"
5 "crypto/rand"
6 "encoding/base64"
7
8 "github.com/gin-gonic/gin"
9)
10
11func CORSMiddleware() gin.HandlerFunc {
12 return func(c *gin.Context) {
13 c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
14 c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
15 c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
16 c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT")
17
18 if c.Request.Method == "OPTIONS" {
19 c.AbortWithStatus(204)
20 return
21 }
22
23 c.Next()
24 }
25}
26
27func generateToken() string {
28 token := make([]byte, 32)
29 rand.Read(token)
30 return base64.StdEncoding.EncodeToString(token)
31}
32
33type User struct {
34 Username string
35 Password string
36}
37
38var users = map[string]User{
39 "user1": {"user1", "password1"},
40}
41
42func setupRouter() *gin.Engine {
43 // Disable Console Color
44 // gin.DisableConsoleColor()
45 r := gin.Default()
46 r.Use(CORSMiddleware())
47
48 api := r.Group("api/v1")
49
50 api.POST("/auth", func(c *gin.Context) {
51 username, password, ok := c.Request.BasicAuth()
52 if !ok {
53 c.Header("WWW-Authenticate", `Basic realm="Please enter your username and password."`)
54 c.AbortWithStatus(http.StatusUnauthorized)
55 return
56 }
57
58 user, exists := users[username]
59
60 if !exists || user.Password != password {
61 c.AbortWithStatus(http.StatusUnauthorized)
62 return
63 }
64
65 // Generate a simple API token
66 apiToken := generateToken()
67 c.JSON(http.StatusOK, gin.H{"token": apiToken})
68 })
69
70 stats := api.Group("stats")
71
72 stats.GET("/", func(c *gin.Context) {
73 c.JSON(http.StatusOK, gin.H{"status": "ok"})
74 })
75
76 stats.POST("/", func(c *gin.Context) {
77 c.JSON(http.StatusCreated, gin.H{"status": "created"})
78 })
79
80 stats.GET("/:uuid", func(c *gin.Context) {
81 c.JSON(http.StatusOK, gin.H{"status": "ok", "uuid": c.Param("uuid")})
82 })
83
84 stats.PATCH("/:uuid", func(c *gin.Context) {
85 c.JSON(http.StatusNoContent, gin.H{"status": "No Content"})
86 })
87
88 stats.DELETE("/:uuid", func(c *gin.Context) {
89 c.JSON(http.StatusNoContent, gin.H{"status": "No Content"})
90 })
91
92 return r
93}
94
95func main() {
96 r := setupRouter()
97 // Listen and Server in 0.0.0.0:8080
98 r.Run(":8080")
99}
diff --git a/db/scripts/water_init.sql b/db/scripts/water_init.sql
new file mode 100644
index 0000000..d7b912a
--- /dev/null
+++ b/db/scripts/water_init.sql
@@ -0,0 +1,42 @@
1-- user table for users.
2CREATE TABLE IF NOT EXISTS Users (
3 id INT PRIMARY KEY,
4 name TEXT NOT NULL,
5 UNIQUE(name)
6);
7
8-- statistics table for users to log their consumption
9CREATE TABLE IF NOT EXISTS Statistics (
10 id INT PRIMARY KEY,
11 date DATETIME NOT NULL,
12 user_id INT NOT NULL,
13 quantity INT
14);
15
16-- preferences table for a user.
17CREATE TABLE IF NOT EXISTS Preferences (
18 id INT PRIMARY KEY,
19 color TEXT NOT NULL DEFAULT "#000000",
20 user_id INT NOT NULL,
21 size_id INT NOT NULL DEFAULT 1,
22 FOREIGN KEY(user_id) REFERENCES Users(id) ON DELETE CASCADE
23 FOREIGN KEY(size_id) REFERENCES Sizes(id)
24);
25
26-- lookup table for sizes.
27CREATE TABLE IF NOT EXISTS Sizes (
28 id INT PRIMARY KEY,
29 size INT NOT NULL
30 unit TEXT DEFAULT "oz"
31);
32
33-- create default sizes for sizes lookup table.
34INSERT OR IGNORE INTO Sizes (id, size) VALUES (1, 8), (2, 16), (3, 24), (4, 32), (5, 40), (6, 48);
35
36-- create default users.
37INSERT OR IGNORE INTO Users (id, name) VALUES (1, 'Parker'), (2, 'Zach');
38
39-- create default preferences.
40INSERT OR IGNORE INTO Preferences (id, user_id) VALUES (1, 1), (2, 2);
41
42
diff --git a/db/water.sqlite3 b/db/water.sqlite3
new file mode 100644
index 0000000..97f9214
--- /dev/null
+++ b/db/water.sqlite3
Binary files differ
diff --git a/fe/.gitignore b/fe/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/fe/.gitignore
@@ -0,0 +1,24 @@
1# Logs
2logs
3*.log
4npm-debug.log*
5yarn-debug.log*
6yarn-error.log*
7pnpm-debug.log*
8lerna-debug.log*
9
10node_modules
11dist
12dist-ssr
13*.local
14
15# Editor directories and files
16.vscode/*
17!.vscode/extensions.json
18.idea
19.DS_Store
20*.suo
21*.ntvs*
22*.njsproj
23*.sln
24*.sw?
diff --git a/fe/.vscode/extensions.json b/fe/.vscode/extensions.json
new file mode 100644
index 0000000..bdef820
--- /dev/null
+++ b/fe/.vscode/extensions.json
@@ -0,0 +1,3 @@
1{
2 "recommendations": ["svelte.svelte-vscode"]
3}
diff --git a/fe/README.md b/fe/README.md
new file mode 100644
index 0000000..e6cd94f
--- /dev/null
+++ b/fe/README.md
@@ -0,0 +1,47 @@
1# Svelte + TS + Vite
2
3This template should help get you started developing with Svelte and TypeScript in Vite.
4
5## Recommended IDE Setup
6
7[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
8
9## Need an official Svelte framework?
10
11Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
12
13## Technical considerations
14
15**Why use this over SvelteKit?**
16
17- It brings its own routing solution which might not be preferable for some users.
18- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
19
20This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
21
22Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
23
24**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
25
26Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
27
28**Why include `.vscode/extensions.json`?**
29
30Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
31
32**Why enable `allowJs` in the TS template?**
33
34While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant.
35
36**Why is HMR not preserving my local component state?**
37
38HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr).
39
40If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR.
41
42```ts
43// store.ts
44// An extremely simple external store
45import { writable } from 'svelte/store'
46export default writable(0)
47```
diff --git a/fe/index.html b/fe/index.html
new file mode 100644
index 0000000..b6c5f0a
--- /dev/null
+++ b/fe/index.html
@@ -0,0 +1,13 @@
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7 <title>Vite + Svelte + TS</title>
8 </head>
9 <body>
10 <div id="app"></div>
11 <script type="module" src="/src/main.ts"></script>
12 </body>
13</html>
diff --git a/fe/package-lock.json b/fe/package-lock.json
new file mode 100644
index 0000000..2c4146a
--- /dev/null
+++ b/fe/package-lock.json
@@ -0,0 +1,1772 @@
1{
2 "name": "fe",
3 "version": "0.0.0",
4 "lockfileVersion": 3,
5 "requires": true,
6 "packages": {
7 "": {
8 "name": "fe",
9 "version": "0.0.0",
10 "devDependencies": {
11 "@sveltejs/vite-plugin-svelte": "^3.0.2",
12 "@tsconfig/svelte": "^5.0.2",
13 "svelte": "^4.2.10",
14 "svelte-check": "^3.6.3",
15 "tslib": "^2.6.2",
16 "typescript": "^5.2.2",
17 "vite": "^5.1.0"
18 }
19 },
20 "node_modules/@ampproject/remapping": {
21 "version": "2.2.1",
22 "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
23 "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
24 "dev": true,
25 "dependencies": {
26 "@jridgewell/gen-mapping": "^0.3.0",
27 "@jridgewell/trace-mapping": "^0.3.9"
28 },
29 "engines": {
30 "node": ">=6.0.0"
31 }
32 },
33 "node_modules/@esbuild/aix-ppc64": {
34 "version": "0.19.12",
35 "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
36 "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==",
37 "cpu": [
38 "ppc64"
39 ],
40 "dev": true,
41 "optional": true,
42 "os": [
43 "aix"
44 ],
45 "engines": {
46 "node": ">=12"
47 }
48 },
49 "node_modules/@esbuild/android-arm": {
50 "version": "0.19.12",
51 "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz",
52 "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==",
53 "cpu": [
54 "arm"
55 ],
56 "dev": true,
57 "optional": true,
58 "os": [
59 "android"
60 ],
61 "engines": {
62 "node": ">=12"
63 }
64 },
65 "node_modules/@esbuild/android-arm64": {
66 "version": "0.19.12",
67 "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz",
68 "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==",
69 "cpu": [
70 "arm64"
71 ],
72 "dev": true,
73 "optional": true,
74 "os": [
75 "android"
76 ],
77 "engines": {
78 "node": ">=12"
79 }
80 },
81 "node_modules/@esbuild/android-x64": {
82 "version": "0.19.12",
83 "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz",
84 "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==",
85 "cpu": [
86 "x64"
87 ],
88 "dev": true,
89 "optional": true,
90 "os": [
91 "android"
92 ],
93 "engines": {
94 "node": ">=12"
95 }
96 },
97 "node_modules/@esbuild/darwin-arm64": {
98 "version": "0.19.12",
99 "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz",
100 "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==",
101 "cpu": [
102 "arm64"
103 ],
104 "dev": true,
105 "optional": true,
106 "os": [
107 "darwin"
108 ],
109 "engines": {
110 "node": ">=12"
111 }
112 },
113 "node_modules/@esbuild/darwin-x64": {
114 "version": "0.19.12",
115 "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz",
116 "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==",
117 "cpu": [
118 "x64"
119 ],
120 "dev": true,
121 "optional": true,
122 "os": [
123 "darwin"
124 ],
125 "engines": {
126 "node": ">=12"
127 }
128 },
129 "node_modules/@esbuild/freebsd-arm64": {
130 "version": "0.19.12",
131 "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz",
132 "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==",
133 "cpu": [
134 "arm64"
135 ],
136 "dev": true,
137 "optional": true,
138 "os": [
139 "freebsd"
140 ],
141 "engines": {
142 "node": ">=12"
143 }
144 },
145 "node_modules/@esbuild/freebsd-x64": {
146 "version": "0.19.12",
147 "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz",
148 "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==",
149 "cpu": [
150 "x64"
151 ],
152 "dev": true,
153 "optional": true,
154 "os": [
155 "freebsd"
156 ],
157 "engines": {
158 "node": ">=12"
159 }
160 },
161 "node_modules/@esbuild/linux-arm": {
162 "version": "0.19.12",
163 "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz",
164 "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==",
165 "cpu": [
166 "arm"
167 ],
168 "dev": true,
169 "optional": true,
170 "os": [
171 "linux"
172 ],
173 "engines": {
174 "node": ">=12"
175 }
176 },
177 "node_modules/@esbuild/linux-arm64": {
178 "version": "0.19.12",
179 "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz",
180 "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==",
181 "cpu": [
182 "arm64"
183 ],
184 "dev": true,
185 "optional": true,
186 "os": [
187 "linux"
188 ],
189 "engines": {
190 "node": ">=12"
191 }
192 },
193 "node_modules/@esbuild/linux-ia32": {
194 "version": "0.19.12",
195 "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz",
196 "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==",
197 "cpu": [
198 "ia32"
199 ],
200 "dev": true,
201 "optional": true,
202 "os": [
203 "linux"
204 ],
205 "engines": {
206 "node": ">=12"
207 }
208 },
209 "node_modules/@esbuild/linux-loong64": {
210 "version": "0.19.12",
211 "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz",
212 "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==",
213 "cpu": [
214 "loong64"
215 ],
216 "dev": true,
217 "optional": true,
218 "os": [
219 "linux"
220 ],
221 "engines": {
222 "node": ">=12"
223 }
224 },
225 "node_modules/@esbuild/linux-mips64el": {
226 "version": "0.19.12",
227 "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz",
228 "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==",
229 "cpu": [
230 "mips64el"
231 ],
232 "dev": true,
233 "optional": true,
234 "os": [
235 "linux"
236 ],
237 "engines": {
238 "node": ">=12"
239 }
240 },
241 "node_modules/@esbuild/linux-ppc64": {
242 "version": "0.19.12",
243 "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz",
244 "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==",
245 "cpu": [
246 "ppc64"
247 ],
248 "dev": true,
249 "optional": true,
250 "os": [
251 "linux"
252 ],
253 "engines": {
254 "node": ">=12"
255 }
256 },
257 "node_modules/@esbuild/linux-riscv64": {
258 "version": "0.19.12",
259 "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz",
260 "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==",
261 "cpu": [
262 "riscv64"
263 ],
264 "dev": true,
265 "optional": true,
266 "os": [
267 "linux"
268 ],
269 "engines": {
270 "node": ">=12"
271 }
272 },
273 "node_modules/@esbuild/linux-s390x": {
274 "version": "0.19.12",
275 "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz",
276 "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==",
277 "cpu": [
278 "s390x"
279 ],
280 "dev": true,
281 "optional": true,
282 "os": [
283 "linux"
284 ],
285 "engines": {
286 "node": ">=12"
287 }
288 },
289 "node_modules/@esbuild/linux-x64": {
290 "version": "0.19.12",
291 "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz",
292 "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==",
293 "cpu": [
294 "x64"
295 ],
296 "dev": true,
297 "optional": true,
298 "os": [
299 "linux"
300 ],
301 "engines": {
302 "node": ">=12"
303 }
304 },
305 "node_modules/@esbuild/netbsd-x64": {
306 "version": "0.19.12",
307 "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz",
308 "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==",
309 "cpu": [
310 "x64"
311 ],
312 "dev": true,
313 "optional": true,
314 "os": [
315 "netbsd"
316 ],
317 "engines": {
318 "node": ">=12"
319 }
320 },
321 "node_modules/@esbuild/openbsd-x64": {
322 "version": "0.19.12",
323 "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz",
324 "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==",
325 "cpu": [
326 "x64"
327 ],
328 "dev": true,
329 "optional": true,
330 "os": [
331 "openbsd"
332 ],
333 "engines": {
334 "node": ">=12"
335 }
336 },
337 "node_modules/@esbuild/sunos-x64": {
338 "version": "0.19.12",
339 "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz",
340 "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==",
341 "cpu": [
342 "x64"
343 ],
344 "dev": true,
345 "optional": true,
346 "os": [
347 "sunos"
348 ],
349 "engines": {
350 "node": ">=12"
351 }
352 },
353 "node_modules/@esbuild/win32-arm64": {
354 "version": "0.19.12",
355 "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz",
356 "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==",
357 "cpu": [
358 "arm64"
359 ],
360 "dev": true,
361 "optional": true,
362 "os": [
363 "win32"
364 ],
365 "engines": {
366 "node": ">=12"
367 }
368 },
369 "node_modules/@esbuild/win32-ia32": {
370 "version": "0.19.12",
371 "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz",
372 "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==",
373 "cpu": [
374 "ia32"
375 ],
376 "dev": true,
377 "optional": true,
378 "os": [
379 "win32"
380 ],
381 "engines": {
382 "node": ">=12"
383 }
384 },
385 "node_modules/@esbuild/win32-x64": {
386 "version": "0.19.12",
387 "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz",
388 "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==",
389 "cpu": [
390 "x64"
391 ],
392 "dev": true,
393 "optional": true,
394 "os": [
395 "win32"
396 ],
397 "engines": {
398 "node": ">=12"
399 }
400 },
401 "node_modules/@jridgewell/gen-mapping": {
402 "version": "0.3.3",
403 "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
404 "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
405 "dev": true,
406 "dependencies": {
407 "@jridgewell/set-array": "^1.0.1",
408 "@jridgewell/sourcemap-codec": "^1.4.10",
409 "@jridgewell/trace-mapping": "^0.3.9"
410 },
411 "engines": {
412 "node": ">=6.0.0"
413 }
414 },
415 "node_modules/@jridgewell/resolve-uri": {
416 "version": "3.1.2",
417 "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
418 "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
419 "dev": true,
420 "engines": {
421 "node": ">=6.0.0"
422 }
423 },
424 "node_modules/@jridgewell/set-array": {
425 "version": "1.1.2",
426 "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
427 "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
428 "dev": true,
429 "engines": {
430 "node": ">=6.0.0"
431 }
432 },
433 "node_modules/@jridgewell/sourcemap-codec": {
434 "version": "1.4.15",
435 "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
436 "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
437 "dev": true
438 },
439 "node_modules/@jridgewell/trace-mapping": {
440 "version": "0.3.22",
441 "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz",
442 "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==",
443 "dev": true,
444 "dependencies": {
445 "@jridgewell/resolve-uri": "^3.1.0",
446 "@jridgewell/sourcemap-codec": "^1.4.14"
447 }
448 },
449 "node_modules/@nodelib/fs.scandir": {
450 "version": "2.1.5",
451 "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
452 "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
453 "dev": true,
454 "dependencies": {
455 "@nodelib/fs.stat": "2.0.5",
456 "run-parallel": "^1.1.9"
457 },
458 "engines": {
459 "node": ">= 8"
460 }
461 },
462 "node_modules/@nodelib/fs.stat": {
463 "version": "2.0.5",
464 "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
465 "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
466 "dev": true,
467 "engines": {
468 "node": ">= 8"
469 }
470 },
471 "node_modules/@nodelib/fs.walk": {
472 "version": "1.2.8",
473 "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
474 "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
475 "dev": true,
476 "dependencies": {
477 "@nodelib/fs.scandir": "2.1.5",
478 "fastq": "^1.6.0"
479 },
480 "engines": {
481 "node": ">= 8"
482 }
483 },
484 "node_modules/@rollup/rollup-android-arm-eabi": {
485 "version": "4.12.0",
486 "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.12.0.tgz",
487 "integrity": "sha512-+ac02NL/2TCKRrJu2wffk1kZ+RyqxVUlbjSagNgPm94frxtr+XDL12E5Ll1enWskLrtrZ2r8L3wED1orIibV/w==",
488 "cpu": [
489 "arm"
490 ],
491 "dev": true,
492 "optional": true,
493 "os": [
494 "android"
495 ]
496 },
497 "node_modules/@rollup/rollup-android-arm64": {
498 "version": "4.12.0",
499 "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.12.0.tgz",
500 "integrity": "sha512-OBqcX2BMe6nvjQ0Nyp7cC90cnumt8PXmO7Dp3gfAju/6YwG0Tj74z1vKrfRz7qAv23nBcYM8BCbhrsWqO7PzQQ==",
501 "cpu": [
502 "arm64"
503 ],
504 "dev": true,
505 "optional": true,
506 "os": [
507 "android"
508 ]
509 },
510 "node_modules/@rollup/rollup-darwin-arm64": {
511 "version": "4.12.0",
512 "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.12.0.tgz",
513 "integrity": "sha512-X64tZd8dRE/QTrBIEs63kaOBG0b5GVEd3ccoLtyf6IdXtHdh8h+I56C2yC3PtC9Ucnv0CpNFJLqKFVgCYe0lOQ==",
514 "cpu": [
515 "arm64"
516 ],
517 "dev": true,
518 "optional": true,
519 "os": [
520 "darwin"
521 ]
522 },
523 "node_modules/@rollup/rollup-darwin-x64": {
524 "version": "4.12.0",
525 "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.12.0.tgz",
526 "integrity": "sha512-cc71KUZoVbUJmGP2cOuiZ9HSOP14AzBAThn3OU+9LcA1+IUqswJyR1cAJj3Mg55HbjZP6OLAIscbQsQLrpgTOg==",
527 "cpu": [
528 "x64"
529 ],
530 "dev": true,
531 "optional": true,
532 "os": [
533 "darwin"
534 ]
535 },
536 "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
537 "version": "4.12.0",
538 "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.12.0.tgz",
539 "integrity": "sha512-a6w/Y3hyyO6GlpKL2xJ4IOh/7d+APaqLYdMf86xnczU3nurFTaVN9s9jOXQg97BE4nYm/7Ga51rjec5nfRdrvA==",
540 "cpu": [
541 "arm"
542 ],
543 "dev": true,
544 "optional": true,
545 "os": [
546 "linux"
547 ]
548 },
549 "node_modules/@rollup/rollup-linux-arm64-gnu": {
550 "version": "4.12.0",
551 "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.12.0.tgz",
552 "integrity": "sha512-0fZBq27b+D7Ar5CQMofVN8sggOVhEtzFUwOwPppQt0k+VR+7UHMZZY4y+64WJ06XOhBTKXtQB/Sv0NwQMXyNAA==",
553 "cpu": [
554 "arm64"
555 ],
556 "dev": true,
557 "optional": true,
558 "os": [
559 "linux"
560 ]
561 },
562 "node_modules/@rollup/rollup-linux-arm64-musl": {
563 "version": "4.12.0",
564 "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.12.0.tgz",
565 "integrity": "sha512-eTvzUS3hhhlgeAv6bfigekzWZjaEX9xP9HhxB0Dvrdbkk5w/b+1Sxct2ZuDxNJKzsRStSq1EaEkVSEe7A7ipgQ==",
566 "cpu": [
567 "arm64"
568 ],
569 "dev": true,
570 "optional": true,
571 "os": [
572 "linux"
573 ]
574 },
575 "node_modules/@rollup/rollup-linux-riscv64-gnu": {
576 "version": "4.12.0",
577 "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.12.0.tgz",
578 "integrity": "sha512-ix+qAB9qmrCRiaO71VFfY8rkiAZJL8zQRXveS27HS+pKdjwUfEhqo2+YF2oI+H/22Xsiski+qqwIBxVewLK7sw==",
579 "cpu": [
580 "riscv64"
581 ],
582 "dev": true,
583 "optional": true,
584 "os": [
585 "linux"
586 ]
587 },
588 "node_modules/@rollup/rollup-linux-x64-gnu": {
589 "version": "4.12.0",
590 "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.12.0.tgz",
591 "integrity": "sha512-TenQhZVOtw/3qKOPa7d+QgkeM6xY0LtwzR8OplmyL5LrgTWIXpTQg2Q2ycBf8jm+SFW2Wt/DTn1gf7nFp3ssVA==",
592 "cpu": [
593 "x64"
594 ],
595 "dev": true,
596 "optional": true,
597 "os": [
598 "linux"
599 ]
600 },
601 "node_modules/@rollup/rollup-linux-x64-musl": {
602 "version": "4.12.0",
603 "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.12.0.tgz",
604 "integrity": "sha512-LfFdRhNnW0zdMvdCb5FNuWlls2WbbSridJvxOvYWgSBOYZtgBfW9UGNJG//rwMqTX1xQE9BAodvMH9tAusKDUw==",
605 "cpu": [
606 "x64"
607 ],
608 "dev": true,
609 "optional": true,
610 "os": [
611 "linux"
612 ]
613 },
614 "node_modules/@rollup/rollup-win32-arm64-msvc": {
615 "version": "4.12.0",
616 "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.12.0.tgz",
617 "integrity": "sha512-JPDxovheWNp6d7AHCgsUlkuCKvtu3RB55iNEkaQcf0ttsDU/JZF+iQnYcQJSk/7PtT4mjjVG8N1kpwnI9SLYaw==",
618 "cpu": [
619 "arm64"
620 ],
621 "dev": true,
622 "optional": true,
623 "os": [
624 "win32"
625 ]
626 },
627 "node_modules/@rollup/rollup-win32-ia32-msvc": {
628 "version": "4.12.0",
629 "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.12.0.tgz",
630 "integrity": "sha512-fjtuvMWRGJn1oZacG8IPnzIV6GF2/XG+h71FKn76OYFqySXInJtseAqdprVTDTyqPxQOG9Exak5/E9Z3+EJ8ZA==",
631 "cpu": [
632 "ia32"
633 ],
634 "dev": true,
635 "optional": true,
636 "os": [
637 "win32"
638 ]
639 },
640 "node_modules/@rollup/rollup-win32-x64-msvc": {
641 "version": "4.12.0",
642 "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.12.0.tgz",
643 "integrity": "sha512-ZYmr5mS2wd4Dew/JjT0Fqi2NPB/ZhZ2VvPp7SmvPZb4Y1CG/LRcS6tcRo2cYU7zLK5A7cdbhWnnWmUjoI4qapg==",
644 "cpu": [
645 "x64"
646 ],
647 "dev": true,
648 "optional": true,
649 "os": [
650 "win32"
651 ]
652 },
653 "node_modules/@sveltejs/vite-plugin-svelte": {
654 "version": "3.0.2",
655 "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-3.0.2.tgz",
656 "integrity": "sha512-MpmF/cju2HqUls50WyTHQBZUV3ovV/Uk8k66AN2gwHogNAG8wnW8xtZDhzNBsFJJuvmq1qnzA5kE7YfMJNFv2Q==",
657 "dev": true,
658 "dependencies": {
659 "@sveltejs/vite-plugin-svelte-inspector": "^2.0.0",
660 "debug": "^4.3.4",
661 "deepmerge": "^4.3.1",
662 "kleur": "^4.1.5",
663 "magic-string": "^0.30.5",
664 "svelte-hmr": "^0.15.3",
665 "vitefu": "^0.2.5"
666 },
667 "engines": {
668 "node": "^18.0.0 || >=20"
669 },
670 "peerDependencies": {
671 "svelte": "^4.0.0 || ^5.0.0-next.0",
672 "vite": "^5.0.0"
673 }
674 },
675 "node_modules/@sveltejs/vite-plugin-svelte-inspector": {
676 "version": "2.0.0",
677 "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte-inspector/-/vite-plugin-svelte-inspector-2.0.0.tgz",
678 "integrity": "sha512-gjr9ZFg1BSlIpfZ4PRewigrvYmHWbDrq2uvvPB1AmTWKuM+dI1JXQSUu2pIrYLb/QncyiIGkFDFKTwJ0XqQZZg==",
679 "dev": true,
680 "dependencies": {
681 "debug": "^4.3.4"
682 },
683 "engines": {
684 "node": "^18.0.0 || >=20"
685 },
686 "peerDependencies": {
687 "@sveltejs/vite-plugin-svelte": "^3.0.0",
688 "svelte": "^4.0.0 || ^5.0.0-next.0",
689 "vite": "^5.0.0"
690 }
691 },
692 "node_modules/@tsconfig/svelte": {
693 "version": "5.0.2",
694 "resolved": "https://registry.npmjs.org/@tsconfig/svelte/-/svelte-5.0.2.tgz",
695 "integrity": "sha512-BRbo1fOtyVbhfLyuCWw6wAWp+U8UQle+ZXu84MYYWzYSEB28dyfnRBIE99eoG+qdAC0po6L2ScIEivcT07UaMA==",
696 "dev": true
697 },
698 "node_modules/@types/estree": {
699 "version": "1.0.5",
700 "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
701 "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
702 "dev": true
703 },
704 "node_modules/@types/pug": {
705 "version": "2.0.10",
706 "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz",
707 "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
708 "dev": true
709 },
710 "node_modules/acorn": {
711 "version": "8.11.3",
712 "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
713 "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
714 "dev": true,
715 "bin": {
716 "acorn": "bin/acorn"
717 },
718 "engines": {
719 "node": ">=0.4.0"
720 }
721 },
722 "node_modules/anymatch": {
723 "version": "3.1.3",
724 "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
725 "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
726 "dev": true,
727 "dependencies": {
728 "normalize-path": "^3.0.0",
729 "picomatch": "^2.0.4"
730 },
731 "engines": {
732 "node": ">= 8"
733 }
734 },
735 "node_modules/aria-query": {
736 "version": "5.3.0",
737 "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
738 "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
739 "dev": true,
740 "dependencies": {
741 "dequal": "^2.0.3"
742 }
743 },
744 "node_modules/axobject-query": {
745 "version": "4.0.0",
746 "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz",
747 "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==",
748 "dev": true,
749 "dependencies": {
750 "dequal": "^2.0.3"
751 }
752 },
753 "node_modules/balanced-match": {
754 "version": "1.0.2",
755 "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
756 "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
757 "dev": true
758 },
759 "node_modules/binary-extensions": {
760 "version": "2.2.0",
761 "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
762 "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
763 "dev": true,
764 "engines": {
765 "node": ">=8"
766 }
767 },
768 "node_modules/brace-expansion": {
769 "version": "1.1.11",
770 "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
771 "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
772 "dev": true,
773 "dependencies": {
774 "balanced-match": "^1.0.0",
775 "concat-map": "0.0.1"
776 }
777 },
778 "node_modules/braces": {
779 "version": "3.0.2",
780 "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
781 "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
782 "dev": true,
783 "dependencies": {
784 "fill-range": "^7.0.1"
785 },
786 "engines": {
787 "node": ">=8"
788 }
789 },
790 "node_modules/buffer-crc32": {
791 "version": "0.2.13",
792 "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
793 "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
794 "dev": true,
795 "engines": {
796 "node": "*"
797 }
798 },
799 "node_modules/callsites": {
800 "version": "3.1.0",
801 "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
802 "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
803 "dev": true,
804 "engines": {
805 "node": ">=6"
806 }
807 },
808 "node_modules/chokidar": {
809 "version": "3.6.0",
810 "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
811 "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
812 "dev": true,
813 "dependencies": {
814 "anymatch": "~3.1.2",
815 "braces": "~3.0.2",
816 "glob-parent": "~5.1.2",
817 "is-binary-path": "~2.1.0",
818 "is-glob": "~4.0.1",
819 "normalize-path": "~3.0.0",
820 "readdirp": "~3.6.0"
821 },
822 "engines": {
823 "node": ">= 8.10.0"
824 },
825 "funding": {
826 "url": "https://paulmillr.com/funding/"
827 },
828 "optionalDependencies": {
829 "fsevents": "~2.3.2"
830 }
831 },
832 "node_modules/code-red": {
833 "version": "1.0.4",
834 "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz",
835 "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==",
836 "dev": true,
837 "dependencies": {
838 "@jridgewell/sourcemap-codec": "^1.4.15",
839 "@types/estree": "^1.0.1",
840 "acorn": "^8.10.0",
841 "estree-walker": "^3.0.3",
842 "periscopic": "^3.1.0"
843 }
844 },
845 "node_modules/concat-map": {
846 "version": "0.0.1",
847 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
848 "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
849 "dev": true
850 },
851 "node_modules/css-tree": {
852 "version": "2.3.1",
853 "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
854 "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
855 "dev": true,
856 "dependencies": {
857 "mdn-data": "2.0.30",
858 "source-map-js": "^1.0.1"
859 },
860 "engines": {
861 "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
862 }
863 },
864 "node_modules/debug": {
865 "version": "4.3.4",
866 "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
867 "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
868 "dev": true,
869 "dependencies": {
870 "ms": "2.1.2"
871 },
872 "engines": {
873 "node": ">=6.0"
874 },
875 "peerDependenciesMeta": {
876 "supports-color": {
877 "optional": true
878 }
879 }
880 },
881 "node_modules/deepmerge": {
882 "version": "4.3.1",
883 "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
884 "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
885 "dev": true,
886 "engines": {
887 "node": ">=0.10.0"
888 }
889 },
890 "node_modules/dequal": {
891 "version": "2.0.3",
892 "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
893 "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
894 "dev": true,
895 "engines": {
896 "node": ">=6"
897 }
898 },
899 "node_modules/detect-indent": {
900 "version": "6.1.0",
901 "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz",
902 "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==",
903 "dev": true,
904 "engines": {
905 "node": ">=8"
906 }
907 },
908 "node_modules/es6-promise": {
909 "version": "3.3.1",
910 "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
911 "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==",
912 "dev": true
913 },
914 "node_modules/esbuild": {
915 "version": "0.19.12",
916 "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz",
917 "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==",
918 "dev": true,
919 "hasInstallScript": true,
920 "bin": {
921 "esbuild": "bin/esbuild"
922 },
923 "engines": {
924 "node": ">=12"
925 },
926 "optionalDependencies": {
927 "@esbuild/aix-ppc64": "0.19.12",
928 "@esbuild/android-arm": "0.19.12",
929 "@esbuild/android-arm64": "0.19.12",
930 "@esbuild/android-x64": "0.19.12",
931 "@esbuild/darwin-arm64": "0.19.12",
932 "@esbuild/darwin-x64": "0.19.12",
933 "@esbuild/freebsd-arm64": "0.19.12",
934 "@esbuild/freebsd-x64": "0.19.12",
935 "@esbuild/linux-arm": "0.19.12",
936 "@esbuild/linux-arm64": "0.19.12",
937 "@esbuild/linux-ia32": "0.19.12",
938 "@esbuild/linux-loong64": "0.19.12",
939 "@esbuild/linux-mips64el": "0.19.12",
940 "@esbuild/linux-ppc64": "0.19.12",
941 "@esbuild/linux-riscv64": "0.19.12",
942 "@esbuild/linux-s390x": "0.19.12",
943 "@esbuild/linux-x64": "0.19.12",
944 "@esbuild/netbsd-x64": "0.19.12",
945 "@esbuild/openbsd-x64": "0.19.12",
946 "@esbuild/sunos-x64": "0.19.12",
947 "@esbuild/win32-arm64": "0.19.12",
948 "@esbuild/win32-ia32": "0.19.12",
949 "@esbuild/win32-x64": "0.19.12"
950 }
951 },
952 "node_modules/estree-walker": {
953 "version": "3.0.3",
954 "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
955 "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
956 "dev": true,
957 "dependencies": {
958 "@types/estree": "^1.0.0"
959 }
960 },
961 "node_modules/fast-glob": {
962 "version": "3.3.2",
963 "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
964 "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
965 "dev": true,
966 "dependencies": {
967 "@nodelib/fs.stat": "^2.0.2",
968 "@nodelib/fs.walk": "^1.2.3",
969 "glob-parent": "^5.1.2",
970 "merge2": "^1.3.0",
971 "micromatch": "^4.0.4"
972 },
973 "engines": {
974 "node": ">=8.6.0"
975 }
976 },
977 "node_modules/fastq": {
978 "version": "1.17.1",
979 "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
980 "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
981 "dev": true,
982 "dependencies": {
983 "reusify": "^1.0.4"
984 }
985 },
986 "node_modules/fill-range": {
987 "version": "7.0.1",
988 "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
989 "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
990 "dev": true,
991 "dependencies": {
992 "to-regex-range": "^5.0.1"
993 },
994 "engines": {
995 "node": ">=8"
996 }
997 },
998 "node_modules/fs.realpath": {
999 "version": "1.0.0",
1000 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1001 "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
1002 "dev": true
1003 },
1004 "node_modules/fsevents": {
1005 "version": "2.3.3",
1006 "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1007 "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1008 "dev": true,
1009 "hasInstallScript": true,
1010 "optional": true,
1011 "os": [
1012 "darwin"
1013 ],
1014 "engines": {
1015 "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1016 }
1017 },
1018 "node_modules/glob": {
1019 "version": "7.2.3",
1020 "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
1021 "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
1022 "dev": true,
1023 "dependencies": {
1024 "fs.realpath": "^1.0.0",
1025 "inflight": "^1.0.4",
1026 "inherits": "2",
1027 "minimatch": "^3.1.1",
1028 "once": "^1.3.0",
1029 "path-is-absolute": "^1.0.0"
1030 },
1031 "engines": {
1032 "node": "*"
1033 },
1034 "funding": {
1035 "url": "https://github.com/sponsors/isaacs"
1036 }
1037 },
1038 "node_modules/glob-parent": {
1039 "version": "5.1.2",
1040 "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
1041 "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
1042 "dev": true,
1043 "dependencies": {
1044 "is-glob": "^4.0.1"
1045 },
1046 "engines": {
1047 "node": ">= 6"
1048 }
1049 },
1050 "node_modules/graceful-fs": {
1051 "version": "4.2.11",
1052 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
1053 "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
1054 "dev": true
1055 },
1056 "node_modules/import-fresh": {
1057 "version": "3.3.0",
1058 "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
1059 "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
1060 "dev": true,
1061 "dependencies": {
1062 "parent-module": "^1.0.0",
1063 "resolve-from": "^4.0.0"
1064 },
1065 "engines": {
1066 "node": ">=6"
1067 },
1068 "funding": {
1069 "url": "https://github.com/sponsors/sindresorhus"
1070 }
1071 },
1072 "node_modules/inflight": {
1073 "version": "1.0.6",
1074 "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1075 "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
1076 "dev": true,
1077 "dependencies": {
1078 "once": "^1.3.0",
1079 "wrappy": "1"
1080 }
1081 },
1082 "node_modules/inherits": {
1083 "version": "2.0.4",
1084 "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1085 "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1086 "dev": true
1087 },
1088 "node_modules/is-binary-path": {
1089 "version": "2.1.0",
1090 "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
1091 "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
1092 "dev": true,
1093 "dependencies": {
1094 "binary-extensions": "^2.0.0"
1095 },
1096 "engines": {
1097 "node": ">=8"
1098 }
1099 },
1100 "node_modules/is-extglob": {
1101 "version": "2.1.1",
1102 "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1103 "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
1104 "dev": true,
1105 "engines": {
1106 "node": ">=0.10.0"
1107 }
1108 },
1109 "node_modules/is-glob": {
1110 "version": "4.0.3",
1111 "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
1112 "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
1113 "dev": true,
1114 "dependencies": {
1115 "is-extglob": "^2.1.1"
1116 },
1117 "engines": {
1118 "node": ">=0.10.0"
1119 }
1120 },
1121 "node_modules/is-number": {
1122 "version": "7.0.0",
1123 "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
1124 "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1125 "dev": true,
1126 "engines": {
1127 "node": ">=0.12.0"
1128 }
1129 },
1130 "node_modules/is-reference": {
1131 "version": "3.0.2",
1132 "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz",
1133 "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==",
1134 "dev": true,
1135 "dependencies": {
1136 "@types/estree": "*"
1137 }
1138 },
1139 "node_modules/kleur": {
1140 "version": "4.1.5",
1141 "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
1142 "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
1143 "dev": true,
1144 "engines": {
1145 "node": ">=6"
1146 }
1147 },
1148 "node_modules/locate-character": {
1149 "version": "3.0.0",
1150 "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
1151 "integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
1152 "dev": true
1153 },
1154 "node_modules/magic-string": {
1155 "version": "0.30.7",
1156 "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz",
1157 "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==",
1158 "dev": true,
1159 "dependencies": {
1160 "@jridgewell/sourcemap-codec": "^1.4.15"
1161 },
1162 "engines": {
1163 "node": ">=12"
1164 }
1165 },
1166 "node_modules/mdn-data": {
1167 "version": "2.0.30",
1168 "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
1169 "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
1170 "dev": true
1171 },
1172 "node_modules/merge2": {
1173 "version": "1.4.1",
1174 "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
1175 "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
1176 "dev": true,
1177 "engines": {
1178 "node": ">= 8"
1179 }
1180 },
1181 "node_modules/micromatch": {
1182 "version": "4.0.5",
1183 "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
1184 "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
1185 "dev": true,
1186 "dependencies": {
1187 "braces": "^3.0.2",
1188 "picomatch": "^2.3.1"
1189 },
1190 "engines": {
1191 "node": ">=8.6"
1192 }
1193 },
1194 "node_modules/min-indent": {
1195 "version": "1.0.1",
1196 "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
1197 "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
1198 "dev": true,
1199 "engines": {
1200 "node": ">=4"
1201 }
1202 },
1203 "node_modules/minimatch": {
1204 "version": "3.1.2",
1205 "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
1206 "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
1207 "dev": true,
1208 "dependencies": {
1209 "brace-expansion": "^1.1.7"
1210 },
1211 "engines": {
1212 "node": "*"
1213 }
1214 },
1215 "node_modules/minimist": {
1216 "version": "1.2.8",
1217 "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
1218 "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
1219 "dev": true,
1220 "funding": {
1221 "url": "https://github.com/sponsors/ljharb"
1222 }
1223 },
1224 "node_modules/mkdirp": {
1225 "version": "0.5.6",
1226 "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
1227 "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
1228 "dev": true,
1229 "dependencies": {
1230 "minimist": "^1.2.6"
1231 },
1232 "bin": {
1233 "mkdirp": "bin/cmd.js"
1234 }
1235 },
1236 "node_modules/mri": {
1237 "version": "1.2.0",
1238 "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
1239 "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
1240 "dev": true,
1241 "engines": {
1242 "node": ">=4"
1243 }
1244 },
1245 "node_modules/ms": {
1246 "version": "2.1.2",
1247 "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1248 "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1249 "dev": true
1250 },
1251 "node_modules/nanoid": {
1252 "version": "3.3.7",
1253 "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
1254 "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
1255 "dev": true,
1256 "funding": [
1257 {
1258 "type": "github",
1259 "url": "https://github.com/sponsors/ai"
1260 }
1261 ],
1262 "bin": {
1263 "nanoid": "bin/nanoid.cjs"
1264 },
1265 "engines": {
1266 "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1267 }
1268 },
1269 "node_modules/normalize-path": {
1270 "version": "3.0.0",
1271 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
1272 "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
1273 "dev": true,
1274 "engines": {
1275 "node": ">=0.10.0"
1276 }
1277 },
1278 "node_modules/once": {
1279 "version": "1.4.0",
1280 "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
1281 "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
1282 "dev": true,
1283 "dependencies": {
1284 "wrappy": "1"
1285 }
1286 },
1287 "node_modules/parent-module": {
1288 "version": "1.0.1",
1289 "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
1290 "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
1291 "dev": true,
1292 "dependencies": {
1293 "callsites": "^3.0.0"
1294 },
1295 "engines": {
1296 "node": ">=6"
1297 }
1298 },
1299 "node_modules/path-is-absolute": {
1300 "version": "1.0.1",
1301 "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
1302 "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
1303 "dev": true,
1304 "engines": {
1305 "node": ">=0.10.0"
1306 }
1307 },
1308 "node_modules/periscopic": {
1309 "version": "3.1.0",
1310 "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
1311 "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==",
1312 "dev": true,
1313 "dependencies": {
1314 "@types/estree": "^1.0.0",
1315 "estree-walker": "^3.0.0",
1316 "is-reference": "^3.0.0"
1317 }
1318 },
1319 "node_modules/picocolors": {
1320 "version": "1.0.0",
1321 "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
1322 "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
1323 "dev": true
1324 },
1325 "node_modules/picomatch": {
1326 "version": "2.3.1",
1327 "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
1328 "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
1329 "dev": true,
1330 "engines": {
1331 "node": ">=8.6"
1332 },
1333 "funding": {
1334 "url": "https://github.com/sponsors/jonschlinkert"
1335 }
1336 },
1337 "node_modules/postcss": {
1338 "version": "8.4.35",
1339 "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
1340 "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==",
1341 "dev": true,
1342 "funding": [
1343 {
1344 "type": "opencollective",
1345 "url": "https://opencollective.com/postcss/"
1346 },
1347 {
1348 "type": "tidelift",
1349 "url": "https://tidelift.com/funding/github/npm/postcss"
1350 },
1351 {
1352 "type": "github",
1353 "url": "https://github.com/sponsors/ai"
1354 }
1355 ],
1356 "dependencies": {
1357 "nanoid": "^3.3.7",
1358 "picocolors": "^1.0.0",
1359 "source-map-js": "^1.0.2"
1360 },
1361 "engines": {
1362 "node": "^10 || ^12 || >=14"
1363 }
1364 },
1365 "node_modules/queue-microtask": {
1366 "version": "1.2.3",
1367 "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
1368 "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
1369 "dev": true,
1370 "funding": [
1371 {
1372 "type": "github",
1373 "url": "https://github.com/sponsors/feross"
1374 },
1375 {
1376 "type": "patreon",
1377 "url": "https://www.patreon.com/feross"
1378 },
1379 {
1380 "type": "consulting",
1381 "url": "https://feross.org/support"
1382 }
1383 ]
1384 },
1385 "node_modules/readdirp": {
1386 "version": "3.6.0",
1387 "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
1388 "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
1389 "dev": true,
1390 "dependencies": {
1391 "picomatch": "^2.2.1"
1392 },
1393 "engines": {
1394 "node": ">=8.10.0"
1395 }
1396 },
1397 "node_modules/resolve-from": {
1398 "version": "4.0.0",
1399 "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
1400 "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
1401 "dev": true,
1402 "engines": {
1403 "node": ">=4"
1404 }
1405 },
1406 "node_modules/reusify": {
1407 "version": "1.0.4",
1408 "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
1409 "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
1410 "dev": true,
1411 "engines": {
1412 "iojs": ">=1.0.0",
1413 "node": ">=0.10.0"
1414 }
1415 },
1416 "node_modules/rimraf": {
1417 "version": "2.7.1",
1418 "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
1419 "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
1420 "dev": true,
1421 "dependencies": {
1422 "glob": "^7.1.3"
1423 },
1424 "bin": {
1425 "rimraf": "bin.js"
1426 }
1427 },
1428 "node_modules/rollup": {
1429 "version": "4.12.0",
1430 "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.12.0.tgz",
1431 "integrity": "sha512-wz66wn4t1OHIJw3+XU7mJJQV/2NAfw5OAk6G6Hoo3zcvz/XOfQ52Vgi+AN4Uxoxi0KBBwk2g8zPrTDA4btSB/Q==",
1432 "dev": true,
1433 "dependencies": {
1434 "@types/estree": "1.0.5"
1435 },
1436 "bin": {
1437 "rollup": "dist/bin/rollup"
1438 },
1439 "engines": {
1440 "node": ">=18.0.0",
1441 "npm": ">=8.0.0"
1442 },
1443 "optionalDependencies": {
1444 "@rollup/rollup-android-arm-eabi": "4.12.0",
1445 "@rollup/rollup-android-arm64": "4.12.0",
1446 "@rollup/rollup-darwin-arm64": "4.12.0",
1447 "@rollup/rollup-darwin-x64": "4.12.0",
1448 "@rollup/rollup-linux-arm-gnueabihf": "4.12.0",
1449 "@rollup/rollup-linux-arm64-gnu": "4.12.0",
1450 "@rollup/rollup-linux-arm64-musl": "4.12.0",
1451 "@rollup/rollup-linux-riscv64-gnu": "4.12.0",
1452 "@rollup/rollup-linux-x64-gnu": "4.12.0",
1453 "@rollup/rollup-linux-x64-musl": "4.12.0",
1454 "@rollup/rollup-win32-arm64-msvc": "4.12.0",
1455 "@rollup/rollup-win32-ia32-msvc": "4.12.0",
1456 "@rollup/rollup-win32-x64-msvc": "4.12.0",
1457 "fsevents": "~2.3.2"
1458 }
1459 },
1460 "node_modules/run-parallel": {
1461 "version": "1.2.0",
1462 "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
1463 "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
1464 "dev": true,
1465 "funding": [
1466 {
1467 "type": "github",
1468 "url": "https://github.com/sponsors/feross"
1469 },
1470 {
1471 "type": "patreon",
1472 "url": "https://www.patreon.com/feross"
1473 },
1474 {
1475 "type": "consulting",
1476 "url": "https://feross.org/support"
1477 }
1478 ],
1479 "dependencies": {
1480 "queue-microtask": "^1.2.2"
1481 }
1482 },
1483 "node_modules/sade": {
1484 "version": "1.8.1",
1485 "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
1486 "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
1487 "dev": true,
1488 "dependencies": {
1489 "mri": "^1.1.0"
1490 },
1491 "engines": {
1492 "node": ">=6"
1493 }
1494 },
1495 "node_modules/sander": {
1496 "version": "0.5.1",
1497 "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz",
1498 "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==",
1499 "dev": true,
1500 "dependencies": {
1501 "es6-promise": "^3.1.2",
1502 "graceful-fs": "^4.1.3",
1503 "mkdirp": "^0.5.1",
1504 "rimraf": "^2.5.2"
1505 }
1506 },
1507 "node_modules/sorcery": {
1508 "version": "0.11.0",
1509 "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.11.0.tgz",
1510 "integrity": "sha512-J69LQ22xrQB1cIFJhPfgtLuI6BpWRiWu1Y3vSsIwK/eAScqJxd/+CJlUuHQRdX2C9NGFamq+KqNywGgaThwfHw==",
1511 "dev": true,
1512 "dependencies": {
1513 "@jridgewell/sourcemap-codec": "^1.4.14",
1514 "buffer-crc32": "^0.2.5",
1515 "minimist": "^1.2.0",
1516 "sander": "^0.5.0"
1517 },
1518 "bin": {
1519 "sorcery": "bin/sorcery"
1520 }
1521 },
1522 "node_modules/source-map-js": {
1523 "version": "1.0.2",
1524 "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
1525 "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
1526 "dev": true,
1527 "engines": {
1528 "node": ">=0.10.0"
1529 }
1530 },
1531 "node_modules/strip-indent": {
1532 "version": "3.0.0",
1533 "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
1534 "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
1535 "dev": true,
1536 "dependencies": {
1537 "min-indent": "^1.0.0"
1538 },
1539 "engines": {
1540 "node": ">=8"
1541 }
1542 },
1543 "node_modules/svelte": {
1544 "version": "4.2.11",
1545 "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.11.tgz",
1546 "integrity": "sha512-YIQk3J4X89wOLhjsqIW8tqY3JHPuBdtdOIkASP2PZeAMcSW9RsIjQzMesCrxOF3gdWYC0mKknlKF7OqmLM+Zqg==",
1547 "dev": true,
1548 "dependencies": {
1549 "@ampproject/remapping": "^2.2.1",
1550 "@jridgewell/sourcemap-codec": "^1.4.15",
1551 "@jridgewell/trace-mapping": "^0.3.18",
1552 "@types/estree": "^1.0.1",
1553 "acorn": "^8.9.0",
1554 "aria-query": "^5.3.0",
1555 "axobject-query": "^4.0.0",
1556 "code-red": "^1.0.3",
1557 "css-tree": "^2.3.1",
1558 "estree-walker": "^3.0.3",
1559 "is-reference": "^3.0.1",
1560 "locate-character": "^3.0.0",
1561 "magic-string": "^0.30.4",
1562 "periscopic": "^3.1.0"
1563 },
1564 "engines": {
1565 "node": ">=16"
1566 }
1567 },
1568 "node_modules/svelte-check": {
1569 "version": "3.6.4",
1570 "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.4.tgz",
1571 "integrity": "sha512-mY/dqucqm46p72M8yZmn81WPZx9mN6uuw8UVfR3ZKQeLxQg5HDGO3HHm5AZuWZPYNMLJ+TRMn+TeN53HfQ/vsw==",
1572 "dev": true,
1573 "dependencies": {
1574 "@jridgewell/trace-mapping": "^0.3.17",
1575 "chokidar": "^3.4.1",
1576 "fast-glob": "^3.2.7",
1577 "import-fresh": "^3.2.1",
1578 "picocolors": "^1.0.0",
1579 "sade": "^1.7.4",
1580 "svelte-preprocess": "^5.1.0",
1581 "typescript": "^5.0.3"
1582 },
1583 "bin": {
1584 "svelte-check": "bin/svelte-check"
1585 },
1586 "peerDependencies": {
1587 "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0"
1588 }
1589 },
1590 "node_modules/svelte-hmr": {
1591 "version": "0.15.3",
1592 "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz",
1593 "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==",
1594 "dev": true,
1595 "engines": {
1596 "node": "^12.20 || ^14.13.1 || >= 16"
1597 },
1598 "peerDependencies": {
1599 "svelte": "^3.19.0 || ^4.0.0"
1600 }
1601 },
1602 "node_modules/svelte-preprocess": {
1603 "version": "5.1.3",
1604 "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-5.1.3.tgz",
1605 "integrity": "sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==",
1606 "dev": true,
1607 "hasInstallScript": true,
1608 "dependencies": {
1609 "@types/pug": "^2.0.6",
1610 "detect-indent": "^6.1.0",
1611 "magic-string": "^0.30.5",
1612 "sorcery": "^0.11.0",
1613 "strip-indent": "^3.0.0"
1614 },
1615 "engines": {
1616 "node": ">= 16.0.0",
1617 "pnpm": "^8.0.0"
1618 },
1619 "peerDependencies": {
1620 "@babel/core": "^7.10.2",
1621 "coffeescript": "^2.5.1",
1622 "less": "^3.11.3 || ^4.0.0",
1623 "postcss": "^7 || ^8",
1624 "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0 || ^5.0.0",
1625 "pug": "^3.0.0",
1626 "sass": "^1.26.8",
1627 "stylus": "^0.55.0",
1628 "sugarss": "^2.0.0 || ^3.0.0 || ^4.0.0",
1629 "svelte": "^3.23.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0",
1630 "typescript": ">=3.9.5 || ^4.0.0 || ^5.0.0"
1631 },
1632 "peerDependenciesMeta": {
1633 "@babel/core": {
1634 "optional": true
1635 },
1636 "coffeescript": {
1637 "optional": true
1638 },
1639 "less": {
1640 "optional": true
1641 },
1642 "postcss": {
1643 "optional": true
1644 },
1645 "postcss-load-config": {
1646 "optional": true
1647 },
1648 "pug": {
1649 "optional": true
1650 },
1651 "sass": {
1652 "optional": true
1653 },
1654 "stylus": {
1655 "optional": true
1656 },
1657 "sugarss": {
1658 "optional": true
1659 },
1660 "typescript": {
1661 "optional": true
1662 }
1663 }
1664 },
1665 "node_modules/to-regex-range": {
1666 "version": "5.0.1",
1667 "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
1668 "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
1669 "dev": true,
1670 "dependencies": {
1671 "is-number": "^7.0.0"
1672 },
1673 "engines": {
1674 "node": ">=8.0"
1675 }
1676 },
1677 "node_modules/tslib": {
1678 "version": "2.6.2",
1679 "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
1680 "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
1681 "dev": true
1682 },
1683 "node_modules/typescript": {
1684 "version": "5.3.3",
1685 "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
1686 "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
1687 "dev": true,
1688 "bin": {
1689 "tsc": "bin/tsc",
1690 "tsserver": "bin/tsserver"
1691 },
1692 "engines": {
1693 "node": ">=14.17"
1694 }
1695 },
1696 "node_modules/vite": {
1697 "version": "5.1.3",
1698 "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.3.tgz",
1699 "integrity": "sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==",
1700 "dev": true,
1701 "dependencies": {
1702 "esbuild": "^0.19.3",
1703 "postcss": "^8.4.35",
1704 "rollup": "^4.2.0"
1705 },
1706 "bin": {
1707 "vite": "bin/vite.js"
1708 },
1709 "engines": {
1710 "node": "^18.0.0 || >=20.0.0"
1711 },
1712 "funding": {
1713 "url": "https://github.com/vitejs/vite?sponsor=1"
1714 },
1715 "optionalDependencies": {
1716 "fsevents": "~2.3.3"
1717 },
1718 "peerDependencies": {
1719 "@types/node": "^18.0.0 || >=20.0.0",
1720 "less": "*",
1721 "lightningcss": "^1.21.0",
1722 "sass": "*",
1723 "stylus": "*",
1724 "sugarss": "*",
1725 "terser": "^5.4.0"
1726 },
1727 "peerDependenciesMeta": {
1728 "@types/node": {
1729 "optional": true
1730 },
1731 "less": {
1732 "optional": true
1733 },
1734 "lightningcss": {
1735 "optional": true
1736 },
1737 "sass": {
1738 "optional": true
1739 },
1740 "stylus": {
1741 "optional": true
1742 },
1743 "sugarss": {
1744 "optional": true
1745 },
1746 "terser": {
1747 "optional": true
1748 }
1749 }
1750 },
1751 "node_modules/vitefu": {
1752 "version": "0.2.5",
1753 "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.5.tgz",
1754 "integrity": "sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==",
1755 "dev": true,
1756 "peerDependencies": {
1757 "vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
1758 },
1759 "peerDependenciesMeta": {
1760 "vite": {
1761 "optional": true
1762 }
1763 }
1764 },
1765 "node_modules/wrappy": {
1766 "version": "1.0.2",
1767 "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
1768 "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
1769 "dev": true
1770 }
1771 }
1772}
diff --git a/fe/package.json b/fe/package.json
new file mode 100644
index 0000000..6bc8619
--- /dev/null
+++ b/fe/package.json
@@ -0,0 +1,21 @@
1{
2 "name": "fe",
3 "private": true,
4 "version": "0.0.0",
5 "type": "module",
6 "scripts": {
7 "dev": "vite",
8 "build": "vite build",
9 "preview": "vite preview",
10 "check": "svelte-check --tsconfig ./tsconfig.json"
11 },
12 "devDependencies": {
13 "@sveltejs/vite-plugin-svelte": "^3.0.2",
14 "@tsconfig/svelte": "^5.0.2",
15 "svelte": "^4.2.10",
16 "svelte-check": "^3.6.3",
17 "tslib": "^2.6.2",
18 "typescript": "^5.2.2",
19 "vite": "^5.1.0"
20 }
21}
diff --git a/fe/public/vite.svg b/fe/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/fe/public/vite.svg
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg> \ No newline at end of file
diff --git a/fe/src/App.svelte b/fe/src/App.svelte
new file mode 100644
index 0000000..cc4e594
--- /dev/null
+++ b/fe/src/App.svelte
@@ -0,0 +1,167 @@
1<script lang="ts">
2 import {onMount} from 'svelte';
3 import svelteLogo from './assets/svelte.svg'
4 import viteLogo from '/vite.svg'
5 import Counter from './lib/Counter.svelte'
6 import Table from './lib/Table.svelte'
7 import Card from './lib/Card.svelte'
8 import { UnauthorizedError } from './lib/errors';
9
10 let data;
11 let error;
12
13 let user = {
14 username: '',
15 password: ''
16 }
17
18 interface CredentialObject {
19 username: string;
20 password: string;
21 }
22
23 function sleep(ms) {
24 return new Promise(resolve => setTimeout(resolve, ms));
25 }
26
27 async function getData() {
28 const res = await fetch('http://localhost:8080/api/v1/stats/');
29 if (res.ok) {
30 await sleep(3000);
31 return await res.json();
32 } else {
33 throw new Error('There was a problem with your request');
34 }
35 }
36
37 function handleClick () {
38 data = getData();
39 }
40
41 let authenticated: boolean = false;
42
43 function prepareCredentials ({ username, password }: CredentialObject): string {
44 return btoa(`${username}:${password}`);
45 }
46
47
48 async function onSubmit(e) {
49 if (!user.username || !user.password) {
50 error = 'please enter your username and password';
51 return;
52 }
53 const auth = prepareCredentials(user);
54
55 const response = await fetch('http://localhost:8080/api/v1/auth', {
56 method: 'POST',
57 headers: {
58 'Authorization': `Basic ${auth}`,
59 },
60 });
61
62 if (response.status === 401) {
63 error = "Your username or password is wrong";
64 return;
65 }
66
67 if (response.ok) {
68 const { token } = await response.json();
69 console.log(token);
70 localStorage.user = JSON.stringify(user);
71 localStorage.token = token;
72 authenticated = true;
73 }
74
75
76 error = null;
77 }
78
79 function logout() {
80 localStorage.removeItem("user");
81 localStorage.removeItem("token");
82 authenticated = false;
83 }
84
85
86 onMount(() => {
87 if (localStorage.token) {
88 authenticated = true;
89 }
90 });
91</script>
92
93<main>
94 {#if !authenticated}
95 <Card>
96 <form class="form" on:submit|preventDefault={onSubmit}>
97 <div class='form input group'>
98 <label for="username">Username</label>
99 <input bind:value={user.username} id="username" name='username' type="text" />
100 </div>
101 <div class='form input group'>
102 <label for="password">Password</label>
103 <input bind:value={user.password} id="password" name='password' type="password" />
104 </div>
105 {#if error}
106 <p class="error">{error}</p>
107 {/if}
108 <button type="submit">Log in</button>
109 </form>
110 </Card>
111 {:else}
112 <div>
113 <button on:click={logout}>Logout</button>
114 </div>
115 <div>
116 <a href="https://vitejs.dev" target="_blank" rel="noreferrer">
117 <img src={viteLogo} class="logo" alt="Vite Logo" />
118 </a>
119 <a href="https://svelte.dev" target="_blank" rel="noreferrer">
120 <img src={svelteLogo} class="logo svelte" alt="Svelte Logo" />
121 </a>
122 </div>
123
124 <button on:click={handleClick}>
125 Get Data
126 </button>
127
128 {#await data}
129 <p>...fetching</p>
130 {:then data}
131 {#if data}
132 <p>Status</p>
133 <p>{data.status}</p>
134 <Table />
135 <Table nofooter title="No Footer"/>
136 <Table noheader title="No Header"/>
137 {:else}
138 <p>No data yet</p>
139 {/if}
140 {:catch errror}
141 <p>{error.message}</p>
142 {/await}
143 {/if}
144</main>
145
146<style>
147 .logo {
148 height: 6em;
149 padding: 1.5em;
150 will-change: filter;
151 transition: filter 300ms;
152 }
153 .logo:hover {
154 filter: drop-shadow(0 0 2em #646cffaa);
155 }
156 .logo.svelte:hover {
157 filter: drop-shadow(0 0 2em #ff3e00aa);
158 }
159 .read-the-docs {
160 color: #888;
161 }
162
163 .error {
164 font-size: 0.75em;
165 color: red;
166 }
167</style>
diff --git a/fe/src/app.css b/fe/src/app.css
new file mode 100644
index 0000000..4768cf6
--- /dev/null
+++ b/fe/src/app.css
@@ -0,0 +1,111 @@
1:root {
2 font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3 line-height: 1.5;
4 font-weight: 400;
5
6 color-scheme: light dark;
7 color: rgba(255, 255, 255, 0.87);
8 background-color: #242424;
9
10 font-synthesis: none;
11 text-rendering: optimizeLegibility;
12 -webkit-font-smoothing: antialiased;
13 -moz-osx-font-smoothing: grayscale;
14
15 --submit: #28a745;
16}
17
18a {
19 font-weight: 500;
20 color: #646cff;
21 text-decoration: inherit;
22}
23a:hover {
24 color: #535bf2;
25}
26
27body {
28 margin: 0;
29 display: flex;
30 place-items: center;
31 min-width: 320px;
32 min-height: 100vh;
33}
34
35h1 {
36 font-size: 3.2em;
37 line-height: 1.1;
38}
39
40.card {
41 padding: 2em;
42}
43
44#app {
45 max-width: 1280px;
46 margin: 0 auto;
47 padding: 2rem;
48}
49
50button {
51 border-radius: 8px;
52 border: 1px solid transparent;
53 padding: 0.6em 1.2em;
54 font-size: 1em;
55 font-weight: 500;
56 font-family: inherit;
57 background-color: #1a1a1a;
58 cursor: pointer;
59 transition: border-color 0.25s;
60}
61button:hover {
62 border-color: #646cff;
63}
64button:focus,
65button:focus-visible {
66 outline: 4px auto -webkit-focus-ring-color;
67}
68
69@media (prefers-color-scheme: light) {
70 :root {
71 color: #213547;
72 background-color: #ffffff;
73 }
74 a:hover {
75 color: #747bff;
76 }
77 button {
78 background-color: #f9f9f9;
79 }
80}
81
82@media (prefers-color-scheme: dark) {
83 :root {
84 color: #000;
85 }
86}
87
88.form {
89 display: flex;
90 flex-direction: column;
91}
92
93.form.input.group {
94 display: flex;
95 flex-direction: column;
96 margin-bottom: 1em;
97}
98
99.form.input.group label {
100 margin-bottom: .5em;
101}
102
103.form.input.group input {
104 padding: 1em;
105}
106
107.form button[type=submit] {
108 align-self: flex-end;
109 background: var(--submit);
110 color: #fff;
111}
diff --git a/fe/src/assets/svelte.svg b/fe/src/assets/svelte.svg
new file mode 100644
index 0000000..c5e0848
--- /dev/null
+++ b/fe/src/assets/svelte.svg
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="26.6" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 308"><path fill="#FF3E00" d="M239.682 40.707C211.113-.182 154.69-12.301 113.895 13.69L42.247 59.356a82.198 82.198 0 0 0-37.135 55.056a86.566 86.566 0 0 0 8.536 55.576a82.425 82.425 0 0 0-12.296 30.719a87.596 87.596 0 0 0 14.964 66.244c28.574 40.893 84.997 53.007 125.787 27.016l71.648-45.664a82.182 82.182 0 0 0 37.135-55.057a86.601 86.601 0 0 0-8.53-55.577a82.409 82.409 0 0 0 12.29-30.718a87.573 87.573 0 0 0-14.963-66.244"></path><path fill="#FFF" d="M106.889 270.841c-23.102 6.007-47.497-3.036-61.103-22.648a52.685 52.685 0 0 1-9.003-39.85a49.978 49.978 0 0 1 1.713-6.693l1.35-4.115l3.671 2.697a92.447 92.447 0 0 0 28.036 14.007l2.663.808l-.245 2.659a16.067 16.067 0 0 0 2.89 10.656a17.143 17.143 0 0 0 18.397 6.828a15.786 15.786 0 0 0 4.403-1.935l71.67-45.672a14.922 14.922 0 0 0 6.734-9.977a15.923 15.923 0 0 0-2.713-12.011a17.156 17.156 0 0 0-18.404-6.832a15.78 15.78 0 0 0-4.396 1.933l-27.35 17.434a52.298 52.298 0 0 1-14.553 6.391c-23.101 6.007-47.497-3.036-61.101-22.649a52.681 52.681 0 0 1-9.004-39.849a49.428 49.428 0 0 1 22.34-33.114l71.664-45.677a52.218 52.218 0 0 1 14.563-6.398c23.101-6.007 47.497 3.036 61.101 22.648a52.685 52.685 0 0 1 9.004 39.85a50.559 50.559 0 0 1-1.713 6.692l-1.35 4.116l-3.67-2.693a92.373 92.373 0 0 0-28.037-14.013l-2.664-.809l.246-2.658a16.099 16.099 0 0 0-2.89-10.656a17.143 17.143 0 0 0-18.398-6.828a15.786 15.786 0 0 0-4.402 1.935l-71.67 45.674a14.898 14.898 0 0 0-6.73 9.975a15.9 15.9 0 0 0 2.709 12.012a17.156 17.156 0 0 0 18.404 6.832a15.841 15.841 0 0 0 4.402-1.935l27.345-17.427a52.147 52.147 0 0 1 14.552-6.397c23.101-6.006 47.497 3.037 61.102 22.65a52.681 52.681 0 0 1 9.003 39.848a49.453 49.453 0 0 1-22.34 33.12l-71.664 45.673a52.218 52.218 0 0 1-14.563 6.398"></path></svg> \ No newline at end of file
diff --git a/fe/src/lib/Card.svelte b/fe/src/lib/Card.svelte
new file mode 100644
index 0000000..feb5bcc
--- /dev/null
+++ b/fe/src/lib/Card.svelte
@@ -0,0 +1,22 @@
1<script lang="ts">
2export let title;
3</script>
4
5<div class="card">
6 {#if title}
7 <h2>{title}</h2>
8 {/if}
9 <slot />
10</div>
11
12<style>
13.card {
14 background: #fff;
15 width: 16rem;
16 display: flex;
17 flex-direction: column;
18 align-items: left;
19 border: solid 2px #00000066;
20 border-radius: 0.25em;
21}
22</style>
diff --git a/fe/src/lib/Counter.svelte b/fe/src/lib/Counter.svelte
new file mode 100644
index 0000000..979b4df
--- /dev/null
+++ b/fe/src/lib/Counter.svelte
@@ -0,0 +1,10 @@
1<script lang="ts">
2 let count: number = 0
3 const increment = () => {
4 count += 1
5 }
6</script>
7
8<button on:click={increment}>
9 count is {count}
10</button>
diff --git a/fe/src/lib/Table.svelte b/fe/src/lib/Table.svelte
new file mode 100644
index 0000000..2df9f8c
--- /dev/null
+++ b/fe/src/lib/Table.svelte
@@ -0,0 +1,41 @@
1<script lang="ts">
2 export let data;
3 export let nofooter: boolean = false;
4 export let noheader: boolean = false;
5 export let title: string;
6</script>
7<table>
8 {#if title}
9 <h2>{title}</h2>
10 {/if}
11 {#if !noheader}
12 <thead>
13 <tr>
14 <th>
15 Data Header
16 </th>
17 </tr>
18 </thead>
19 {/if}
20 <tbody>
21 <tr>
22 <td>Data</td>
23 </tr>
24 </tbody>
25 {#if !nofooter}
26 <slot name="footer">
27 <tfoot>
28 <tr>
29 <td>Table Footer</td>
30 </tr>
31 </tfoot>
32 </slot>
33 {/if}
34</table>
35<style>
36table {
37 padding: 16px;
38 margin: 8px;
39 border: solid 1px black;
40}
41</style>
diff --git a/fe/src/lib/errors.ts b/fe/src/lib/errors.ts
new file mode 100644
index 0000000..0663d63
--- /dev/null
+++ b/fe/src/lib/errors.ts
@@ -0,0 +1,7 @@
1export class UnauthorizedError extends Error {
2 constructor (message?: string , options?: ErrorOptions) {
3 super(message, options);
4 }
5}
6
7
diff --git a/fe/src/lib/utils.ts b/fe/src/lib/utils.ts
new file mode 100644
index 0000000..c5501ae
--- /dev/null
+++ b/fe/src/lib/utils.ts
@@ -0,0 +1,9 @@
1export function processFormInput(form) {
2 const formData = new FormData(form);
3 const data = {};
4 for (let field of formData) {
5 const [key, value] = field;
6 data[key] = value;
7 }
8 return data;
9}
diff --git a/fe/src/main.ts b/fe/src/main.ts
new file mode 100644
index 0000000..8a909a1
--- /dev/null
+++ b/fe/src/main.ts
@@ -0,0 +1,8 @@
1import './app.css'
2import App from './App.svelte'
3
4const app = new App({
5 target: document.getElementById('app'),
6})
7
8export default app
diff --git a/fe/src/vite-env.d.ts b/fe/src/vite-env.d.ts
new file mode 100644
index 0000000..4078e74
--- /dev/null
+++ b/fe/src/vite-env.d.ts
@@ -0,0 +1,2 @@
1/// <reference types="svelte" />
2/// <reference types="vite/client" />
diff --git a/fe/svelte.config.js b/fe/svelte.config.js
new file mode 100644
index 0000000..b0683fd
--- /dev/null
+++ b/fe/svelte.config.js
@@ -0,0 +1,7 @@
1import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
2
3export default {
4 // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
5 // for more information about preprocessors
6 preprocess: vitePreprocess(),
7}
diff --git a/fe/tsconfig.json b/fe/tsconfig.json
new file mode 100644
index 0000000..5fb548f
--- /dev/null
+++ b/fe/tsconfig.json
@@ -0,0 +1,20 @@
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 },
18 "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
19 "references": [{ "path": "./tsconfig.node.json" }]
20}
diff --git a/fe/tsconfig.node.json b/fe/tsconfig.node.json
new file mode 100644
index 0000000..d02c37d
--- /dev/null
+++ b/fe/tsconfig.node.json
@@ -0,0 +1,10 @@
1{
2 "compilerOptions": {
3 "composite": true,
4 "skipLibCheck": true,
5 "module": "ESNext",
6 "moduleResolution": "bundler",
7 "strict": true
8 },
9 "include": ["vite.config.ts"]
10}
diff --git a/fe/vite.config.ts b/fe/vite.config.ts
new file mode 100644
index 0000000..d701969
--- /dev/null
+++ b/fe/vite.config.ts
@@ -0,0 +1,7 @@
1import { defineConfig } from 'vite'
2import { svelte } from '@sveltejs/vite-plugin-svelte'
3
4// https://vitejs.dev/config/
5export default defineConfig({
6 plugins: [svelte()],
7})